我在我的应用程序中使用JPA / Hibernate和Spring事务管理。
有一个InspectionEntity与InspectionDetailEntity有一对多的关系。
两个实体的PK都是由数据库中的插入触发器创建的。我尝试保存时的PK值是默认的0值。
我通过调用addInspectionDetail()将InspectionDetailEntity添加到InspectionEntity,然后保存InspectionEntity - entityManager.persist(inspection);
我期望的是检查与所有InspectionDetail一起保存。
但这导致了一个
org.hibernate.NonUniqueObjectException:具有相同标识符值的其他对象已与会话关联:[com.xyz.entity.InspectionDetailEntity#0]。
我还尝试将Set直接设置为InspectionEntity(不使用addInspectionDetail())。这也会导致相同的错误。任何帮助都将受到高度赞赏。
@Entity
@Table(name = "tb_inspection")
public class InspectionEntity {
@Id
@Column(name = "inspection_id")
private Integer inspectionId;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "inspectionDetailId", cascade = CascadeType.ALL)
@JoinColumn(name = "inspection_id", insertable = true, updatable = true)
private Set<InspectionDetailEntity> inspectionDetails;
/**
* Adds a inspectionDetailEntity to the set of inspectionDetails
* @param inspectionDetailEntity
*/
public void addInspectionDetail(InspectionDetailEntity inspectionDetailEntity) {
if(inspectionDetails == null)
inspectionDetails = new HashSet<InspectionDetailEntity>();
inspectionDetailEntity.setInspection(this);
inspectionDetails.add(inspectionDetailEntity);
}
//setter and getters
}
@Entity
@Table(name = "tb_inspection_dtl")
public class InspectionDetailEntity {
@Id
@Column(name = "inspection_dtl_id")
private Integer inspectionDetailId;
@Column(name = "inspection_id")
private Integer inspectionId;
@ManyToOne
@JoinColumn(name="inspection_id", insertable = false, updatable = false)
private InspectionEntity inspection;
//setters and getters
}
答案 0 :(得分:2)
保存前不要将id设置为0。保留为null。如果设置了值,Hibernate将假定该对象已经在数据库中并尝试更新它。
你可能最终得到了具有相同id(0)的多个对象。
更新
正如我想的那样,你可能被迫将id设置为某个值,因为你没有id生成器而Hibernate希望你为id提供值。但是,Hibernate中没有任何内容可以在插入后更新对象上的id。因此,您最终会在会话中使用id为0的多个对象。
我不确定这种情况会有什么好处。您很可能需要编写自定义ID生成器。但是,例如,在序列的情况下,它需要额外调用数据库。可能你应该考虑除了触发器之外的id赋值吗?
答案 1 :(得分:0)
尝试删除
inspectionDetailEntity.setInspection(this);
或
inspectionDetails.add(inspectionDetailEntity);
我认为你不需要两者。
您的孩子和父母之间的单向关系可能值得考虑