【发布时间】:2011-08-02 09:58:46
【问题描述】:
我有一个包含两个表的数据库(实际上更重要,但在这种情况下这无关紧要)。两者之一具有对另一个的外键引用。这些可能是映射:
@Entity @Table public class A {
@Id public String id;
@Version public int version;
@OneToMany(targetEntity = B.class,
mappedBy = "a",
cascade = CascadeType.ALL,
fetch = FetchType.LAZY)
public Collection<B> bs;
...
}
@Entity @Table public class B {
@Id public String id;
@Version public int version;
@ManyToOne(targetEntity = A.class,
cascade = CascadeType.ALL,
fetch = FetchType.LAZY)
public A a;
...
}
我有一个中间数据结构,它包含有关A 和B 之间关系的信息,我在将我的数据保存在活动事务中之前对其进行迭代,检查A 或B 是否已经存在数据库是否使用EntityManager.find(Class<T>, Object):
// get an entity manager and begin transaction
for (C c : cs) {
A a = em.find(A.class, c.getAId()); // an `A` doesn't exist in the database
if (null == a) { // on first iteration so a new one will
a = new A(); // be created
a.id = c.getAId(); // however in a 100 `C` there are 4-5
} // unique `A` exists
B b = em.find(B.class, c.getBId()); // a `B` generally doesn't exist in
if (null == b) { // the database, but the opposite
b = new B(); // could happen often
b.id = c.getBId();
b.a = a;
a.bs.add(b);
}
if (!em.contains(b)) // if a `B` was found in the database
em.persist(b); // persist won't execute here
}
// commit transaction
这很好用:新数据会被持久化,而现有的数据不会。
但是!无论在 for-each 循环中发生什么,我的数据库中的版本列总是都会更新。我已经获取了一组样本数据,将其保存在我的空表中(版本为 0);我已经获取了同样的一组样本数据并再次保存它(EntityManager.persist(Object) 从未被调用)并且版本字段(A)得到了更新,但我无法想象为什么。
我知道即使 EntityManager.persist(Object) 从未被调用,我的持久性提供程序 (Hibernate) 也会生成更新语句来增加版本列。
问题:为什么?我怎样才能防止这种情况?为了避免这种情况,我应该对我的数据持久化方法进行哪些更改?谢谢。
【问题讨论】:
-
我无法重现这个。我将您的代码敲成可运行的形状 - gist.github.com/914504 - 并使用 OpenJPA 2.0.1 运行它(我重命名了这些类,因为不管你信不信,OpenJPA 阻塞了一个名为“B”的类!)。版本列不会随着重复运行而增加。您使用的是什么提供商?你能和你的供应商一起运行这个小应用程序,看看会发生什么吗?
-
I can't reproduce this.从那以后我也没有。你的代码完美无瑕……我不得不稍微修改一下我的数据库布局,在那里添加代码,在那里删除一些代码……然后它就消失了。 :/我有预感是什么问题。我的表没有使用唯一列作为 id,而是使用自动生成的键。因此我不能使用EntityManager.find(Object),我不得不在唯一字段上编写查询。而且我认为在成功查询后,Hibernate(我的提供者)会增加查询实体的版本。我想不出别的了。 -
这就是程序员的生活!不过,我想说的是,当您发布一个简化的示例时,值得检查它是否确实重现了问题 - 因为如果没有,您已经朝着解决方案迈出了一大步。当然,根据您的示例工作的其他任何人都无法帮助您!
-
是的,你是对的,但我简直不敢相信执行查询会增加版本字段......也许不是。 :) 我不肯定。有时间我会检查它并更新我的问题。
标签: java database jpa persistence jpa-2.0