Reputation: 1561
Good day. I need to check initialization (loaded) of fields. For this task I try to use Hibernate.isInitialized
. I have the following entities:
@Entity
public class Contractor {
/* ... */
@OneToMany(mappedBy = "contractor", fetch = FetchType.LAZY)
private List<Work> works = new ArrayList<Work>();
/* ... */
}
@Entity
public class Work {
/* ... */
@ManyToOne(fetch = FetchType.LAZY)
private Contractor contractor;
@ManyToOne(fetch = FetchType.LAZY)
private Project project;
/* ... */
}
@Entity
public class Project {
/* ... */
@OneToMany(mappedBy = "project", fetch = FetchType.LAZY)
private List<Work> works = new ArrayList<Work>();
/* ... */
}
Then I try to fetch entities by follow method:
List<Contractor> list = em.createQuery("SELECT c FROM Contractor c").getResultList();
for (Contractor contractor : list) {
Hibernate.initialize(contractor.getComments());
Hibernate.initialize(contractor.getWorks());
for (Work work : contractor.getWorks()) {
Hibernate.initialize(work.getProject());
}
}
return list;
After that I check initialization sign of fields (for serialization) by two way:
Project p = contractor.getWorks().get(0).getProject();
Field f = Hibernate.getClass(p).getDeclaredField("works");
f.setAccessible(true);
System.out.println(Hibernate.isInitialized(f.get(p)));
System.out.println(Hibernate.isInitialized(contractor.getWorks().get(0).getProject().getWorks()));
And results are different for collections (true, false), but same for single objects. May be anyone know why?
Upvotes: 1
Views: 8032
Reputation: 78579
You could ensure your lazy relationships are fetched in the query itself and avoid having to check if they are initialized:
SELECT c FROM Contractor c JOIN FETCH c.comments JOIN FETCH c.works
The JOIN FETCH is a special type of join which simply ensures the loading of related entities. This would still just return the contractor objects but it will make sure its related comments and works have been loaded (even if they are declared as lazy).
--Edit--
Perhaps you can do the validations using the standard JPA API. Both the PersistenceUnitUtils class and the PersistenceUtil have two helpful methods:
boolean isLoaded(java.lang.Object entity)
Which determines the load state of an entity belonging to the persistence unit.
boolean isLoaded(java.lang.Object entity, java.lang.String attributeName)
Which determines the load state of a given persistent attribute of an entity belonging to the persistence unit.
These too methods should do the trick for you, hopefully in a consistent way.
Upvotes: 1
Reputation: 372
Hibernate persisting ArrayList - Issues
I had a similar problem. Needed to annotate my class
@OneToMany(mappedBy="tournament")
private List<String> registered;
changed to this
@ElementCollection
@CollectionTable (name = "tournament_eligible", joinColumns=@JoinColumn(name="id"))
private List<String> username; // Contains a list of eligible members
This resolved that issue for me, though my lists just had String objects in them, I can't imagine it would be too much different.
Upvotes: 0