java – Hibernate合并丢失数据
我遇到了Hibernate和合并的奇怪问题. 有问题的类的结构如下: Project --> CaseWorkerA --|> CaseWorker --|> User 所以基本上我有一个Project类,它包含对CaseWorkerA的引用,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; } } 然后我们有User-hierarchy: 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(在数据库和incomming对象中).但在合并之后,案件工作者的状态变为空. 我真的不明白这是怎么可能的,因为数据库中的值是相同的,就像要存储的对象一样,我希望它在合并后保持不变. (此字段的数据库中没有触发器..) (我将尝试更改dao-method以使用saveOrUpdate,但即使这将解决问题,我仍然非常想知道是什么原因造成的). 更新: 所以我摆弄了调试器,发现了以下内容:当我查询有问题的CaseWorker的会话时,它出现了它的状态字段集(实际上,返回的对象正是连接到Project的对象). 执行saveOrUpdate,然后执行get,导致CaseWorker设置了status-field.所以它似乎是合并方法的一个问题.. 解决方法管理好弄明白,事实证明,从项目到用户有一条第二条路径(lastChangedBy类似的东西),有人因某种奇怪的原因决定放入级联.因此,当最后一次更改项目的人是CaseWorker时,lastChangedBy将其引用为User,它不了解状态,因此存储为null.码: public class Project { private User changedBy; @Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE,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相关的字段. 无论如何,删除了不成功的级联,这一切都很好:) (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |