Hibernate, fetch, HQL and hashCode() - java

I have a HQL query something ala'
SELECT myclass
FROM
MyClass myclass JOIN FETCH
myclass.anotherset sub JOIN FETCH
sub.yetanotherset
...
So, class MyClass has a property "anotherset" , which is a set containing instance of another class, lets call it MyClassTwo. And, class MyClassTwo has a property yetanotherset which is a set of a third type of class (with no further associations on it).
In this scenario, I'm having trouble with the hashCode implementation. Basically, the hashCode implementation of MyClassTwo, uses the "yetanotherset" property, and on the exact line it accesses the yetanothertest property, it fails with a LazyInitializationException.
org.hibernate.LazyInitializationException: illegal access to loading collection
I'm guessing, this is because the data from "yetanotherset" hasn't been fetched yet, but how do I fix this? I don't particularly like the idea of dumbing down the hashCode to ignore the property.
Additional question, does HQL ignore fetch=FetchType.EAGER as defined in XML or annotations, it seems like it does. But I cant verify this anywhere.

Implementing hashCode() using a mutable field is a bad idea: it makes storing the entity in a HashSet and modifying the mutable property impossible.
Implementing it in terms of a collection of other entities is an even worse idea: it forces the loading of the collection to compute the hashCode.
Choose a unique, immutable property (or set of properties) in your entity, and implement hashCode based on that. On last resort, you have the option of using the ID, but if it's autogenerated, you must not put it in a Set before the ID is generated.

This is hibernate's most famous exception and it is exactly as you described it. The session has been disconnected, transaction closed, and you are attempting to access this collection. JOIN FETCH in your HQL should force EAGER loading to occur regardless of whether than annotation is present.
I suspect that your annotations are malformed, you have missing or out of date jars, or some other problem of that type.
Bump your Hibernate logging level up to generate the SQL hibernate.SQL=debug and investigate exactly what SQL is being executed up to where you see this exception. This should indicate to you whether your hibernate configuration is behaving the way you think its configured.
Post more of your code and the logs and someone might be able to help you spot the error.

Related

What's different between field #ManyToOne and get #ManyToOne? [duplicate]

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?
There are arguments for both, but most of them stem from certain user requirements "what if you need to add logic for", or "xxxx breaks encapsulation". However, nobody has really commented on the theory, and given a properly reasoned argument.
What is Hibernate/JPA actually doing when it persists an object - well, it is persisting the STATE of the object. That means storing it in a way that it can be easily reproduced.
What is encapsulation? Encapsulations means encapsulating the data (or state) with an interface that the application/client can use to access the data safely - keeping it consistent and valid.
Think of this like MS Word. MS Word maintains a model of the document in memory - the documents STATE. It presents an interface that the user can use to modify the document - a set of buttons, tools, keyboard commands etc. However, when you choose to persist (Save) that document, it saves the internal state, not the set of keypresses and mouse clicks used to generate it.
Saving the internal state of the object DOES NOT break encapsulation - otherwise you don't really understand what encapsulation means, and why it exists. It is just like object serialisation really.
For this reason, IN MOST CASES, it is appropriate to persist the FIELDS and not the ACCESSORS. This means that an object can be accurately recreated from the database exactly the way it was stored. It should not need any validation, because this was done on the original when it was created, and before it was stored in the database (unless, God forbid, you are storing invalid data in the DB!!!!). Likewise, there should be no need to calculate values, as they were already calculated before the object was stored. The object should look just the way it did before it was saved. In fact, by adding additional stuff into the getters/setters you are actually increasing the risk that you will recreate something that is not an exact copy of the original.
Of course, this functionality was added for a reason. There may be some valid use cases for persisting the accessors, however, they will typically be rare. An example may be that you want to avoid persisting a calculated value, though you may want to ask the question why you don't calculate it on demand in the value's getter, or lazily initialise it in the getter. Personally I cannot think of any good use case, and none of the answers here really give a "Software Engineering" answer.
I prefer field access, because that way I'm not forced to provide getter/setter for each property.
A quick survey via Google suggests that field access is the majority (e.g., http://java.dzone.com/tips/12-feb-jpa-20-why-accesstype).
I believe field access is the idiom recommended by Spring, but I can't find a reference to back that up.
There's a related SO question that tried to measure performance and came to the conclusion that there's "no difference".
Here's a situation where you HAVE to use property accessors. Imagine you have a GENERIC abstract class with lots of implementation goodness to inherit into 8 concrete subclasses:
public abstract class Foo<T extends Bar> {
T oneThing;
T anotherThing;
// getters and setters ommited for brevity
// Lots and lots of implementation regarding oneThing and anotherThing here
}
Now exactly how should you annotate this class? The answer is YOU CAN'T annotate it at all with either field or property access because you can't specify the target entity at this point. You HAVE to annotate the concrete implementations. But since the persisted properties are declared in this superclass, you MUST used property access in the subclasses.
Field access is not an option in an application with abstract generic super-classes.
I tend to prefer and to use property accessors:
I can add logic if the need arises (as mentioned in the accepted answer).
it allows me to call foo.getId() without initializing a proxy (important when using Hibernate, until HHH-3718 get resolved).
Drawback:
it makes the code less readable, you have for example to browse a whole class to see if there are #Transient around there.
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).
Let me try to summarize the most important reasons for choosing field-based access. If you want to dive deeper, please read this article on my blog: Access Strategies in JPA and Hibernate – Which is better, field or property access?
Field-based access is by far the better option. Here are 5 reasons for it:
Reason 1: Better readability of your code
If you use field-based access, you annotate your entity attributes with your mapping annotations. By placing the definition of all entity attributes at the top of your class, you get a relatively compact view of all attributes and their mappings.
Reason 2: Omit getter or setter methods that shouldn’t be called by your application
Another advantage of field-based access is that your persistence provider, e.g., Hibernate or EclipseLink, doesn’t use the getter and setter methods of your entity attributes. That means that you don’t need to provide any method that shouldn’t be used by your business code. This is most often the case for setter methods of generated primary key attributes or version columns. Your persistence provider manages the values of these attributes, and you should not set them programmatically.
Reason 3: Flexible implementation of getter and setter methods
Because your persistence provider doesn’t call the getter and setter methods, they are not forced to fulfill any external requirements. You can implement these methods in any way you want. That enables you to implement business-specific validation rules, to trigger additional business logic or to convert the entity attribute into a different data type.
You can, for example, use that to wrap an optional association or attribute into a Java Optional.
Reason 4: No need to mark utility methods as #Transient
Another benefit of the field-based access strategy is that you don’t need to annotate your utility methods with #Transient. This annotation tells your persistence provider that a method or attribute is not part of the entity persistent state. And because with field-type access the persistent state gets defined by the attributes of your entity, your JPA implementation ignores all methods of your entity.
Reason 5: Avoid bugs when working with proxies
Hibernate uses proxies for lazily fetched to-one associations so that it can control the initialization of these associations. That approach works fine in almost all situations. But it introduces a dangerous pitfall if you use property-based access.
If you use property-based access, Hibernate initializes the attributes of the proxy object when you call the getter method. That’s always the case if you use the proxy object in your business code. But quite a lot of equals and hashCode implementations access the attributes directly. If this is the first time you access any of the proxy attributes, these attributes are still uninitialized.
I prefer using field access for the following reasons:
The property access can lead to very nasty bugs when implementing equals/hashCode and referencing fields directly (as opposed through their getters). This is because the proxy is only initialized when the getters are accessed, and a direct-field access would simply return null.
The property access requires you to annotate all utility methods (e.g. addChild/removeChild) as #Transient.
With field access we can hide the #Version field by not exposing a getter at all. A getter can also lead to adding a setter as well, and the version field should never be set manually (which can lead to very nasty issues). All version incrementation should be triggered through OPTIMISTIC_FORCE_INCREMENT or PESSIMISTIC_FORCE_INCREMENT explicit locking.
That really depends on a specific case -- both options are available for a reason. IMO it boils down to three cases:
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;
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.
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).
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.
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.
I believe property access vs. field access is subtly different with regards to lazy initialisation.
Consider the following mappings for 2 basic beans:
<hibernate-mapping package="org.nkl.model" default-access="field">
<class name="FieldBean" table="FIELD_BEAN">
<id name="id">
<generator class="sequence" />
</id>
<property name="message" />
</class>
</hibernate-mapping>
<hibernate-mapping package="org.nkl.model" default-access="property">
<class name="PropBean" table="PROP_BEAN">
<id name="id">
<generator class="sequence" />
</id>
<property name="message" />
</class>
</hibernate-mapping>
And the following unit tests:
#Test
public void testFieldBean() {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
FieldBean fb = new FieldBean("field");
Long id = (Long) session.save(fb);
tx.commit();
session.close();
session = sessionFactory.openSession();
tx = session.beginTransaction();
fb = (FieldBean) session.load(FieldBean.class, id);
System.out.println(fb.getId());
tx.commit();
session.close();
}
#Test
public void testPropBean() {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
PropBean pb = new PropBean("prop");
Long id = (Long) session.save(pb);
tx.commit();
session.close();
session = sessionFactory.openSession();
tx = session.beginTransaction();
pb = (PropBean) session.load(PropBean.class, id);
System.out.println(pb.getId());
tx.commit();
session.close();
}
You will see the subtle difference in the selects required:
Hibernate:
call next value for hibernate_sequence
Hibernate:
insert
into
FIELD_BEAN
(message, id)
values
(?, ?)
Hibernate:
select
fieldbean0_.id as id1_0_,
fieldbean0_.message as message1_0_
from
FIELD_BEAN fieldbean0_
where
fieldbean0_.id=?
0
Hibernate:
call next value for hibernate_sequence
Hibernate:
insert
into
PROP_BEAN
(message, id)
values
(?, ?)
1
That is, calling fb.getId() requires a select, whereas pb.getId() does not.
By default, JPA providers access the values of entity fields and map those fields to database columns
using the entity’s JavaBean property accessor (getter) and mutator (setter) methods. As such, the
names and types of the private fields in an entity do not matter to JPA. Instead, JPA looks at only
the names and return types of the JavaBean property accessors. You can alter this using the #javax.persistence.Access annotation, which enables you to explicitly specify the access methodology
that the JPA provider should employ.
#Entity
#Access(AccessType.FIELD)
public class SomeEntity implements Serializable
{
...
}
The available options for the AccessType enum are PROPERTY (the default) and FIELD. With
PROPERTY, the provider gets and sets field values using the JavaBean property methods. FIELD makes
the provider get and set field values using the instance fields. As a best practice, you should just stick
to the default and use JavaBean properties unless you have a compelling reason to do otherwise.
You
can put these property annotations on either the private fields or the public accessor methods. If
you use AccessType.PROPERTY (default) and annotate the private fields instead of the JavaBean
accessors, the field names must match the JavaBean property names. However, the names do not
have to match if you annotate the JavaBean accessors. Likewise, if you use AccessType.FIELD and
annotate the JavaBean accessors instead of the fields, the field names must also match the JavaBean
property names. In this case, they do not have to match if you annotate the fields. It’s best to just
be consistent and annotate the JavaBean accessors for AccessType.PROPERTY and the fields for
AccessType.FIELD.
It is important that you should never mix JPA property annotations and JPA field annotations
in the same entity. Doing so results in unspecified behavior and is very
likely to cause errors.
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.
Another point in favor of field access is that otherwise you are forced to expose setters for collections as well what, for me, is a bad idea as changing the persistent collection instance to an object not managed by Hibernate will definitely break your data consistency.
So I prefer having collections as protected fields initialized to empty implementations in the default constructor and expose only their getters. Then, only managed operations like clear(), remove(), removeAll() etc are possible that will never make Hibernate unaware of changes.
I prefer fields, but I've run into one situation that seems to force me to place the annotations on getters.
With the Hibernate JPA implementation, #Embedded doesn't seem to work on fields. So that has to go on the getter. And once you put that on the getter, then the various #Column annotations have to go on the getters too. (I think Hibernate doesn't want mixing fields and getters here.) And once you're putting #Column on getters in one class, it probably makes sense to do that throughout.
I favor field accessors. The code is much cleaner. All the annotations can be placed in one
section of a class and the code is much easier to read.
I found another problem with property accessors: if you have getXYZ methods on your class that are NOT annotated as being associated with persistent properties, hibernate generates sql to attempt to get those properties, resulting in some very confusing error messages. Two hours wasted. I did not write this code; I have always used field accessors in the past and have never run into this issue.
Hibernate versions used in this app:
<!-- hibernate -->
<hibernate-core.version>3.3.2.GA</hibernate-core.version>
<hibernate-annotations.version>3.4.0.GA</hibernate-annotations.version>
<hibernate-commons-annotations.version>3.1.0.GA</hibernate-commons-annotations.version>
<hibernate-entitymanager.version>3.4.0.GA</hibernate-entitymanager.version>
You should choose access via fields over access via properties.
With fields you can limit the data sent and received.
With via properties you can send more data as a host, and
set G denominations (which factory set most of the properties in total).
Normally beans are POJO, so they have accessors anyway.
So the question is not "which one is better?", but simply "when to use field access?". And the answer is "when you don't need a setter/getter for the field!".
I had the same question regarding accesstype in hibernate and found some answers here.
I have solved lazy initialisation and field access here Hibernate one-to-one: getId() without fetching entire object
We created entity beans and used getter annotations. The problem we ran into is this: some entities have complex rules for some properties regarding when they can be updated. The solution was to have some business logic in each setter that determines whether or not the actual value changed and, if so, whether the change should be allowed. Of course, Hibernate can always set the properties, so we ended up with two groups of setters. Pretty ugly.
Reading previous posts, I also see that referencing the properties from inside the entity could lead to issues with collections not loading.
Bottom line, I would lean toward annotating the fields in the future.
i thinking about this and i choose method accesor
why?
because field and methos accesor is the same
but if later i need some logic in load field, i save move all annotation placed in fields
regards
Grubhart
To make your classes cleaner, put the annotation in the field then use #Access(AccessType.PROPERTY)
Both :
The EJB3 spec requires that you declare annotations on the element
type that will be accessed, i.e. the getter method if you use property
access, the field if you use field access.
https://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#entity-mapping
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".

Hibernate : Force lazy-loadding on eager field

One of our model object in our application has many fields configured to be eagerly fetched like so:
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "field")
public Field getField() {
return this.field;
}
However I sometime do not need these information, which slow down my queries for nothing. I cannot change the behaviour and use FetchType.LAZY instead as I've no idea what will be the impact on the whole application (legacy...). Is there a way to simply tell hibernate to fetch nothing, except if it is specified in the query?
Last time I checked there was no proper solution provided by hibernate, so I ended up with this solution:
Configured the problematic references as LAZY.
All affected service methods (that used these models) got an overloaded version with boolean forceEager
by default all existing functions were refactored to call the new ones with forceEager=true
and here comes the trick: as a means of "forcing the eager fetching" I found nothing better than actually accessing the proxied (lazy-fetched) objects. In case for example a lazily referenced list doing list.size() will force Hibernate to load the full list, hence the service returns with fully fetched object.
In case of more than one layer in your objectstructure is affected, you need to traverse through the whole hierarchy and access every lazily loaded object from top to bottom.
This is a bit error-prone solution, so you need to handle it with care.
If its possible to switch to Criteria for this query, you could use FetchMode.SELECT for the field property
crit.setFetchMode("field", FetchMode.SELECT);

About the use of #ForceDiscriminator/#DiscriminatorOptions(force=true)

Why is #ForceDiscriminator or its equivalent #DiscriminatorOptions(force=true) necessary in some cases of inheritance and polymorphic associations? It seems to be the only way to get the job done. Are there any reasons not to use it?
As I'm running over this again and again, I think it might help to clarify:
First, it is true that Hibernate does not require discrimination when using JOINED_TABLE mapping. However, it does require it when using SINGLE_TABLE. Even more importantly, other JPA providers mostly do require it.
What Hibernate actually does when performing a polymorphic JOINED_TABLE query is to create a discriminator named clazz on the fly, using a case-switch that checks for the presence of fields unique for concrete subclasses after outer-joining all tables involved in the inheritance-tree. You can clearly see this when including the "hibernate.show_sql" property in your persistence.xml. In my view this is probably the perfect solution for JOINED_TABLE queries, so the Hibernate folks are right to brag about it.
The matter is somewhat different when performing updates and deletes; here hibernate first queries your root-table for any keys that match the statement's where clause, and creates a virtual pkTable from the result. Then it performs a "DELETE FROM / UPDATE table WHERE pk IN pkTable" for any concrete class withing your inheritance tree; the IN operator causes an O(log(N)) subquery per table entry scanned, but it is likely in-memory, so it's not too bad from a performance perspective.
To answer your specific question, Hibernate simply doesn't see a problem here, and from a certain perspective they are correct. It would be incredibly easy for them to simply honour the #DiscriminatorValue annotations by injecting the discriminator values during entityManager.persist(), even if they do not actually use them. However, not honoring the discriminator column in JOINED_TABLE has the advantage (for Hibernate) to create a mild case of vendor lockin, and it is even defensible by pointing to superior technology.
#ForceDiscriminator or #DiscriminatorOptions(force=true) sure help to mitigate the pain a little, but you have to use them before the first entities are created, or be forced to manually add the missing discriminator values using SQL statements. If you dare to move away from Hibernate it at least costs you some code change to remove these Hibernate specific annotations, creating resistance against the migration. And that is obviously all that Hibernate cares about in this case.
In my experience, vendor lockin is the paradise every market leader's wildest dreams are about, because it is the machiavellian magic wand that protects market share without effort; it is therefore done whenever customers do not fight back and force a price upon the vendor that is higher than the benefits reaped. Who said that an Open Source world would be any different?
p.s, just to avoid any confusion: I am in no way affiliated to any JPA implementor.
p.p.s: What I usually do is ignore the problem until migration time; you can then formulate an SQL UPDATE ... FROM statement using the same case-switch-with-outer-joins trick Hibernate uses to fill in the missing discriminator values. It's actually quite easy once you have understood the basic principle.
Guys let me try to explain about #DiscriminatorOptions(Force=true).
Well , it is used in single table inheritence, i have recently used this in one of the scenario.
i have two entities which was mapped to single table. when i was trying to fetch the record for one entity i was getting list of result containg records from both the entities and this was my problem. To solve this problem i have used #DiscriminatorOptions(Force=true) which will create the predicate using Discriminator column with the specified value mapped to the corresponding entity.
so the query will be look like this after i used #DiscriminatorOptions(Force=true)
select *
from TABLE
where YOUR PREDICATE AND DiscriminatorColumn = DiscriminatorValue
I think this is more of my opinion but I think some will agree with me. I prefer the fact that Hibernate enables you to not use a discriminator. In several cases the discriminator isn't necessary.
For example, I have a Person entity which contains stuff like a name, a date of birth, etc. This entity can be used by several other entities like Employee or Customer. When I don't reference Person from other entities, but reference Employee or Customer instead, the discriminator isn't used as Hibernate is instructed to fetch either one.
#yannisf ForceDiscriminator is not the only solution to solve this issue.
You can do instanceof tests for each child class. Though this will be like hardcoding your classes in your code but is a cleaner way to solve the problem if the discriminator column is not populated.
This also helps your code avoid mixing jpa and hibernate annotations.
As pointed out by yannisf, instanceOf is kind of an antipattern in the OO world.
Another solution could be changing your entity mapping. Suppose an entity A has a refernce to a superclass B and B has child classes of type C1 and C2, the instead of A pointing to B, you can have C1 and C2 have a foreign key pointing to A. It all comes down to changing the entity design so as not to mix annotations.
Thanks
Vaibhav

Recommendation for using equals in Entities and avoiding LazyInitializationExceptions?

In the beginning there is a problem that wants to be solved. In my case i got an LazyInitializationException while using indexof in a Collection to retrieve an Object for manipulation. Here i start to think about using equals in EntityBeans (OR-Mapper at all). I know there are some discussions about overriding equals in association with OR-Mapper as hibernate like
[1] Entities equals(), hashCode() and toString(). How to correctly implement them?
[2] To equals and hashcode or not on entity classes, that is the question.
[3] Overriding equals and hashCode in Java
I currently have some entities which implements the equals but inside the code i could not use equals several times because of the LazyInitializationExceptions. So i had to workaround and use eg. the name property of the object to identify it's equality. From my point of view the whole 'LazyInitializationException-thing' is not really mentioned in this questions.
I'd like to know have you got some good patterns or real live recommendations how to avoid such exception in an equal-Method. Shall i use some helper Methodes to distinguish if a Object of a class is already initialized (4) or should i apdicate the use of equals and use helper classes instead (2)? And what is about catching LazyInitializationExceptions in the equals?
[Edit]: If you put equals in context with the initialization of the Object then it will gain importance. Sometimes it is nessesary to have the Object fully initialized but sometimes you don't want to. Because you just need the Object itself (name, id, ...) not its Collection-Properties. So just for equalization you have to reattach the Object and load the whole bunch you don't realy need? Are there any other solutions for such a problem?
LazyInitializationException and equals(), hashCode() et al have little to do with each other. You can a LazyInitializationException when a lazily loaded entity tried to access a related entity that has not yet been loaded, and and the entity has been disconnected or evicted from the Session.
There are two fixes for this:
eagerly load the entity, and it's related entities, before closing the session.
Use the "open session in view" pattern to keep the session open for the duration of the request.
Both of these approaches are discussed in the link below.
JavaLobby: Hibernate, Understanding Lazy Fetching

Hibernate Annotations - Which is better, field or property access?

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?
There are arguments for both, but most of them stem from certain user requirements "what if you need to add logic for", or "xxxx breaks encapsulation". However, nobody has really commented on the theory, and given a properly reasoned argument.
What is Hibernate/JPA actually doing when it persists an object - well, it is persisting the STATE of the object. That means storing it in a way that it can be easily reproduced.
What is encapsulation? Encapsulations means encapsulating the data (or state) with an interface that the application/client can use to access the data safely - keeping it consistent and valid.
Think of this like MS Word. MS Word maintains a model of the document in memory - the documents STATE. It presents an interface that the user can use to modify the document - a set of buttons, tools, keyboard commands etc. However, when you choose to persist (Save) that document, it saves the internal state, not the set of keypresses and mouse clicks used to generate it.
Saving the internal state of the object DOES NOT break encapsulation - otherwise you don't really understand what encapsulation means, and why it exists. It is just like object serialisation really.
For this reason, IN MOST CASES, it is appropriate to persist the FIELDS and not the ACCESSORS. This means that an object can be accurately recreated from the database exactly the way it was stored. It should not need any validation, because this was done on the original when it was created, and before it was stored in the database (unless, God forbid, you are storing invalid data in the DB!!!!). Likewise, there should be no need to calculate values, as they were already calculated before the object was stored. The object should look just the way it did before it was saved. In fact, by adding additional stuff into the getters/setters you are actually increasing the risk that you will recreate something that is not an exact copy of the original.
Of course, this functionality was added for a reason. There may be some valid use cases for persisting the accessors, however, they will typically be rare. An example may be that you want to avoid persisting a calculated value, though you may want to ask the question why you don't calculate it on demand in the value's getter, or lazily initialise it in the getter. Personally I cannot think of any good use case, and none of the answers here really give a "Software Engineering" answer.
I prefer field access, because that way I'm not forced to provide getter/setter for each property.
A quick survey via Google suggests that field access is the majority (e.g., http://java.dzone.com/tips/12-feb-jpa-20-why-accesstype).
I believe field access is the idiom recommended by Spring, but I can't find a reference to back that up.
There's a related SO question that tried to measure performance and came to the conclusion that there's "no difference".
Here's a situation where you HAVE to use property accessors. Imagine you have a GENERIC abstract class with lots of implementation goodness to inherit into 8 concrete subclasses:
public abstract class Foo<T extends Bar> {
T oneThing;
T anotherThing;
// getters and setters ommited for brevity
// Lots and lots of implementation regarding oneThing and anotherThing here
}
Now exactly how should you annotate this class? The answer is YOU CAN'T annotate it at all with either field or property access because you can't specify the target entity at this point. You HAVE to annotate the concrete implementations. But since the persisted properties are declared in this superclass, you MUST used property access in the subclasses.
Field access is not an option in an application with abstract generic super-classes.
I tend to prefer and to use property accessors:
I can add logic if the need arises (as mentioned in the accepted answer).
it allows me to call foo.getId() without initializing a proxy (important when using Hibernate, until HHH-3718 get resolved).
Drawback:
it makes the code less readable, you have for example to browse a whole class to see if there are #Transient around there.
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).
Let me try to summarize the most important reasons for choosing field-based access. If you want to dive deeper, please read this article on my blog: Access Strategies in JPA and Hibernate – Which is better, field or property access?
Field-based access is by far the better option. Here are 5 reasons for it:
Reason 1: Better readability of your code
If you use field-based access, you annotate your entity attributes with your mapping annotations. By placing the definition of all entity attributes at the top of your class, you get a relatively compact view of all attributes and their mappings.
Reason 2: Omit getter or setter methods that shouldn’t be called by your application
Another advantage of field-based access is that your persistence provider, e.g., Hibernate or EclipseLink, doesn’t use the getter and setter methods of your entity attributes. That means that you don’t need to provide any method that shouldn’t be used by your business code. This is most often the case for setter methods of generated primary key attributes or version columns. Your persistence provider manages the values of these attributes, and you should not set them programmatically.
Reason 3: Flexible implementation of getter and setter methods
Because your persistence provider doesn’t call the getter and setter methods, they are not forced to fulfill any external requirements. You can implement these methods in any way you want. That enables you to implement business-specific validation rules, to trigger additional business logic or to convert the entity attribute into a different data type.
You can, for example, use that to wrap an optional association or attribute into a Java Optional.
Reason 4: No need to mark utility methods as #Transient
Another benefit of the field-based access strategy is that you don’t need to annotate your utility methods with #Transient. This annotation tells your persistence provider that a method or attribute is not part of the entity persistent state. And because with field-type access the persistent state gets defined by the attributes of your entity, your JPA implementation ignores all methods of your entity.
Reason 5: Avoid bugs when working with proxies
Hibernate uses proxies for lazily fetched to-one associations so that it can control the initialization of these associations. That approach works fine in almost all situations. But it introduces a dangerous pitfall if you use property-based access.
If you use property-based access, Hibernate initializes the attributes of the proxy object when you call the getter method. That’s always the case if you use the proxy object in your business code. But quite a lot of equals and hashCode implementations access the attributes directly. If this is the first time you access any of the proxy attributes, these attributes are still uninitialized.
I prefer using field access for the following reasons:
The property access can lead to very nasty bugs when implementing equals/hashCode and referencing fields directly (as opposed through their getters). This is because the proxy is only initialized when the getters are accessed, and a direct-field access would simply return null.
The property access requires you to annotate all utility methods (e.g. addChild/removeChild) as #Transient.
With field access we can hide the #Version field by not exposing a getter at all. A getter can also lead to adding a setter as well, and the version field should never be set manually (which can lead to very nasty issues). All version incrementation should be triggered through OPTIMISTIC_FORCE_INCREMENT or PESSIMISTIC_FORCE_INCREMENT explicit locking.
That really depends on a specific case -- both options are available for a reason. IMO it boils down to three cases:
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;
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.
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).
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.
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.
I believe property access vs. field access is subtly different with regards to lazy initialisation.
Consider the following mappings for 2 basic beans:
<hibernate-mapping package="org.nkl.model" default-access="field">
<class name="FieldBean" table="FIELD_BEAN">
<id name="id">
<generator class="sequence" />
</id>
<property name="message" />
</class>
</hibernate-mapping>
<hibernate-mapping package="org.nkl.model" default-access="property">
<class name="PropBean" table="PROP_BEAN">
<id name="id">
<generator class="sequence" />
</id>
<property name="message" />
</class>
</hibernate-mapping>
And the following unit tests:
#Test
public void testFieldBean() {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
FieldBean fb = new FieldBean("field");
Long id = (Long) session.save(fb);
tx.commit();
session.close();
session = sessionFactory.openSession();
tx = session.beginTransaction();
fb = (FieldBean) session.load(FieldBean.class, id);
System.out.println(fb.getId());
tx.commit();
session.close();
}
#Test
public void testPropBean() {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
PropBean pb = new PropBean("prop");
Long id = (Long) session.save(pb);
tx.commit();
session.close();
session = sessionFactory.openSession();
tx = session.beginTransaction();
pb = (PropBean) session.load(PropBean.class, id);
System.out.println(pb.getId());
tx.commit();
session.close();
}
You will see the subtle difference in the selects required:
Hibernate:
call next value for hibernate_sequence
Hibernate:
insert
into
FIELD_BEAN
(message, id)
values
(?, ?)
Hibernate:
select
fieldbean0_.id as id1_0_,
fieldbean0_.message as message1_0_
from
FIELD_BEAN fieldbean0_
where
fieldbean0_.id=?
0
Hibernate:
call next value for hibernate_sequence
Hibernate:
insert
into
PROP_BEAN
(message, id)
values
(?, ?)
1
That is, calling fb.getId() requires a select, whereas pb.getId() does not.
By default, JPA providers access the values of entity fields and map those fields to database columns
using the entity’s JavaBean property accessor (getter) and mutator (setter) methods. As such, the
names and types of the private fields in an entity do not matter to JPA. Instead, JPA looks at only
the names and return types of the JavaBean property accessors. You can alter this using the #javax.persistence.Access annotation, which enables you to explicitly specify the access methodology
that the JPA provider should employ.
#Entity
#Access(AccessType.FIELD)
public class SomeEntity implements Serializable
{
...
}
The available options for the AccessType enum are PROPERTY (the default) and FIELD. With
PROPERTY, the provider gets and sets field values using the JavaBean property methods. FIELD makes
the provider get and set field values using the instance fields. As a best practice, you should just stick
to the default and use JavaBean properties unless you have a compelling reason to do otherwise.
You
can put these property annotations on either the private fields or the public accessor methods. If
you use AccessType.PROPERTY (default) and annotate the private fields instead of the JavaBean
accessors, the field names must match the JavaBean property names. However, the names do not
have to match if you annotate the JavaBean accessors. Likewise, if you use AccessType.FIELD and
annotate the JavaBean accessors instead of the fields, the field names must also match the JavaBean
property names. In this case, they do not have to match if you annotate the fields. It’s best to just
be consistent and annotate the JavaBean accessors for AccessType.PROPERTY and the fields for
AccessType.FIELD.
It is important that you should never mix JPA property annotations and JPA field annotations
in the same entity. Doing so results in unspecified behavior and is very
likely to cause errors.
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.
Another point in favor of field access is that otherwise you are forced to expose setters for collections as well what, for me, is a bad idea as changing the persistent collection instance to an object not managed by Hibernate will definitely break your data consistency.
So I prefer having collections as protected fields initialized to empty implementations in the default constructor and expose only their getters. Then, only managed operations like clear(), remove(), removeAll() etc are possible that will never make Hibernate unaware of changes.
I prefer fields, but I've run into one situation that seems to force me to place the annotations on getters.
With the Hibernate JPA implementation, #Embedded doesn't seem to work on fields. So that has to go on the getter. And once you put that on the getter, then the various #Column annotations have to go on the getters too. (I think Hibernate doesn't want mixing fields and getters here.) And once you're putting #Column on getters in one class, it probably makes sense to do that throughout.
I favor field accessors. The code is much cleaner. All the annotations can be placed in one
section of a class and the code is much easier to read.
I found another problem with property accessors: if you have getXYZ methods on your class that are NOT annotated as being associated with persistent properties, hibernate generates sql to attempt to get those properties, resulting in some very confusing error messages. Two hours wasted. I did not write this code; I have always used field accessors in the past and have never run into this issue.
Hibernate versions used in this app:
<!-- hibernate -->
<hibernate-core.version>3.3.2.GA</hibernate-core.version>
<hibernate-annotations.version>3.4.0.GA</hibernate-annotations.version>
<hibernate-commons-annotations.version>3.1.0.GA</hibernate-commons-annotations.version>
<hibernate-entitymanager.version>3.4.0.GA</hibernate-entitymanager.version>
You should choose access via fields over access via properties.
With fields you can limit the data sent and received.
With via properties you can send more data as a host, and
set G denominations (which factory set most of the properties in total).
Normally beans are POJO, so they have accessors anyway.
So the question is not "which one is better?", but simply "when to use field access?". And the answer is "when you don't need a setter/getter for the field!".
I had the same question regarding accesstype in hibernate and found some answers here.
I have solved lazy initialisation and field access here Hibernate one-to-one: getId() without fetching entire object
We created entity beans and used getter annotations. The problem we ran into is this: some entities have complex rules for some properties regarding when they can be updated. The solution was to have some business logic in each setter that determines whether or not the actual value changed and, if so, whether the change should be allowed. Of course, Hibernate can always set the properties, so we ended up with two groups of setters. Pretty ugly.
Reading previous posts, I also see that referencing the properties from inside the entity could lead to issues with collections not loading.
Bottom line, I would lean toward annotating the fields in the future.
i thinking about this and i choose method accesor
why?
because field and methos accesor is the same
but if later i need some logic in load field, i save move all annotation placed in fields
regards
Grubhart
To make your classes cleaner, put the annotation in the field then use #Access(AccessType.PROPERTY)
Both :
The EJB3 spec requires that you declare annotations on the element
type that will be accessed, i.e. the getter method if you use property
access, the field if you use field access.
https://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#entity-mapping
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".

Categories