Hibernate とマージで奇妙な問題が発生しています。
問題のクラスの構造は次のようになります。
Project --> CaseWorkerA --|> CaseWorker --|> User
したがって、基本的には、CaseWorkerA への参照を含む Project クラスがあります。これは、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 メソッドは、データベースに存在するプロジェクトを受け取ります。このプロジェクトは、ステータスが CaseWorkerStatus.ACTIVE である CaseWorkerA に接続されています (データベースと着信オブジェクトの両方で)。しかし、マージ後、ケースワーカーのステータスは null になります。
格納されるオブジェクトと同様に、値はデータベースでも同じであるため、マージ後も同じままであると予想されます。
(このフィールドのデータベースにはトリガーがありません..)
(代わりに saveOrUpdate を使用するように dao-method を変更しようとしていますが、これで問題が解決したとしても、そもそも何が原因なのか知りたいと思っています)。
アップデート:
そこで、デバッガーをいじってみたところ、次のことがわかりました。 問題の CaseWorker のセッションを照会したところ、ステータス フィールドが設定された状態で表示されました (実際、返されたオブジェクトは、プロジェクトに接続されていたものとまったく同じでした)。
saveOrUpdate を実行してから get を実行すると、ステータス フィールドが設定された CaseWorker が生成されました。ということで、マージ方法に問題がありそうです..