开发者

Creating entities rules

开发者 https://www.devze.com 2023-03-26 20:45 出处:网络
I\'d like to know the answer to this simple question. When I create an entity object and I want to restrict a setting of an attribute (for example I don\'t want to allow anyone to set an integer valu

I'd like to know the answer to this simple question.

When I create an entity object and I want to restrict a setting of an attribute (for example I don't want to allow anyone to set an integer value less then 1 to an attribute), should I implement it in the setter of this attribute or s开发者_如何学Pythonhould I check this restriction latter in a class that handles these objects ? Generally, can I implement getters and setters however I want as long as my getters return and setters set attributes ?

I know there are some rules (code conventions) in java, so I don't want to break any of them.

Thanks in advance, hope that my question is clear enough and sorry for any grammar mistakes I might have made :/ .


Yes getters/setters are useful for that.

for example:

public void setAge(int age){
 if(age < 0){
  throw new IllegalArgumentException("Invalid age : " + age);
  //or if you don't want to throw an exception you can handle it otherways too
 }
}

You can also use Java-EE's Bean Validators for this

public class Person{

   @Min(value = 0)
   @Max(value = 99)
   private Integer age;

   //some other code
}


My preferred approach is to use JSR 303 (Bean Validation API) to ensure that the properties of the class are valid.

It is quite alright to perform validation in setters, but this is not always a desirable approach. There is the potential of mixing the needs of several contexts that are not related to each other. For example, some of your properties must never be set from the user-interface, and would instead be computed by a service, before being persisted. In such an event, it is not desirable to have this logic inside a setter, for you would need to know the context in which the setter is being invoked; you'll need to apply different rules in your UI layer and in your persistence layer. JSR 303 allows you to separate these concerns using validation groups, so that your UI validation group is different from your persistence validation group.

In JPA 2.0, when you annotate your class using constraints that are evaluated by a JSR 303 validator, your persistence provider can automatically evaluate these constraints on the PrePersist, PreUpdate and PreRemove (typically not done; see below) lifecycle events of entities. To perform validation of entities in your JPA provider, you must specify either the validation-mode element or the javax.persistence.validation.mode property in your persistence.xml file; the values must be either AUTO (the default) or CALLBACK (and not NONE).

The presence of a Bean Validation provider is sufficient to ensure that validation occurs on JPA entity lifecycle events, as the default value is AUTO. You get this by default, in a Java EE 6 application server; Glassfish uses the RI implementation of JSR 303 which is Hibernate Validator, and it works quite well with EclipseLink as well.

The CALLBACK mode will allow you to override the validation groups that are to be applied when the lifecycle events are triggered. By default, the default Bean validation group (Default) will be validated for update and persist events; the remove event does not involve any validation. The CALLBACK mode allows you to specify a different validation group for these events, using the properties javax.persistence.validation.group.pre-persist, javax.persistence.validation.group.pre-update and javax.persistence.validation.group.pre-remove.

Do keep in mind that JSR 303 validation can be used outside a Java EE container, although the Bean Validation API documentation link that I've posted above is from the Java EE 6 API documentation.


This is the goal of getters and setters.

If we cannot add some behavior in these methods, well... why don't we use public attributes ?


From my understanding of your question, it pretty much related to encapsulation OO principle. You can have a look at this article: http://www.tutorialspoint.com/java/java_encapsulation.htm


Getters and setters are great for adding the restrictions, just like Jigar Joshi has in his answer. That way you get feedback immediately and can handle the problem when it is introduced.

Another solution would be to use object validation (something like a JSR-303 implementation) which would allow you to annotate the field with a min and max values. Something like

@Min(value=1)
private int myvalue;

Then you can validate the entire object in one go and get all messages if you have other constrained fields. This is obviously not useful everywhere, but if it fits your need it is an option.

Finally, when you say "entity" I think of something stored in a database or related to ORM tools. If that is the case, you will want to be careful with what you do in your getter. For instance, if you do lazy initialization in the getter some ORM suppliers will mark the entity as dirty and attempt to flush it to the database possibly causing an unintended write.

0

精彩评论

暂无评论...
验证码 换一张
取 消