Spring Data JPA - 为什么返回的Entity的更改会自动保留?

8bi*_*kie 25 spring jpa spring-data-jpa

我以一个例子提出这个问题.

断言我们有一个Repository,如下所示:

public interface ExampleObjectRepository extends CrudRepository<ExampleObject, Long> {

}
Run Code Online (Sandbox Code Playgroud)

通过扩展JpaRepository接口,ExampleObject存储库继承以下方法:

T findOne(ID id);
Run Code Online (Sandbox Code Playgroud)

现在,我观察到,如果在调用此方法后收到对ExampleObject的引用,我对此方法所做的任何操作都会自动保存到数据库中,例如:

ExampleObject pointInCase = exampleObjectRepository.findOne(1L);
pointInCase.setName("Something else");
Run Code Online (Sandbox Code Playgroud)

阅读这个主题,我明白这个ExampleObject实例就是这个标志not detached.

这违背了我的期望.我原以为我需要使用从中继承的save方法CrudRepository来保存更改:

T save(T entity);
Run Code Online (Sandbox Code Playgroud)

是否有人能够确认从Spring Data JPA Repository返回的对象仍然作为标准附加,并解释如何使用API​​在存储库中标记方法,使其仅返回分离的引用?

我想,改变实体的状态也可能在与所述save(T entity)方法一起使用时改变其定义,因此我也理解如何处理更新的身份.

JB *_*zet 22

这是JPA的基本原则.您使用附加(托管)实体,并且对这些托管实体所做的每个修改都会自动保持持久性.

如果您不希望更改是持久的,则不要进行更改或回滚事务.

处理分离的实体将是一场噩梦,因为它可以防止延迟加载所有关联.你总是可以打电话EntityManager.detach()给你的实体,但我真的不会这样做.试着了解它是如何工作的并处理它.有许多好处而不是缺点.其中之一就是你甚至不必考虑保存复杂业务逻辑可能会做的所有更改,因为这一切都是由JPA透明地完成的.

  • 为什么会这样?您启动事务,对所需的任何数量和种类的实体进行任意数量的修改,然后提交事务。要么提交所有更改,要么回滚所有更改。方法的事务方面也适用于它调用的每个内部方法:传播事务上下文。 (2认同)

Jen*_*der 5

如果您的Transaction限定为存储库,则可以使Repository返回已分离的实体.即,您的事务从进入存储库开始,并在代码退出存储库时关闭.

如果你这样工作,你必须要小心一次性加载所有必要的数据,否则你将得到延迟初始化异常.但在许多情况下,我认为这是可取的,因为它可以让您在何时以及加载了什么数据时对其进行控制,否则在使用JPA时会轻易地通过您的手指滑动.

对于修改,我使用不同的事务范围,它包装了加载,更改(和隐式持久)的完整过程.

  • 如何实现存储库的事务范围? (2认同)