繁体   English   中英

Hibernate合并丢失数据

[英]Hibernate merge loses data

我遇到了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.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相关的字段。

无论如何,删除了不成功的级联,这一切都很好:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM