我有以下的Enitities:
@Entity
public class Parent {
@Id
@Column(name = "ID", nullable = false)
private Long id;
}
@Entity
public class Child {
@Id
@Column(name = "ID", nullable = false)
private Long id;
private Parent parent;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "PARENT_ID", referencedColumnName = "ID", updatable = false, insertable = false)
public Parent getParent() {
return parent;
}
}
现在,当我保存孩子时,我想将父母的ID保存到列" PARENT_ID"。
但是,当孩子被保存时,我不想保存或更新父母
因此我已将updatable = false, insertable = false
添加到@JoinColumn
问题是,这样我得到" org.hibernate.TransientPropertyValueException:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例"。
所以Hibernate告诉我在Child之前保存Parent。好吧,家长已经保存了,但是Hibernate并不知道,因为它是一个新的交易而我不想要
再次保存Parent(即updatable = false, insertable = false
的整点)。我也不想再次获取Parent(没有额外的选择,我只需要ID(我已经拥有)而不是整个对象)
我已经尝试使用@Transient注释getParent以防止持久化Parent,这很有效,但是当获取Child时,Parent不是。
(我用另一个我手动设置的属性保存了ID)
我有办法实现我想要的目标吗? (在我获取子项时获取Parent,在保存Child时保存ParentID,但不保存或更新Parent)
答案 0 :(得分:1)
问题似乎是你正在创建一个新的父级,尽管你想要的只是将一个新的孩子附加到现有的父级。不要这样做。由于父级已存在,请从EntityManager中获取它:
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "PARENT_ID")
public Parent getParent() {
return parent;
}
并保存具有现有父ID的新Child:
Parent existingParent = entityManager.getReference(Parent.class, parentId);
Child child = new Child();
child.setParent(existingParent);
entityManager.persist(child);
答案 1 :(得分:-1)
评论JB Nizet答案,我不得不使用不同的解决方案,但我认为你应该使用他的,如果可以的话。
我的解决方案如下:
- 从getParent()中删除@ManyToOne和@JoinColumn并使用@Transient注释它
- 添加另一个属性(Long parentId)
- 使用@Column(“PARENT_ID”)注释parentId
- 当从DB加载Child时,我得到parentId并加载Parent并通过其Setter方法将其添加到子项