Spring Boot JPA CrudRepository-实体未附加到persistencecontext [英] Spring Boot JPA CrudRepository - entities are not attached to persistencecontext

查看:64
本文介绍了Spring Boot JPA CrudRepository-实体未附加到persistencecontext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

经过多年的JEE,我目前正在实现我的第一个spring boot应用程序.

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

我想知道JPA/Hibernate的行为.在JEE中,一旦持久存储或找到" @Entity,对JEntity的所有更改将由JPA实现自动填充到数据库中,而无需调用persist(),flush()等.

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.

现在,只有在我明确调用save()的情况下,具有CrudRepository的更改才会存储到数据库中.

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

我的Crud存储库:

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

示例代码:

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);
} 

在.setLastName之后的JEE实现中,更改将由Hibernate持久保存到数据库中.在我的spring-boot服务中,它不是.通常明确需要发出.save()任何想法,为什么以及如何获得与JEE中相同的行为?

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?

推荐答案

实际上,Spring Boot Repository在后台使用JPA将实体持久保存到数据库中.但我想解释一下幕后发生的事情.您知道存在一个具有持久性上下文的EntityManager.创建EntityManager时,它将自身附加到当前的TransactionManager上,以便当该事务提交了该持久性上下文中的所有数据时,都将其提交给数据库,或者另一方面,当事务回退该持久性上下文中的所有数据时,回滚.在Spring Repository中,您可以看到没有持久性上下文.此持久性上下文存在,但在后台工作,并且findById方法返回并为您提供实体时,该实体未附加到持久性上下文,实际上,当findById返回时,此上下文已关闭.

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.

但是Spring Repository使所有这些过程对用户透明,因为它在后台使用了EntityManager和Transaction Manager.实际上,正是Spring的魔杖使您忽略了所有这些样板代码.但是,这种魔力并非没有任何缺点,在您的updateUser方法中,您没有打开并且没有提交任何事务,但是它们实际上是在后台打开并提交了两次,一次是在调用findById方法时提交的,它将打开事务,获取数据并提交.再次,当您在此处保存数据时,再次打开事务,并且在提交事务时将持久性上下文内容保存到数据库.假设您在特殊方法中有某种交易过程,那么您应该特别考虑一下.

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.

这篇关于Spring Boot JPA CrudRepository-实体未附加到persistencecontext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆