我有两种方法在Hibernate中的刷新方面表现出不同的行为。
第一个是:
@Transactional
public void firstMthod(int id, int status) {
Person entity = session.get(Person.class, id);
entity .setStatus(personStatus.registered);
session.merge(entity);
updatePersonAge(id,18);
}
updatePersonAge
方法位于另一个类中,此方法的SQL输出如下所示:
select personel0_.ID as ID1_119_0_,
personel0_.status as status2_119_0_,
personel0_.age as age3_119_0_,
personel0_.CreatedBy as CreatedBy4_119_0_,
personel0_.UpdatedBy as UpdatedBy5_119_0_,
personel0_.CreatedDate as CreatedDate6_119_0_,
personel0_.UpdatedDate as UpdatedDate7_119_0_,
personel0_.Ip as Ip8_119_0_
from tbl_personel personel0_
where personel0_.ID = ?
update tbl_person set status = ? where ID = ?
update tbl_person set age = ? where ID = ?
对于第二个用例,我们有以下方法:
@Override
@Transactional
public void secondMethod(int id,int courseId, int status) {
Course courseEntity=session.get(Course .class, courseId);
courseEntity.setCreatedDate(new Date());
session.merge(courseEntity);
updatePersonAge(id,18);
}
updatePersonAge
方法为其生成以下SQL输出:
select course0_.ID as ID1_120_0_,
course0_.CreatedBy as CreatedBy7_120_0_,
course0_.UpdatedBy as UpdatedBy8_120_0_,
course0_.CreatedDate as CreatedDate9_120_0_,
course0_.UpdatedDate as UpdatedDate10_120_0_,
course0_.Ip as Ip11_120_0_
from tbl_course course0_
where course0_.ID = ?
update tbl_course set created_date = ? where ID = ?
update tbl_person set age = ? where ID = ?
updatePersoneAge
方法是:
public int updatePersonAge(int id,int age){
Query query = session.createQuery("update " + domainClass.getName() + " e set e.age= :age ");
query.setParameter("age ", age);
return query.executeUpdate();
}
根据我的预期,第二种方法的输出应该与第一种方法的输出相同。为什么差异呢?这真令人困惑。
答案 0 :(得分:2)
首先,在已经附加到当前正在运行的merge
的实体上调用Session
是没有意义的。 Merge
旨在使用when you want to attach a detached entity。
其次,正如我在this article中所解释的那样,如果要运行的查询与AUTO
中的实体重叠,则Hibernate ActionQueue
flush仅触发刷新。
在第一个示例中,因为您修改了Person
,并且查询是针对Person
运行的,所以触发刷新是有意义的,否则SQL查询可能会返回过时的结果。< / p>
在第二种情况下,您修改了Course
实体,但又要从Person
中进行选择。所以,没有必要触发冲洗。
您可以使用Query.addSyncronizedEntityName
中的说明使用{
"name": "@my/my-chart",
...
"peerDependencies": {
"d3": "^4.0.0"
}
}
来控制此行为。
答案 1 :(得分:0)
除了明确地更新年龄之外,在updatePersonAge
方法中,在每个事务中,您还隐式地(通过获取实体并更改其中一个字段)更新被管实体的其他字段。
当您合并这些更改时,PErsistence Provider有义务在交易结束时清除这些更改。
这就是为什么当你改变状态时:
Person entity = session.get(Person.class, id);
entity .setStatus(personStatus.registered);
session.merge(entity);
Hibernate持续存在这种变化以及明确的年龄增长:
update tbl_person set status = ? where ID = ?
update tbl_person set age = ? where ID = ?
在第二种方法中,当您更改“课程”实体的字段时:
Course courseEntity=session.get(Course .class, courseId);
courseEntity.setCreatedDate(new Date());
session.merge(courseEntity);
该变化与明确的年龄更新一起持续:
update tbl_course set created_date = ? where ID = ?
update tbl_person set age = ? where ID = ?