Search code examples
hibernatejpajpqleager

OneToMany LazyInitializationException when collection is empty


I know there are dozens of questions with the same topic but I cannot figure it out why they are not working in my case.

I have two tables, one with the name of Account and one with CustomerRelations, and there is a one-to-many relarionship between them (to one account can belong several customerRelations... an account can exist without other customer relations but a customer relation can only be attached to an existing account)

This is how they are annotated in my entity classes:

Account table:

@OneToMany(mappedBy = "account", cascade = CascadeType.ALL, orphanRemoval = true)
@OnDelete(action = OnDeleteAction.CASCADE)
private List<CustomRel> customRels = new ArrayList<>();

CustomerRelation table:

@ManyToOne(fetch = FetchType.EAGER)
private Account account;

I have the business logic where I want to call a query based on specific date saved in the Account tabel:

@NamedQuery(name = Account.FIND_BY_ACC_NBR, query = "select acc from Account acc where acc.accountNumber =:accountNumber")

This query gives the correct data from the account table but for the field customerRels I get the following exception:

**Unable to evaluate the expression Method threw 'org.hibernate.LazyInitializationException' exception.**

The same comes when a getter method is called on my Account object:

enter image description here

In my example case, there is an account object with an empty list of customerRels. So there is no customerRels record in the database which is connected to the accountId.

As far as I know that the fetchType in my Account entity class in lazy - as default, right?.

In my SQL scripts which are creating the tables, there is only an account_id added in the CustomerRelations table, in the Account table there is no reference to the child object.

I know it is a very banal issue, but I need some help. Should I modify my JPQL query?


Solution

  • OneToMany is default LAZY and you are accessing collection outside of hibernate session(running transaction). Even the list is empty a select is needed to initialize lazy collection. Persistence cannot know if there are items in collection, unless it checks in DB.

    options:

    1. FetchType.EAGER
    2. join fetch rels r in your JPQL
    3. initialize collection inside transaction/session