【发布时间】:2013-10-27 19:56:59
【问题描述】:
我的问题是我无法保存我的实体,因为它包含另一个实体,该实体由一个键映射,该键也是该表主键的一部分。该表如下所示:
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:
添加了一个 embeddedId 而不是 id_A 和 id_B:
@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) 之前没有em.persist(c.getId().b);,我仍然会得到瞬态对象异常。坚持这一点,虽然它很丑。
@Trein:它不是双向的。实体B代码:
@Entity
public class EntityB implements Serializable {
public long id;
public String text;
}
【问题讨论】: