Hibernate Annotations - Which is better, field or

2018-12-31 23:36发布

This question is somewhat related to Hibernate Annotation Placement Question.

But I want to know which is better? Access via properties or access via fields? What are the advantages and disadvantages of each?

25条回答
若你有天会懂
2楼-- · 2019-01-01 00:08

That really depends on a specific case -- both options are available for a reason. IMO it boils down to three cases:

  1. setter has some logic that should not be executed at the time of loading an instance from a database; for example, some value validation happens in the setter, however the data coming from db should be valid (otherwise it would not get there (: ); in this case field access is most appropriate;
  2. setter has some logic that should always be invoked, even during loading of an instance from db; for example, the property being initialised is used in computation of some calculated field (e.g. property -- a monetary amount, calculated property -- a total of several monetary properties of the same instance); in this case property access is required.
  3. None of the above cases -- then both options are applicable, just stay consistent (e.i. if field access is the choice in this situation then use it all the time in similar situation).
查看更多
一个人的天荒地老
3楼-- · 2019-01-01 00:08

I would strongly recommend field access and NOT annotations on the getters (property access) if you want to do anything more in the setters than just setting the value (e.g. Encryption or calculation).

The problem with the property access is that the setters are also called when the object is loaded. This has worked for me fine for many month until we wanted to introduce encryption. In our use case we wanted to encrypt a field in the setter and decrypt it in the getter. The problem now with property access was that when Hibernate loaded the object it was also calling the setter to populate the field and thus was encrypting the encrypted value again. This post also mentions this: Java Hibernate: Different property set function behavior depending on who is calling it

This has cause me headaches until I remembered the difference between field access and property access. Now I have moved all my annotations from property access to field access and it works fine now.

查看更多
像晚风撩人
4楼-- · 2019-01-01 00:09

I think annotating the property is better because updating fields directly breaks encapsulation, even when your ORM does it.

Here's a great example of where it will burn you: you probably want your annotations for hibernate validator & persistence in the same place (either fields or properties). If you want to test your hibernate validator powered validations which are annotated on a field, you can't use a mock of your entity to isolate your unit test to just the validator. Ouch.

查看更多
怪性笑人.
5楼-- · 2019-01-01 00:12

Are we there yet

That's an old presentation but Rod suggests that annotation on property access encourages anemic domain models and should not be the "default" way to annotate.

查看更多
君临天下
6楼-- · 2019-01-01 00:12

AccessType.PROPERTY: The EJB persistence implementation will load state into your class via JavaBean "setter" methods, and retrieve state from your class using JavaBean "getter" methods. This is the default.

AccessType.FIELD: State is loaded and retrieved directly from your class' fields. You do not have to write JavaBean "getters" and "setters".

查看更多
像晚风撩人
7楼-- · 2019-01-01 00:13

I prefer accessors, since I can add some business logic to my accessors whenever I need. Here's an example:

@Entity
public class Person {

  @Column("nickName")
  public String getNickName(){
     if(this.name != null) return generateFunnyNick(this.name);
     else return "John Doe";
  }
}

Besides, if you throw another libs into the mix (like some JSON-converting lib or BeanMapper or Dozer or other bean mapping/cloning lib based on getter/setter properties) you'll have the guarantee that the lib is in sync with the persistence manager (both use the getter/setter).

查看更多
登录 后发表回答