1
votes

I have table called category which has parent category field. I am using that field to get the sub categories. I have checked the answer for the similar question, the suggestion was (fetch = FetchType.EAGER). But I want to load it as LAZY because it is circular dependency. (Pointing to the same table again).

@Entity
@Table(name = "CATEGORY")
public class Category implements Serializable {
    @Id
    @Column(name = "ID")
    @GeneratedValue
    private Integer id;

    @Column(name = "CATEGORY_NAME", nullable = false, length = 40)
    private String name;

    @Column(name = "DESCRIPTION", nullable = false, length = 255)
    private String description;

    @Column(name = "DATE_CREATED", nullable = false)
    private Date dateCreated;

    @Column(name = "UUID", nullable = false, length = 40)
    private String uuid;

    @ManyToOne
    @JoinColumn(name = "PARENT_CATEGORY_ID")
    private Category parentCategory;

    @OneToMany(mappedBy = "parentCategory")
    private Collection<Category> subCategories = new LinkedHashSet<Category>();
}

The error is:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.hemanths.expense.manager.api.hibernate.entity.Category.subCategories, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:545)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:124)
    at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:266)

Can someone help me find the solution?

2

2 Answers

2
votes

If you want to fetch a collection of objects that are annotated to be lazy loaded and you don't want to convert the loading mechanism to eager, then you will have to fetch the collection in the same session or transaction that you are fetching your parent object in it by only calling the size() method for your collection, for example if you have a service method like this:

public Category getCategortById(int id) {
  Category category = categoryDao.getCategortById(id);
  category.getSubCategories().size();  // Hibernate will fetch the collection once you call the size()
}

Also, If you want a cleaner way for it, you can use Hibernate.initalize() method, to initialize any lazy loading object or collection, so it could be like this

 public Category getCategortById(int id) {
  Category category = categoryDao.getCategortById(id);
  Hibernate.initialize(category.getSubCategories());
}

You can check more on Initializing collections here

1
votes

Looking at your stack trace, it looks like this is a session management issue. Try looking at where you are opening your session, and what SessionContext you are using?