为什么在JPA中需要独立实体? [英] Why need detached entities in JPA?

查看:109
本文介绍了为什么在JPA中需要独立实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与分离实体的问题相关的问题总是很多!

There are always so many questions related to issues with detached entities!

首先,它们经常导致Hibernate中的LazyInitializationException. 是的,还有另一种持久性提供程序,它们不抛出异常, 但是我认为他们在一致性方面存在一些问题. 考虑我们有引用的AB实体 (@ManyToOne)从AB,该值必须为非空.

First, they often cause LazyInitializationException in Hibernate. Yes, there are another persistence providers, which don't throw exceptions, but I think that they have some problems with consistency. Consider we have A and B entities that there is reference (@ManyToOne) from A to B that is required to be non-null.

我们开始了会话,加载了A实例,然后关闭了会话. 之后,我们尝试获取对B的引用. 并假设另一个事务刚刚删除了我们的AB实例.因此,当我们从数据库查询时,找不到合适的B实例并获得null

We started our session, loaded A instance and then closed session. After that we try to obtain a reference to B. And assume that another transaction just deleted both our A and B instances. So when we query from database we can't find appropriate B instance and get null!

因此违反了我们的合同.一些依赖于以下事实的代码: a.getB()返回的对象将抛出NullPointerException. 对于持久性实体,这是不可能的,因为我们都懒惰 通过获取对象本身加载同一笔交易, 因此所有操作都是原子操作(当然,如果我们有适当的事务隔离).

So our contract is violated. Some code that relies on fact that a.getB() returns an object will throw an NullPointerException. With persistent entities this is impossible because we have all lazy loading in the same transaction with obtaining object itself, so all operations are atomic (if we have a proper transaction isolation of course).

当您要将持久性实体和分离的实体存储在一个Set中时,也会出现问题.在这种情况下,您应该始终覆盖通常看起来很尴尬的equalshashCode,因为我看不到这样做的真正好方法.

Also there are problems when you want to store persistent and detached entities in one Set. It that case you should always override equals and hashCode, which usually looks awkward, as I can't see a really good way to do it.

要使独立实体重新回到EntityManager,您应该使用出现故障的merge.

To get a detached entity back into EntityManager you should use merge which is glitchy.

所以我的问题是:是否存在合理需要分离实体的合理情况?此外,何时必须混合分离实体和持久实体 并将分离的实体合并到新的EntityManager?

So my question is: is there is a reasonable scenario where detached entities are really needed? Furthermore, when do you have to mix detached and persistent entities and merge detached entities into a new EntityManager?

推荐答案

我将解释为什么不应该发生这种情况以及为什么我们需要分离的实体.

I will explain why that scenario should not occur and why we need detached entities.

考虑您正在进行JTA事务(JPA需要对此事务进行支持)并获取a. 现在,您可以在此事务中调用a.getB()(1)(即管理实体a),或者在断开a时调用(2).

Consider you are in a JTA transaction (JPA requires support for it) and fetch a. Now you can call a.getB() either (1) in this transaction (i.e entity a is managed) or (2) when a is detached.

方案1 :现在,根据您的事务隔离级别,您可能会看到或可能不会看到其他事务在做什么.例如,如果您具有SERIALIZABLE隔离级别,则即使该行在并发事务中被删除,您也将成功获取a.getB().如果该行已被删除,并且您的事务看到该行,则意味着您的数据库不一致(没有外键)或您使用了错误的事务隔离级别.

Scenario 1: now depending on your transaction isolation level, you might see or might not see what other transactions do. For example, if you have the SERIALIZABLE isolation level, then you will successfully fetch a.getB(), even if that row was deleted in a concurrent transaction. If that row was already deleted and your transaction sees that, it means that either your DB is inconsistent (no foreign key) or that you used the wrong transaction isolation level.

方案2 :实体a是分离的.当抛出LazyInitializationException时,对我而言,这意味着您为确保应用程序中的一致性而调用a.getB()的时间太晚了(因为不再管理a了).为了解决该问题,您只需在仍然管理实体时就更早地调用它.不会发生NPE.

Scenario 2: the entity a is detached. When a LazyInitializationException is thrown, that means to me that you called a.getB() too late in order to guarantee a consistence in your application (as a is not managed anymore). In order to solve the problem you simply call it earlier when the entity is still managed. A NPE cannot occur.

为什么我们需要DETACHED STATE?好吧,我们需要一个不跟踪对实体实例的更改的状态.为什么?

Why we need the DETACHED STATE? Well, we need a state in which the changes to an entity instance are not tracked. Why?

示例1 :假设您在EJB层中接收到一个实体(具有持久身份),并且没有分离状态(意味着应管理所有实体).但是我们需要在持久化实体之前进行验证.如果该实体将被自动管理,则其更改将自动保存到DB.因此引入了这种新状态.

Example 1: suppose you receive an entity (with persistent identity) in the EJB layer and that there were no detached state (meaning all entities should be managed). But we need to do a validation before persisting the entity. If that entity would be automatically managed, its changes would be automatically persisted to DB. So this new state was introduced.

示例2 :您在EJB层中收到一个实体,您只需要从该实体更新10个字段中的5个即可.如果该实体自动进入托管状态,则所有10个字段都将保留.在这种情况下,解决方案是获取一个受管实体,并仅更新该实体中的5个字段.

Example 2: you receive in the EJB layer an entity, any you need to update ONLY 5 fields of 10 from that entity. If that entity would get automatically into the managed state, all 10 fields would be persisted. The solution in this case is to fetch a managed entity and to update the 5 fields ONLY in that entity.

这篇关于为什么在JPA中需要独立实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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