私の問題は、このテーブルの主キーの一部でもあるキーによってマップされた別のエンティティが含まれているため、エンティティを保存できないことです。テーブルは次のようになります。
table C:
+-----+------+
| id_A | id_B |
+-----+------+
..ここで、idA はテーブル A の主キーでEntityA
あり、idB はテーブル B の主キーですEntityB
。
したがって、基本的にはn対mの関係です。これは、テーブル C に使用しているエンティティです。
@Entity
public class EntityC {
private long idA;
private EntityB b;
@Id
@Column(name = "id_A")
public long getIdA() {
return idA;
}
@Id
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "id_B")
public EntityB getB() {
return b;
}
...setters are here...
}
id_A
はそのまま (id) にid_B
マッピングされますが、 はそのオブジェクト表現としてマッピングされることに注意してくださいEntityB
。これは私がそれでやりたいことです:
EntityC c = new EntityC();
c.setIdA(123);
c.setB(new EntityB());
em.persist(c);
tx.commit();
em.close();
EntityB
持続できる場合にのみ持続したいEntityC
。
tx.commit()
私はこの例外を受け取ります:org.hibernate.TransientObjectException: object references an unsaved transient instance
id_B
これは、主キーの一部が保存されていないために発生すると思われます。しかし、カスケードをすべてに設定したので、問題はありません!
なぜこれが機能しないのですか?
編集:
私がこれを行うとき:
em.persist(c.getB());
em.persist(c);
できます。しかし、Hibernate/JPA はそれを自動的に行うことはできませんか? それがカスケードの良いところだと思いました。
EDIT2:
id_A と id_B の代わりに embeddedId を追加しました:
@Embeddable
public class EntityCID implements Serializable {
public long idA;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "id_B", referencedColumnName = "id")
public EntryB b;
}
EntityC は次のようになります。
@Entity
public class EntityC implements Serializable {
private EntityCID id;
...
@EmbeddedId
public void getId() {
return id;
}
}
em.persist(c.getId().b);
しかし、以前にそうしなかった場合でも、一時的なオブジェクトの例外が発生しますem.persist(c)
。それは醜いですが、それに固執します。
@Trein: 双方向ではありません。エンティティ B コード:
@Entity
public class EntityB implements Serializable {
public long id;
public String text;
}