How do I access Core Data Attribute validation information from code? - core-data

I have a string attribute in a Core Data entity whose Max Length value is 40. I'd like to use this value in code and not have to re-type the value "40." Is this possible?

As #K.Steff says in the comments above, you are better off validating in your code and not setting a max length in your core data model. To add on to that comment, I would also advise you to look at using a custom NSManagedObject subclass for this entity type, and within that subclass overriding the validateValue:forKey:error: or implementing a key-specific validation method for this property.
The value of this approach is that you can do things like "coerce" the validation by truncating strings at validation time. From the NSManagedObject documentation:
This method is responsible for two things: coercing the value into an appropriate
type for the object, and validating it according to the object’s rules.
The default implementation provided by NSManagedObject consults the object’s entity
description to coerce the value and to check for basic errors, such as a null value when
that isn’t allowed and the length of strings when a field width is specified for the
attribute. It then searches for a method of the form validate< Key >:error: and invokes it
if it exists.
You can implement methods of the form validate< Key >:error: to perform validation that is
not possible using the constraints available in the property description. If it finds an
unacceptable value, your validation method should return NO and in error an NSError object
that describes the problem. For more details, see “Model Object Validation”. For
inter-property validation (to check for combinations of values that are invalid), see
validateForUpdate: and related methods.
So you can implement this method to both validate that the string is not too long and, if necessary, truncate it when it is too long.

From NSManagedObject you can access the NSEntityDescription via entity. In there you can grab the array properties and a dictionary propertiesByName, either of which will get you to NSPropertyDescriptions. Each property description has a property, validationPredicates that will return an array of NSPredicates. One of those will be the condition that your string length must be at most 40.
Sadly predicates are a lot of hassle to reverse engineer — and doing so can even be impossible, given that you can create one by supplying a block. Hopefully though you'll just have an NSComparisonPredicate or be able to get to one by tree walking downward from an NSCompoundPredicate or an NSExpression.
From the comparison predicate you'll be able to spot from the left and right expressions that one is string length and the other is a constant value.
So, in summary:
Core Data exposes validation criteria only via the very general means of predicates;
you can usually, but not always, rebuild an expression (in the natural language sense rather than the NSExpression sense) from a predicate; and
if you know specifically you're just looking for a length comparison somewhere then you can simplify that further into a tree walk for comparison predicates that involve the length.
It's definitely not going to be pretty because of the mismatch of the specific and the general but it is possible.

Related

Is it allowed to modify value of the Value Object on construction

Assuming that I want that following Value Object contains always capitalized String value. Is it eligible to do it like this with toUpperCase() in constructor?
class CapitalizedId(value: String) {
val value: String = value.toUpperCase()
// getters
// equals and hashCode
}
In general, I do not see a problem of performing such a simple transformation in a value object's constructor. There should of course be no surprises for the user of a constructor but as the name CapitalizedId already tells you that whatever will be created will be capitalized there is no surprise, from my point of view. I also perform validity checks in constructors to ensure business invariants are adhered.
If you are worried to not perform operations in a constructor or if the operations and validations become too complex you can always provide factory methods instead (or in Kotlin using companion, I guess, not a Kotlin expert) containing all the heavy lifting (think of LocalDateTime.of()) and validation logic and use it somehow like this:
CapitalizedId.of("abc5464g");
Note: when implementing a factory method the constructor should be made private in such cases
Is it eligible to do it like this with toUpperCase() in constructor?
Yes, in the sense that what you end up with is still an expression of the ValueObject pattern.
It's not consistent with the idea that initializers should initialize, and not also include other responsibilities. See Misko Hevery 2008.
Will this specific implementation be an expensive mistake? Probably not

Mockito discourages mocking VO and DTOs ? A good reason why [duplicate]

In the book GOOS. It is told not to mock values, which leaves me confused. Does it means that values don't have any behavior?
I dont' much knowledge about the value object but AFAIK the value objects are those which are immutable. Is there any heuristic on deciding when to create a value object?
Not all immutable objects are value objects. By the way, when designing, consider that the ideal object has only immutable fields and no-arg methods.
Regarding the heuristic, a valid approach can be considering how objects will be used: if you build an instance, invoke some methods and then are done with it (or store it in a field) likely it won't be a value object. On the contrary, if you keep objects in some data structure and compare them (with .equals()) likely you have a value object. This is especially true for objects that will be used to key Maps
Value objects should be automatic-tested themselves (and tests are usually a pleasure to read and write because are straightforward) but there's no point in mocking them: the main practical reasons for mocking interfaces is that implementation classes
are usually difficult to build (need lot of collaborators)
are expensive to run (access the network, the filesystem, ...).
Neither apply to value objects.
Quoting the linked blog post:
There are a couple of heuristics for when a class is not worth mocking. First, it has only accessors or simple methods that act on values it holds, it doesn't have any interesting behaviour. Second, you can't think of a meaningful name for the class other than VideoImpl or some such vague term.
The implication of the first point, in the context of a section entitled "Don't mock value objects", is that value objects don't have interesting behaviour.

To Have An ID or Not To Have An ID - Regarding Value Object

Let's say two domain objects: Product and ProductVariety (with data such as color, size etc). The relationship between these two is one-to-many. Conceptually saying in the domain driven design, the ProductVariaty should be a value object, which is not the same object once its data is changed. From the implementation point of view, however, it is better to have some sort identification for the ProductVariaty so that we know which ProductVariety is selected and so on. Is an only solution to convert it to an entity class?
The following is a code segment to illustrate this situation.
#Embeddable
class ProductVariety {...}
#Entity
class Product {
#ElementCollection
private Set<ProductVariety> varities;
...
}
Conceptually saying in the domain driven design, the ProductVariaty should be a value object, which is not the same object once its data is changed
That's not quite the right spelling. In almost all cases (many nines), Value Object should be immutable; its data never changes.
Is an only solution to convert it to an entity class?
"It depends".
There's nothing conceptually wrong with having an identifier be part of the immutable state of the object. For example, PANTONE 5395 C is an Identifier (value type) that is unique to a particular Color (value type).
However, for an identifier like PANTONE 5395 C to have value, it needs to be semantically stable. Changing the mapping of the identifier to the actual color spectrum elements destroys the meaning of previous messages about color. If the identifier is "wrong", then the proper thing to do is deprecate the identifier and nominate a replacement.
Put simply, you can't repaint the house by taking the label off the old paint can and putting it on a new one.
In that case, there's no great advantage to using the identifier vs the entire value object. But its not wrong to do so, either.
On the other hand, if you are really modeling a mapping, and you want to follow changes that happen over time -- that's pretty much the definition of an entity right there.
What it really depends on is "cost to the business". What are the trade offs involved, within the context of the problem you are trying to solve?
Note: if you really do find yourself in circumstances where you are considering something like this, be sure to document your cost benefit analysis, so that the next developer that comes along has a trail of breadcrumbs to work from.

is not bound to a legal value during translation

I would like to know a bit more about the bounding this error relates to.
I have an alloy model for which I create an instance manually (by writting it down in XML).
This instance is readable and the A4Solution can be correctly displayed.
But when I try to evaluate an expression in this instance using the eval() function, I receive this error message, though the field name and type of the exprvar retrieved from the model is exactly the same as the one in the instance..
I would like to know what does this bounding consist of. What are the properties taken into consideration to tell that one element of the instance is bounded to one element of the model.
Is the hidden ID figuring in the XML somewhere taken into consideration ?
I would like to know what does this bounding consist of.
It means that every free variable (i.e., relation in Kodkod) has to be given a bound before asking the solver to solve the formula.
What are the properties taken into consideration to tell that one element of the instance is bounded to one element of the model.
The instance XML file contains and exact value (a tuple set) for each and every sig and field from the model; those tuple sets are exactly the bounds that should be used when evaluating expressions. I'm not sure how exactly you are trying to use the Alloy API; but recreating the bounds from the XML file should (mostly) be handled by the API behind the scene.
Judging by your last comment to my previous answer, your problem might be related to this post.
In a nutshell, if you are trying to evaluate AST expression objects obtained from one "alloy world" (CompModule) against a solution that was entirely recreated from an XML file, you will get exactly that error. For example, if you have two PrimSig objects, s1 and s2, and they both have the same name (e.g., both were obtained by parsing sig S {...}), they are not "Java equals" (s1.equals(s2) returns false); the same holds for the underlying Kodkod relations/variables. So if you then try to evaluate s1 in a context which has a bound only for s2, you'll get an error saying that s1 is not bound.
Providing the set of Signatures defined in the metamodel while reading the A4Solution solved my problem.
Thus changing:
solution = A4SolutionReader.read(null, new XMLNode(f));
by
solution = A4SolutionReader.read(mm.getAllReachableSigs(), new XMLNode(f));
solved this illegal bounding issue

Sharp Architecture Value Objects

I'm checking out Sharp Architecture's code. So far it's cool, but I'm having problems getting my head around how to implement DDD value objects in the framework (doesn't seem to be anything mentioning this in the code). I'm assuming the base Entity class and Repository base are to be used for entities only. Any ideas on how to implement value objects in the framework?
In Sharp Arch there is a class ValueObject in namespace SharpArch.Domain.DomainModel. This object inherits from BaseObject and overrides the == and != operators and the Equals() and GetHashCode() methods. The method overrides just calls the BaseObject versions of those two methods which in turn uses GetTypeSpecificSignatureProperties() method to get the properties to use in the equality comparison.
Bottom line is that Entity's equality is determined by
Reference equality
Same type?
Id's are the same
Comparison of all properties decorated with the [DomainSignature] attribute
For ValueObjects, the BaseObject's Equals method is used
Reference equality
Same type?
Compare all public properties
This is a little bit simplified, I suggest you get the latest code from github and read through the code in the mentioned 3 classes yourself.
Edit: Regarding persistence, this SO question might help. Other than that, refer to the official NH and Fluent NH documentation
Value objects are simple objects that don't require a base class. (The only reason entities have base classes is to provide equality based on the identity). Implementing a value object just means creating a class to represent a value from your domain. A lot of times value objects should be immutable and provide equality comparison methods to determine equality to other value objects of the same type. Take a look here.

Resources