gpt4 book ai didi

java - Hibernate 持久对象行为

转载 作者:行者123 更新时间:2023-12-01 16:36:47 25 4
gpt4 key购买 nike

我试图了解 Hibernate 中对象的不同状态。我尝试了以下操作,但找不到对所显示行为的解释。有人可以帮忙吗?

这就是我想要做的:在 Employee 表中插入一条新记录(empId 是主键)。在同一事务中,更新新添加的记录(使用查询,修改 empName)。然后,当我检查持久对象的 empName 属性时,它继续显示旧的 empName 值。作为一个持久对象,我希望它能够反射(reflect)数据库中所做的更改。我不明白为什么没有。 (我的 hibernate 配置文件将所有内容设置为默认值,除了“hibernate.hbm2ddl.auto”属性设置为更新)但是,在执行更新后,当我使用 getEmpName 返回的值(显示为 sysout 的旧 empName 值)设置持久对象的 empName 时,表中的最终数据显示新的 empName 值(即我使用更新的值) hql)。请引用代码:

Transaction tx = session.getTransaction();
tx.begin();

Employee e1 = new Employee();
e1.setEmpId(1);
e1.setEmpName("Jack");
e1.setEmpAge(25);
session.save(e1);
System.out.println("before: "+e1.getEmpName()); //prints Jack
session.createQuery("update Employee set empName = \'Jack_new\' where id=1").executeUpdate();
System.out.println("after: "+e1.getEmpName()); //prints Jack
e1.setEmpName(e1.getEmpName()); //should update database
tx.commit(); //sets empName value to Jack_new, as seen in table
System.out.println("last: "+e1.getEmpName()); //prints Jack

最佳答案

来自the hibernate documentation :

Manipulating data directly in the database (using the SQL Data Manipulation Language (DML) the statements: INSERT, UPDATE, DELETE) will not affect in-memory state.

当您使用以下直接 DML 进行更新时,

session.createQuery("update Employee set empName = \'Jack_new\' where id=1").executeUpdate();

它将绕过 Hibernate 持久化上下文(以及所有缓存)。因此,虽然数据库中的empName实际上更新为Jack_new,但其在持久化上下文中的实例仍然保留旧值。

您可以使用 session.refresh(e1); 从底层数据库重新读取 e1 的值,以便 e1.empName 将刷新为 Jack_new

通常情况下,我们不会手动编写 UPDATE 语句来执行更新。只需将更新后的值设置为持久化实例的属性即可。在刷新过程中,hibernate会自动进行脏检查,生成并发出相应的更新SQL来更新那些脏实例。

<小时/>

(回复评论):

However, just before doing tx.commit() I am setting e1.empName to old value (that is value returned by e1.getEmpName()).Still the final value seen in the database is the new value.?

/**e1 become persisted after save()**/
session.save(e1);

/**e1.empName is updated to new value in the DB , but as the direct DML
will not affect in-memory state , e1.empName in the java side
still keeps the old value***/
session.createQuery("update Employee set empName = \'Jack_new\' where id=1").executeUpdate();

/** As you only set `e1.empName` to its original value , the values of `e1` do
not have any changes. Thus , during the flushing (which occurs at the moment
before `commit()`) , hibernate will consider that `e1` is not dirty and
hence no update SQL will be generated and issued to update e1 .
***/
e1.setEmpName(e1.getEmpName());

因此,结果是 Jack_new 保存在数据库中。

关于java - Hibernate 持久对象行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8189623/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com