gpt4 book ai didi

java - Hibernate合并丢失数据

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:37:45 25 4
gpt4 key购买 nike

我在使用 Hibernate 和合并时遇到了一个奇怪的问题。

有问题的类的结构是这样的:

Project --> CaseWorkerA --|> CaseWorker --|> User

基本上我有一个 Project 类,它包含对 CaseWorkerA 的引用,它是 CaseWorker 的子类,也是 User 的子类。

在代码中:

public class Project {
[...]
private CaseWorkerA caseWorkerA;

@ManyToOne(fetch = FetchType.EAGER)
@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.PERSIST,
org.hibernate.annotations.CascadeType.REFRESH, org.hibernate.annotations.CascadeType.MERGE })
@JoinColumn(name = "CaseWorker_A")
public CaseWorkerA getCaseWorkerA() {
return caseWorkerA;
}
}

然后我们有用户层次结构:

public class User {
[...]
}

public class CaseWorker extends User {
private CaseWorkerStatus status;

@Enumerated(EnumType.STRING)
public CaseWorkerStatus getStatus() {
return status;
}
[...]
}

public class CaseWorkerA extends CaseWorker {
[...]
}

然后,Dao 类中有一个方法,用于存储项目:

public class ProjectDao {
[...]
public Project saveUpdateProject(final Project project) {
if (project.getId() == null) {
getSession(false).save(project);
} else {
project = (Project) getSession(false).merge(project);
}
getHibernateTemplate().flush();
return project;
}
}

现在,问题如下:

Dao 方法接收数据库中存在的项目。该项目连接到 CaseWorkerA,其状态为 CaseWorkerStatus.ACTIVE(在数据库和传入对象中)。但合并后,caseworker 的状态变为空。

我真的不明白这是怎么可能的,因为数据库中的值与要存储的对象中的值相同,我希望它在合并后保持不变。

(数据库中没有该字段的触发器..)

(我将尝试更改 dao 方法以改为使用 saveOrUpdate,但即使这可以解决问题,我仍然非常想知道最初是什么原因造成的)。

更新:

所以我摆弄了调试器,发现了以下内容:当我为有问题的 CaseWorker 查询 session 时,它出现了它的状态字段集(实际上,返回的对象正是连接到项目)。

先执行 saveOrUpdate,然后再执行 get,生成一个设置了状态字段的 CaseWorker。所以好像是merge方法的问题..

最佳答案

设法弄清楚了,原来还有第二条路径从项目到用户(lastChangedBy 之类的东西),有人出于某种奇怪的原因决定放置级联。因此,当最后更改项目的人是 CaseWorker 时,lastChangedBy 将其作为用户引用,该用户对状态一无所知,因此将其存储为 null。

代码:

public class Project {
private User changedBy;

@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.PERSIST,
org.hibernate.annotations.CascadeType.REFRESH, org.hibernate.annotations.CascadeType.MERGE })
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "changed_by")
public User getChangedBy() {
return this.changedBy;
}
[...]
}

设置为 changedBy 的用户是这样从数据库中检索的:

public class UserDao {
public User getUser(final String userName) {
return (User) getSession(false).createQuery("from User u where u.loginName = :username").setParameter("username", userName).uniqueResult();
}
}

显然,即使最终检索到的用户是 CaseWorker,也不会检索到属于 CaseWorker 的字段。

无论如何,删除了不必要的级联,一切都很好:)

关于java - Hibernate合并丢失数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12216138/

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