Spring Boot JPA CrudRepository - entities are not attached to persistencecontext

ε祈祈猫儿з 提交于 2021-01-29 16:47:01

问题


I'm currently implementing my first spring boot application after years of JEE.

I am wondering about JPA / Hibernate behaviour. In JEE, once persisted or "find" an @Entity, all changes to this Entity are populated automatically by the JPA implementation to the database without any need to call persist(), flush() etc.

Now with a CrudRepository changes are only stored to the database if I explicitely call save().

My CrudRepository:

public interface UserAccountRepository extends CrudRepository<UserAccount, Long> {
    public Optional<UserAccount> findByEmail(String email);
    public Optional<UserAccount> findByVerificationCode(String verificationCode);
}

Example code:

public void updateUser(Long userId, String newName) {
    UserAccount userAccount = userAccountRepository.findById(userId)
            .orElseThrow(() -> new NotFoundException("Userid not found"));

    userAccount.setLastName(newName);        
    //Stop here in JEE
    userAccountRepository.save(userAccount);
} 

In a JEE implementation right after .setLastName the change would be persisted to the database by Hibernate. In my spring-boot service it istn't. It's usually explicitely necessary to issue .save() any idea why and how I could gain the same behaviour like in JEE?


回答1:


Actually Spring boot Repository uses JPA behind the scene to persist entity to the database. but I want to explain what happen behind the scene. You know there is an EntityManager which has a Persistence Context. When EntityManager created, it will attach itself to the current TransactionManager so that when that transaction committed all data within that Persistence Context will be committed to the database or on the other hand when transaction RollBack all data within that Persistence Context will be roll backed. Here in Spring Repository you can see that there is no Persistence Context explicitly. This Persistence Context exist but works behind the scene and when findById method return and deliver you the entity, that entity is not attached to persistence Context actually this context is closed when findById return.

But Spring Repository make all this proccess transparent to the user since it uses EntityManager and Transaction Manager behind the scene. actually it is the magic wand of Spring that let you omit all these boilerplate code. But this magic didn't come without any drawback, in your updateUser method you don't open and you don't commit any transaction but they acctually opened and committed two times behind the scene, once when you call findById method, it open transaction, fetch data and commit it. And again when you save data here again transaction open, and Persistence Context content save to database when transaction committed. imagine you have some transactional process in your special method in that case you should think about that specially.



来源:https://stackoverflow.com/questions/62289962/spring-boot-jpa-crudrepository-entities-are-not-attached-to-persistencecontext

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!