【发布时间】:2016-03-17 11:05:03
【问题描述】:
我有一个表,我试图理解 session.merge 背后的逻辑,但我认为它在某种程度上是无用的,我会尝试用一些代码来解释更多。
public static void main(String[] args)
{
final Merge clazz = new Merge();
Ragonvalia ragonvalia = clazz.load();//LOADED FROM DATABASE...
System.out.println("ORIGINAL: "+ragonvalia);
//Prints c02=1953
clazz.session.evict(ragonvalia);//WE EVICT HERE FOR FORCE MERGE RELOAD FROM DB
//HERE I MAKE SOME MODIFICATIONS TO THE RECORD IN THE DB DIRECTLY.....
try{Thread.sleep(20000);}catch(final Exception e){e.printStackTrace();}
//now c02=2000
final Ragonvalia merge = ragonvalia = (Ragonvalia)clazz.session.merge(ragonvalia);//MERGE IN FACT THE SELECT IS THROWN
System.out.println("MERGING");
System.out.println("merge: "+merge);
System.out.println("ragonvalia: "+ragonvalia);
System.out.println(merge.toString().equals(ragonvalia.toString()));//PRINT EQUALS
ragonvalia.setC01("PUEBLO LINDO");//I MODIFIY THE C01 FIELD
System.out.println(ragonvalia);
final Transaction tx = clazz.session.beginTransaction();
clazz.session.update(merge);//WE UPDATE
tx.commit();
//In this point i can see the c02 was reset again to 1953
clazz.shutDown();
}
是的,我知道合并用于分离对象和所有这些东西,但选择背后的真正原因是我只是想到了一些事情。
- 如果当我从第一次检索记录时,字段 c02=1953 后者更改为 c02=2000 我只是在进行合并时他们会保留新字段已更改的 c02=2000,如果我没有在我的会话中修改字段,他们将替换从 1953 年到 2000 年的 c02,以便在保留 1953 年并将字段更新为 1953 年和 1953 年替换数据库中的 2000 年时不会伤害任何人的工作当然是工作从另一个人那里丢失了。
我在互联网上阅读了一些内容,并且看到了类似的内容基本上,如果您没有版本或时间戳字段,Hibernate 必须在更新之前检查现有记录,以便不会发生并发修改。您不希望在您阅读后被其他人修改的记录更新。上面的链接中概述了几种解决方案。但是,如果可以在每个表上添加一个版本字段,它会让生活变得更加轻松。听起来不错,但是在更新它之前不会发生并发修改这不会发生 Hibernate 只是更新字段即使它们在当前数据库记录中不一样,我也在我的课堂上。
Hibernate 必须在更新之前检查现有记录检查 hibernate 检查什么?
事实上,我没有在我的模型中使用任何版本,但似乎合并仅用于检查数据库中是否存在记录。
我知道这个问题有点简单或重复,但我只是看不出触发选择的逻辑或好处。
简历
合并后 Hibernate 正在更新所有属性,即使是那些未修改的我也不知道为什么会这样1 次或手动修改我认为合并是无用的。
update
ragonvalia
set
.....
.....
.....
c01=?,
c02=?,HERE IS 1953 EVEN WHEN THE MERGE WAS FIRED THE VALUE IN THE DB WAS 2000
c03=?
where
ID=?
【问题讨论】:
标签: java mysql hibernate select merge