Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是;“预先存在”;在JPA2.0持久性上下文中的托管实体实例上下文中是什么意思?_Jpa - Fatal编程技术网

什么是;“预先存在”;在JPA2.0持久性上下文中的托管实体实例上下文中是什么意思?

什么是;“预先存在”;在JPA2.0持久性上下文中的托管实体实例上下文中是什么意思?,jpa,Jpa,我相信我可能对JPA关于持久性上下文的概念以及该方法如何使用它有一个基本的误解 背景 动机 我希望能够依赖于merge()操作的特定行为,我突然意识到这可能不会发生。具体地说,我想依靠它模糊地暗示的UPSERT功能。就这个问题而言,我对级联行为或任何类型的缓存都不感兴趣。此外,在这个问题上,我对一个供应商如何做事情或另一个供应商如何做事情不感兴趣;我对语言和要求感兴趣 这个问题很长,故意重复了好几次;我发现并不是每个人都用同样的方式来表达,所以我想用不同的方式来表达。请原谅我的长篇大论 规范引用

我相信我可能对JPA关于持久性上下文的概念以及该方法如何使用它有一个基本的误解

背景 动机 我希望能够依赖于
merge()
操作的特定行为,我突然意识到这可能不会发生。具体地说,我想依靠它模糊地暗示的
UPSERT
功能。就这个问题而言,我对级联行为或任何类型的缓存都不感兴趣。此外,在这个问题上,我对一个供应商如何做事情或另一个供应商如何做事情不感兴趣;我对语言和要求感兴趣

这个问题很长,故意重复了好几次;我发现并不是每个人都用同样的方式来表达,所以我想用不同的方式来表达。请原谅我的长篇大论

规范引用 第7.1节中规定:

持久性上下文是一组托管实体实例,其中对于任何持久性实体标识,都有一个唯一的实体实例。在持久性上下文中,实体实例及其生命周期由实体管理器管理

(因此,这段话说:考虑一组对象;我们将其命名为持久性上下文。它的成员将其生命周期由<代码> EntItMyReals/CODE管理,并且将对应于它们在数据库Land中的匹配持久表示。它们的<代码> @ ID>代码> S,也就是说,将匹配DAT中的对应主键。贬低)

请注意,本段没有说明对象如何进入集合(实体如何进入持久性上下文),只说明一旦有对象在其中,哪些条件必须为真。有关如何进入集合的规则在规范的其他地方有规定

最后,为了完整性,从语义上讲,空的持久性上下文似乎是可以的。在执行
EntityManager\clear()
之后,会产生持久性上下文

第3.2.7.1节说:

应用于实体X的合并操作的语义如下所示:

•如果X是分离实体,则将X的状态复制到具有相同标识的先前存在的托管实体实例X'上,或者创建X的新托管副本X'

问题: 当我们在持久性上下文中谈到预先存在的托管实体实例时,预先存在到底意味着什么?

或者:以一种迂回的方式,我真的在问
clear()
做了什么:它真的清空了持久性上下文,还是只清空了当前可能保留引用的对象

或者:假设我的持久性上下文为空(我刚刚调用了
EntityManager#clear()
)。其中是否有任何标识的“预先存在的托管实体实例”?是否所有数据库行都本质上存在于持久性上下文中,即
clear()
操作并不意味着持久性上下文真的是空的,只意味着如果不添加一些内容,就无法从中获得任何东西

或者:在执行
merge()
操作时,
EntityManager
实现是否有义务在
merge()
被调用,如下所示:

// Assuming a previously empty persistence context (em.clear()).
// Pseudocode follows as though this were part of the
// EntityManager merge() implementation.
//
// Here "pre-existing" means "not there to start with,
// but located just in time and thus snuck into the
// persistence context from disk as though it had been
// there all along".  This would mean that things like
// primary key violations and the like at flush() time would be 
// effectively prohibited by spec.
SomeEntity xPrime = this.find(SomeEntity.class, x.getID());
if (xPrime == null) {
  xPrime = new SomeEntity();
  manage(xPrime);
}
assert isManaged(xPrime); // hypothetical method
copyProperties(x, xPrime);
return xPrime;
在本例中,
X'
是否说是预先存在的,即使在调用
merge()
时,持久性上下文是空的

或者,一致的
EntityManager
只需执行以下操作:

// Assuming a previously empty persistence context.
// Pseudocode follows as though it were part of the
// EntityManager merge() implementation.
//
// Here "pre-existing" means "already in the persistence context",
// which given that we're assuming we started with an empty one,
// means we just do a new instance here.  This scares me but I can't
// see how the spec rules this out.
SomeEntity xPrime = new SomeEntity();
copyProperties(x, xPrime);
manage(xPrime);
assert isManaged(xPrime); // hypothetical method
return xPrime;
这种解释的理由可能是句子中说“……或者创建了X的新托管副本X”,这让我认为JPA供应商可以决定是否需要费心先执行
find()
。在第二种解释下,如果没有隐式尝试
find()
,则在
flush()处
time您可能会遇到主键冲突,JPA提供商可能会尝试在实际发生
更新时插入

同样的问题变得更加具体:

假设我的持久性上下文为空(比如,我有一个名为
EntityManager#clear()

假设我手中有一个分离的实体,
X
,带有一个
@Id
-注释的
long
字段,该字段包含值
6L
EntityManager#contains(X)
返回
false

假设我的数据库中有一个
x
表,其中有一行主键是
6
,进一步假设我的
x
实体映射到它

(让我先说点俏皮话:我们可以说,
X'
在这一点上作为托管实体实例预先存在吗?它是否隐式地“预先存在”,因为它可以立即、及时地进行管理,所以就好像它存在一样?回想一下,我们刚刚调用了
em.clear()

现在假设我在分离的实体(
X
)上调用
EntityManager#merge(Object)

根据该规范,“将X的状态复制到具有相同标识的预先存在的托管实体实例X'上,或者创建X的新托管副本X'

在持久性上下文中是否存在一个相同标识的“预先存在的托管实体实例X”(
6
),回想一下我们刚才调用的
em.clear()

一种解释是:不,当然没有;持久性上下文是空的;我们
clear()
ed它;它里面什么都没有