オブジェクトのセットを永続化するためにHibernate3.6.10を使用しています。オブジェクトBには、オブジェクトAへの参照が含まれています。
@Entity
@Table(name = "OBJECT_A")
class ObjectA {
@Id
String id;
@Basic
String name;
}
@Entity
@Table(name = "OBJECT_B")
class ObjectB {
@Id
String id;
@ManyToOne(optional = false)
@Cascade({CascadeType.SAVE_UPDATE})
ObjectA objectA;
@Basic
String name;
}
最初にデータベースからのインスタンスをロードせずObjectB
に、persistedへの参照を使用しての新しいインスタンスを作成しようとしています。例えば:ObjectA
ObjectA
ObjectA objA = new ObjectA();
objA.id = 42; // same ID as persisted object, but not loaded from db
ObjectB objB = new ObjectB();
objB.objectA = objA;
objB.name = "The Answer";
session.save(objB);
session.save(objB)
ただし、失敗します。
org.hibernate.PropertyValueException: not-null property references a null or transient value: ObjectA.name
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:100)
明らかな解決策は、のインスタンスをidでロードすることですが、JSONから逆シリアル化することによってObjectA
のインスタンスが作成される場合を解決しようとしています。ObjectB
{
"ObjectB" : {
"objectA" : {"id" : 42},
"name" : "The Answer"
}
}
デシリアライズを実行するコードが、その構造を知らなくても、マップされたHibernateオブジェクトで機能できる一般的なケースでこれを解決したいと思います。このような逆シリアル化されたオブジェクトを考えると、リフレクションを使用して、マップされたすべてのフィールドを再帰的にウォークし、ObjectB
それらを永続的な同等のもので「再水和」することができます(おそらくを使用してSession.merge(…)
)が、これは解決された問題のようなにおいがするので、車輪の再発明はしたくありません。