Hibernate - LazyInitializationException - delete an object from a proxy and session

MyObject myObject = repositoryHibernateImpl.getMyObjectFromDatabase(); //transaction is finished, and no, there is not an option to reopen it ThirdPartyUtility.doStuffWithMyObjectType( myObject ); 

at this point, you have already determined that it is lazily and eagerly loaded, and a third-party utility will try to call all the methods on your "myObject" instance, this is normal because you do not want to return anything for lazily loaded properties, unfortunately, it does not return null, it throws a LazyInitializationException .

This is because you actually call the method on the Hibernate proxy of your object, and it knows that it did not retrieve this data and throws an exception.

Is it even possible to get a base object with null values ​​so that the getter simply returns null and does not throw an exception? Basically separating the object so that Hibernate no longer knows about it. An accessor to an object that is lazily loaded must return null, it cannot return the actual values, we want to be able to convert the object to POJO without creating an object that looks just like an object, and must reassign all the values.

+4
source share
3 answers

Say you have a field, in a getter you could:

 MyField getMyField() { if (Hibernate.isInitialized(myField)) { return myField; } return null; } 

From javadoc org.hibernate.Hibernate:

public static boolean isInitialized (Object proxy): check if the proxy or persistent collection is initialized.

+2
source

If you do not want to associate your domain with Hibernate, another possibility is for your DAO to instantiate your own instance of the object from inside getMyObjectFromDatabase () and populate it with the appropriate fields from the Hibernate proxy. I did it and it works well.

Obviously, this is more code, but you are guaranteed a β€œclean” instance of your entity (complete with zero uninitialized values) if that is what you want.

0
source

check out my solution.

Minimal example:

I do not load the property from the object, but from the controller.
The code:

 {..} MyProp prop = employeeController.getMyProp(employee); {..} 

This initiaqlizes property through the repository object and returns it.
EmployeeController.java:

 public Set<MyProp> getMyProp(Employee employee) { if (this.employeeRepository.InitMyProp(employee)){ return employee.getMyProp(); } return null; } 

Repository get / open session, reload employee object ! and initialize the lazy loaded field
EmployeeRepository.java:

 public boolean InitMyProp(Employee employee) { if (Hibernate.isInitialized(employee.getMyProp())){ return true; } try { Session session = getSession(); session.refresh(employee); Hibernate.initialize(employee.getMyProp()); } catch (Exception ex) { return false; } return true; } private Session getSession(){ if (session == null || !session.isConnected() || !session.isOpen()){ session = HibernateUtil.getSessionFactory().getCurrentSession(); } if (!session.getTransaction().isActive()) { session.beginTransaction(); } return session; } 

I have in my solution a TableView with several thousand records and 2 more TableViews with detailed information about the selected record in the first TableView.
hope this helps.

0
source

All Articles