Spring Data JPA - Avoiding LazyInitializationException by reattaching detached entity - spring

Famous threads like LazyInitializationException with Spring Data JpaRepositories
mention many solutions to LazyInitializationException but do not mention reattaching the detached entity to a (new?) session when you want to lazy load the rest of the associated entities.
Is that because it can't happen ? If it is possible why isn't it mentioned as an alternative?
Most importantly how can you do that with Spring Data Jpa? Do you need to call the underlying Hibernate update() call in order to reattach? And as with Spring to which session do you attach if the session has already been closed after a Service call to the Repository? do you span a new session by calling into the repository again and with which JPA construct/command?

Related

Hibernate session factory and repository confusion

So there are two ways to persist an entity:
Using Hibernate's session factory where we get the current session and call save(), get(), update() methods.
Extending JPA's repository interfaces
I have the following questions:
How are these two methods different in the context of using Hibernate. As far as I understand, Hibernate is an implementation of JPA API. So when I say I want to use Hibernate, does it mean that I can use both of the above methods?
What is the preferred way of the two based on convenience, flexibility and optimisation?
JPA repository behind the scenes uses Hibernate or JPA APIs to implement its functionality and tries to "abstract" it or provide convenience methods on top of it. You don't have to use JPA repositories though, and can always switch to the Hibernate or JPA APIs when needed. Think though, if you really gain any benefit by using the Spring Data JPA repository concept.

Object/Entity lifecycles when using spring-data-jpa with hibernate as jpa provider?

When using spring-data-jpa with hibernate as jpa provider, are the Object/Entity lifecycles same as when using hibernate directly or as defined by hibernate (or might be jpa spec itself).
Hibernate defines these lifecycles to entities - Transient, Persistent, Detached, Removed.
Are these same life cycles applicable when using spring-data-jpa too.
If so how does below the methods provided by Hibernate map with the methods of spring jpa crud repository.
//below methods in hibernate move an entity to persistent state
save(e),
persist(e);
update(e);
saveOrUpdate(e);
lock(e);
merge(e);
and
//below methods in hibernate move an entity to detached state
detach(e);
evict(e);
For the first part of the question:
Spring Data JPA just offers some comfortable mechanics on top of JPA.
The persistence, mapping and life cycle is still managed by JPA or its implementation, i.e. Hibernate in your case.
This means the life cycle is the same.
As for the mapping between Spring Data JPAs methods and Hibernates/JPA methods see the following table.
Spring Data
JPA
CrudRepository.save*
for new entities EntityManager.persist, EntityManager.merge otherwise
CrudRepository.delete*
EntityManager.remove
CrudRepository.findById
EntityManager.find*
JpaRepository.*flush
EntityManager.flush
JpaRepository.getById
EntityManager.getReference
Other query methods predefined in interfaces or otherwise use various types of queries.
Spring Data Jpa is only an abstraction layer and not provide a lifecycle management. Therefore, if you are using hibernate as a jpa implementation your object's lifecycle will regulated according to hibernate's lifecycle management.
Also, you can find some other explanations here and here as well.

Pass Spring datasource to Javers to Audit DTOs

In My Spring Boot application, I would like to audit DTOs instead of entities and move audit logic to common library which will have #EnableAudit annotation to audit DTO at method level. If I am using JaversBuilder.javers().build(); in common library I would not be able to commit data as it would not know anything of datasource.
I want to create Javers instance in my application and pass datasource to it and then pass Javers instances to common library to perform commit. Is there anyway in Spring boot application to create Javers instance and associat datasource to it which will be used at the time of commit ?
If you take javers-spring-boot-starter, you will get a Javers instance created as a Spring bean. It will be connected to your database and ready-to-use. See https://javers.org/documentation/spring-boot-integration/

Should one close Hibernate Session object every time after performing any CRUD operation?

I am working with enterprise application that uses Spring 3.x with Hibernate annotated programming.I am working with hibernate Session object for performing db operations in my XYZDaoImpl class.
And my doubt is "Is it correct way to close Hibernate Session object every time after performing any CRUD operation?"
If it is not the correct way, please advise me the recommended way of opening/closing of hibernate Session Object.
can you post a bit daoImpl code......
If you use sessionFactory.getCurrentSession(), you will get current session..in this case framework automatically flushed and closed when the transaction ends (commit or rollback).
If you use sessionFactory.openSession(), you have to manage the session yourself and to flush and close it "manually".
No, when using hibernate with spring, you should not (manually) open or close sessions, but let spring manage the hibernate session for you. Spring manages the session as a transactional resource, so you have to configure transaction management correctly.
If you open/close the hibernate session manually, you are hardly using the integration between these two frameworks: the session management is the main feature of the integration.
The only reason to open/close a hibernate session in a spring context is to use the same session to span multiple transactions.

How to reduce database query when using stateless framework like Spring MVC

I just moved to Spring MVC for several days. Before that, I used to develop web project using JSF, EJB and JPA.
In EJB, we can use a stateful session bean(SFSB) with extended persistence context so that I can cache the entities in order to reduce database query. But in Spring MVC, once the entity is returned from a #Service bean, it becomes detached and cannot survive the next request. So I have to query database again in next request.
My question is how can I keep an entity managed by Entitymanager during many request?Thanks!
Use a 2nd level cache or session scoped beans, to keep entities in memory. Spring beans have mulplie different possible scopes.
Worth mentioning that keeping everything stateless makes scaling out easier. And adding state to anything http is always counter intuitive, to me at least.

Resources