Thursday, September 15, 2011

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:

Problem
I had two objects Contacts and Groups having many-to-many association.
A Contact can belong to multiple Groups and a Group can contain multiple Contacts.
My objective was to return a set of Contacts along with the Groups they were associated with.

But if the Contacts-Groups association is set to Lazy load then the above exception will be thrown.

Solution
1. FetchType can be set to EAGER and everything will work fine, the Groups will be loaded; but in a more general case, where the graph of java objects can grow very large, the use of eager fetch may cause unnecessary data to be loaded and the application will be slowed down.

2. Another solution is to explicitly load any lazy-loading the required fields actually hitting a method on those properties
ex: contact.getEmailSet().size(). But this will result in subsequent sql firing which are required to load Groups (Child)
Will also slow down the system.

3. Another solution is to include "fetch join" which allows associations or collections of values to be initialized along with their parent objects using a single select. This is particularly useful in the case of a collection. It effectively overrides the outer join and lazy declarations of the mapping file for associations and collections.





Contacts Domain Object:
@Entity
@Table(name = "Contacts")
public class Contacts implements java.io.Serializable
{
…..
…..
private Set emailSet = new HashSet(0);
….
….

@ManyToMany(targetEntity = EmailList.class, cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch= FetchType.LAZY)
@JoinTable(name="Contacts_EmailGroup", joinColumns={@JoinColumn(name="contactsId")}, inverseJoinColumns={@JoinColumn(name="emailGroupId")})
public Set getEmailSet() {
return this.emailSet;
}
public void setEmailSet(Set emailSet) {
this.emailSet = emailSet;
}
}

EmailList Domain Object:
@Entity
@Table(name = "EmailGroup")
public class EmailList implements java.io.Serializable
{
….
….
private Set contacts = new HashSet(0);
….
….

@ManyToMany(targetEntity = Contacts.class, cascade = { CascadeType.PERSIST, CascadeType.MERGE }, mappedBy="emailSet")
public Set getContacts() {
return this.contacts;
}
public void setContacts(Set contacts) {
this.contacts = contacts;
}
}

DAO layer :
private EntityManager contactsEntity;


public List findAllContacts()
{
Query qry = contactsEntity.createQuery("FROM Contacts c left join fetch c.emailSet");
return qry.getResultList();
}



Hope the solution will be of some use :)

Thanks

A Solution to Hierarcy Cycle Problem with JSON: JSON Filter

When you have a cycle in your domain model, beacuse sometimes you realy need it*, then with Spring JsonView, indeed you may have same problem in different cases, while converting Java objects to JSON objects, you can get en error :

net.sf.json.JSONException: There is a cycle in the hierarchy!

with a following unusefull stack trace:)

First of all, think carefully fi you really do need this cycle in the dependency. If you don’t, remove it.
If you do, the you can use, JSON filters.

I will give an example code to show it. In the code, resulting JSON object will contain only id, name and description fields and values of the objects.




JsonConfig config = new JsonConfig();
config.setJsonPropertyFilter(new PropertyFilter() {
public boolean apply(Object source, String name, Object value) {
if ("name".equals(name) || "description".equals(name) || "id".equals(name)) {
return false;
}
return true;
}
});
List jsonObjects = new ArrayList();
for (Object object : objects) {
jsonObjects.add(JSONSerializer.toJSON(object, config));
}
//Here you have jsonObjects, do whatever you need.
...


This is a sample code. It depends on you how to use this in a proper way! :)

* Consider, you have an class X with composition Y, and in Y class, if you need all Xs referenced by Y, then you will probably have a property containing list of X. Then you have cycle! For example, Employee works on a Department, so Employee has a composition with Department, in Department you need all employees workin in this department.

Let's try to build scrum masters/project managers/software architects/even a company with training AI models

The concept: The basic concept is to build trained AI model for each role separately in scalable fashion within a private cloud. As an examp...