我在休眠和合并时遇到了一个奇怪的问题。

有问题的类的结构如下:

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;
    }
}

现在,问题如下:

道方法接收数据库中存在的项目。该项目连接到状态为CaseWorkerStatus.ACTIVE的CaseWorkerA(在数据库和传入对象中)。但是合并之后,案例工作者的状态为空。

我真的不知道该怎么做,因为数据库中的值与要存储的对象中的值相同,所以我希望合并后该值保持不变。

(数据库中没有此字段的触发器。)

(我将尝试将dao-method更改为使用saveOrUpdate,但是即使这可以解决问题,我还是非常想知道是什么原因引起的)。

更新:

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

先执行saveOrUpdate,然后执行get,会导致CaseWorker的状态字段已设置。因此,合并方法似乎存在问题。

最佳答案

设法弄清楚了,结果发现有一条从项目到用户的第二条路径(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有关的字段。

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

07-24 14:09