有人可以提供一个演示如何实现简单“更新”方法的简单示例吗?这个没有更新
@Override
public void update(final BS bs) {
BS fullBs = em.find(BS.class, bs.getId());
BS merged = this.em.merge(fullBs);
this.em.flush();
}
由于
ER
答案 0 :(得分:2)
有人可以提供一个演示如何实现简单“更新”方法的简单示例吗?这个没有更新(...)
嗯,这实际上取决于您想要更新的实体的状态(托管与分离),但您的代码肯定是无用的。他们分析它:
1. public void update(final BS bs) {
2. BS fullBs = em.find(BS.class, bs.getId());
3. BS merged = this.em.merge(fullBs);
4. this.em.flush();
5. }
bs
实体的状态不清楚。总之... Id
将托管实体加载到fullBs
,然后...... 不要更改任何内容。 merge
一个完全没有必要的已管理实体(JPA为托管实体提供automatic state detection。)flush
变化......不存在:)因此,正如您进行实验一样,您的方法目前没有做任何事情。
现在回到问题:
flush
时间保持更改merge
(并返回合并的实例)。答案 1 :(得分:1)
使用脏检查而不是显式更新调用来实现hibernate中的更新。例如,在上面的方法中,如果您find()
您的BS实体然后修改属性然后调用flush()
,您将看到正在生成SQL更新。没有修改flush()
将决定无所事事。
实施例
@Override
public void update(final BS bs) {
BS fullBs = em.find(BS.class, bs.getId());
fullBs.setMyProperty("hello");
this.em.flush();
}
执行find()
实体由JPA提供程序加载(在本例中为hibernate),hibernate将为您提供实体,并在加载时保留实体状态的内部记录PLUS它持有对它返回的实体的引用。
然后当调用flush()
时,hibernate dirty会检查其缓存中的每个实体(称为第一级缓存或会话缓存)。脏检查包括检查使用内部状态记录获得的实体的每个属性。如果存在任何差异,则实体为“脏”,并且将生成SQL更新。
请注意,flush()
不是事务提交。它只是说,“请保持会话中对数据库所做的任何更改”,这将涉及插入/更新/删除语句。
简单更新不需要merge()
。
此外,您通常不会明确地致电flush()
。让hibernate这样做通常会更好。 Hibernate将在需要时刷新会话,通常是在事务提交时,因此提交将为您执行刷新。