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

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.

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.

Spring Data JPA - Avoiding LazyInitializationException by reattaching detached entity

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?

With Spring Data JPA, under what circumstances should I use EntityManager directly?

Spring Boot Data JPA does an amazing job of generating repositories and abstracting away the managemet of Datasources and EntityManager etc. But sometimes I see code where the EntityManager is included as a field and accessed directly, like in this Dzone example
I don't really understand from that example, when should I include the EntityManager in my class and interact with it directly and when can I just rely on the repository Spring Data JPA autogenerates? Can someone explain?
One good use of EntityManager that I can think of is when you want to get results from a database using complex queries such as join. You can directly query using EntityManager and use ResultTransformer to get into your custom model.

Is Repository the only way to save entity data on DB?

I'm studying Spring boot, and i have create several entity, my problem now is to retrieve the data from controller to save it on db.
Surfing on the web I have learned that i have to use JPARepositery or CrudRepositery in this way:
An example with User entity
public interface UserRepository extends CrudRepository<User, Integer> {
}
and to save
User user = new User();
userRepository.save(user);
But if I have many entities, Do I need to create a repository for each entity?
I have read about Session, FactorySession and Transaction they are compatible with Spring boot? How it works? and #Transactional tag how it works?
Thanks in advance
Yes, usually you need to create one Repository per Entity. This is also a good practice because you are placing operations and queries related to the same Entity in the same Repository.
Yes, you can obtain a Session and a FactorySession object (Hibernate), but I would advice you against using Hibernate directy. Instead, it is better to use Spring Data or JPA mechanisms to access your database (just as you do using a Repository). The reason is because Hibernate is an implementation of the JPA standard and today we use JPA to access databases (because it masks the exact implementation of the ORM). This way you can later (potentially) replace Hibernate with another JPA implementation (such as EclipseLink) without the need to change your code (in theory). In most projects you will find Hibernate being used, however.
Yes, Transaction is a Spring annotation and an important database transaction mechanism in Spring Boot, too.

Transitioning to Spring Data

We are currently using Spring 3.2.3 + JPA (Hibernate). We use aspects for transaction support as opposed to annotations. We write out own entity services (read: repositories) to abstract the persistence away from our application.
I've read a lot about Spring Data and feel it would make our code considerably cleaner and more robust. I wonder though, are there any gotchas that I should consider before transitioning?
Thanks
If you're already on JPA the transition should be as easy as it can be: activate the repositories, point the infrastructure to your EntityManagerFactoryBean and off you go.
Transactions should just work fine as well. The annotation based usage within Spring Data is selectively activated for the repository beans only. They are configured to take part in existing transactions by default, so any custom larger scoped transaction setting should be in effect already.

Resources