2 Replies Latest reply: Dec 24, 2012 10:12 PM by Lin Gao RSS

Errai, Hibernate and JSON lazyInitializationException

Daniel Kemp Newbie

I have done some sampling work on the kitchen sink quickstart app and have had quite the run with playing with the REST services.

 

All of the services I have created work well when using XML. However, when fetching entities with JSON as the requested content type I get this error:

 

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role no session or session was closed.

 

The entities have several OneToMany relationships and are defaulted to a Lazy fetch. If I change the bag non persistant properties to an eager fetch I get a non stop loop of data.

 

I have searched for a solution but cannot find one which is suitable for errai: I have seen a solution where I can add @JsonIgnore on the methods that do not corelate to the entities persistant fields but I think this was from the Jackson API. It is my understanding that Errai has its own JSON engine?

 

Are there any suggestions on how this could be remedied using Errai JSON or any other suitable workaround that someone knows of?

 

 

@Portable
@Entity
@XmlRootElement
public class Territory implements Serializable {

    @Id
    private Integer id;

     ...
    private String name;

    @OneToMany(fetch=FetchType.LAZY, mappedBy = "territory")
    private List<Merchandiser> merchandisers = new ArrayList<Merchandiser>();

    @OneToMany(fetch=FetchType.LAZY, mappedBy = "territory")
    private List<Store> stores = new ArrayList<Store>();

...
    @XmlTransient
    public List<Merchandiser> getMerchandisers() {
        return merchandisers;
    }
...

 

 

@Portable
@Entity
@XmlRootElement
public class Merchandiser implements Serializable, Comparable<Merchandiser> {

          @Id
          private Integer id;
       ...
          private String name;
           ...
          private String mobile;
       ...
          private String email;

          @JoinColumn(name = "address", referencedColumnName = "id") 
          @ManyToOne(fetch=FetchType.EAGER) 
          private Address address;

          @JoinColumn(name = "territory", referencedColumnName = "id") 
          @ManyToOne(fetch=FetchType.EAGER)
          private Territory territory;
...

 

Addendum:

I am assuming this relates to this: http://jira.codehaus.org/browse/JACKSON-276

 

Message was edited by: Daniel Kemp

  • 1. Re: Errai, Hibernate and JSON lazyInitializationException
    Jonathan Fuerth Master

    Hi Daniel,

     

    The simple answer to this question is that within your JAX-RS resource methods, you should first detach your entities from the EntityManager, then prune off the references you don't want (by setting many-to-one associations to null, and clearing out one-to-many associations).

     

    But which references to prune? This depends mostly on how you expect your clients to consume the data.

     

    I'm guessing you have set up your resource paths like this:

     

    /myapp/v1/territory/{territoryId}

    /myapp/v1/merchandiser/{merchantId}

    /myapp/v1/store/{storeId}

     

    So Option A for pruning references would be to prune store and merchandiser references out of territories, making the results of GET /myapp/v1/territory/1 look like this:

     

    {

      id: 1,

      name: "Northwest",

      stores: [],

      merchandisers: []

    }

     

    and then stores and merchandisers would go back unpruned, but their nested Terrirory elements would similarly have the stores and merchandisers collections cleared out (by code you add to the JAX-RS resource methods).

     

    On the other hand, your client application might have the opposite requirement (that users first get an overview of territories, and then they select one and choose from the stores and merchandisers inside it). In this case, you could go with Option B, which is to null-out the references from store to territory and merchandier to territory.

     

    There is also Option C, in which you are making a generic REST API where you don't know how the clients will usually consume the data. In this case, you could add request parameters so the client can specify which associations it wants populated (default is none):

     

    GET /myapp/v1/territory/1?with=stores

     

    {

    id: 1,

    name: "Northwest",

    stores: [{id: 1, name="store1"}, { ... }, { ... }],

    merchandisers: []

    }

     

    Hope this helps!

     

    -Jonathan

  • 2. Re: Errai, Hibernate and JSON lazyInitializationException
    Lin Gao Newbie

    Maybe the article: https://developers.google.com/web-toolkit/articles/using_gwt_with_hibernate can solve your problem.

     

    If Errai can provide a solution to intergrated Hibernate collection mappings, it would be great.