NonUniqueObjectException:具有相同标识符值的不同对象已与会话相关联
NonUniqueObjectException: A different object with the same identifier value was already associated with the session
我的两个 bean 中有以下映射
父 Bean
@OneToMany(fetch = FetchType.LAZY, mappedBy = "application")
@Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE})
@JsonIgnore
private Set<ApplicationBuildVO> applicationBuilds = new HashSet<ApplicationBuildVO>(0);
童豆
@ManyToOne(fetch = FetchType.LAZY)
@Cascade({CascadeType.SAVE_UPDATE})
@JoinColumn(name = "APPLICATION_ID", nullable = false)
@JsonIgnore
private ApplicationVO application;
在我的服务方法中 - 我在应用程序 bean 上执行查找
创建一个子应用程序 bean - 它具有对父应用程序的引用
然后 - 当我尝试在同一服务方法中更新父 bean 上的值时,出现以下错误
Caused by: org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.domain.dao.ApplicationVO#1]
at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:617)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:301)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:244)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:109)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
我的服务代码(精简)如下
public boolean performBuild(Integer applicationId) {
ApplicationVO applicationVO = applicationServices.findAnyApplicationId(applicationId);
ApplicationBuildVO androidApplicationBuildVO = new ApplicationBuildVO();
androidApplicationBuildVO.setIsAndroid(true);
androidApplicationBuildVO.setIsSuccess(appBuildSuccessful);
androidApplicationBuildVO.setApplication(applicationVO);
androidApplicationBuildVO.setSoftwareVersion(androidSoftwareVersionVO);
androidApplicationBuildVO.setS3BucketName(mobileAppsBucketName);
androidApplicationBuildVO.setS3ArtifactKey(androidArtifact);
Integer applicationBuildId = applicationBuildServices.saveApplicationBuild(androidApplicationBuildVO);
applicationVO.setIsCurrentlyBeingBuilt(false);
boolean updateApplicationResult = applicationServices.updateApplication(applicationVO);
}
有什么办法可以解决这个问题吗?
我认为你的问题是因为你先保存 androidApplicationBuildVO
child 然后保存 parent applicationVO
你可以添加 child 到 parent 并像这样保存 parent:
boolean performBuild(Integer applicationId) {
ApplicationVO applicationVO = applicationServices.findAnyApplicationId(applicationId);
ApplicationBuildVO androidApplicationBuildVO = new ApplicationBuildVO();
androidApplicationBuildVO.setIsAndroid(true);
androidApplicationBuildVO.setIsSuccess(appBuildSuccessful);
androidApplicationBuildVO.setApplication(applicationVO);
androidApplicationBuildVO.setSoftwareVersion(androidSoftwareVersionVO);
androidApplicationBuildVO.setS3BucketName(mobileAppsBucketName);
androidApplicationBuildVO.setS3ArtifactKey(androidArtifact);
applicationVO.addBuild(androidApplicationBuildVO);
applicationVO.setIsCurrentlyBeingBuilt(false);
boolean updateApplicationResult = applicationServices.updateApplication(applicationVO);
}
如果 applicationVO
中不存在此方法,则应添加此方法
public void addBuild(ApplicationBuildVO buildVo) {
applicationBuilds.add(buildVo);
}
注意 equals
和 hashcode
ApplicationBuildVO 中的实现不要基于 id 添加未保存的元素时不会有意外 applicationBuilds
设置。
我的两个 bean 中有以下映射
父 Bean
@OneToMany(fetch = FetchType.LAZY, mappedBy = "application")
@Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE})
@JsonIgnore
private Set<ApplicationBuildVO> applicationBuilds = new HashSet<ApplicationBuildVO>(0);
童豆
@ManyToOne(fetch = FetchType.LAZY)
@Cascade({CascadeType.SAVE_UPDATE})
@JoinColumn(name = "APPLICATION_ID", nullable = false)
@JsonIgnore
private ApplicationVO application;
在我的服务方法中 - 我在应用程序 bean 上执行查找 创建一个子应用程序 bean - 它具有对父应用程序的引用
然后 - 当我尝试在同一服务方法中更新父 bean 上的值时,出现以下错误
Caused by: org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.domain.dao.ApplicationVO#1]
at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:617)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:301)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:244)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:109)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
我的服务代码(精简)如下
public boolean performBuild(Integer applicationId) {
ApplicationVO applicationVO = applicationServices.findAnyApplicationId(applicationId);
ApplicationBuildVO androidApplicationBuildVO = new ApplicationBuildVO();
androidApplicationBuildVO.setIsAndroid(true);
androidApplicationBuildVO.setIsSuccess(appBuildSuccessful);
androidApplicationBuildVO.setApplication(applicationVO);
androidApplicationBuildVO.setSoftwareVersion(androidSoftwareVersionVO);
androidApplicationBuildVO.setS3BucketName(mobileAppsBucketName);
androidApplicationBuildVO.setS3ArtifactKey(androidArtifact);
Integer applicationBuildId = applicationBuildServices.saveApplicationBuild(androidApplicationBuildVO);
applicationVO.setIsCurrentlyBeingBuilt(false);
boolean updateApplicationResult = applicationServices.updateApplication(applicationVO);
}
有什么办法可以解决这个问题吗?
我认为你的问题是因为你先保存 androidApplicationBuildVO
child 然后保存 parent applicationVO
你可以添加 child 到 parent 并像这样保存 parent:
boolean performBuild(Integer applicationId) {
ApplicationVO applicationVO = applicationServices.findAnyApplicationId(applicationId);
ApplicationBuildVO androidApplicationBuildVO = new ApplicationBuildVO();
androidApplicationBuildVO.setIsAndroid(true);
androidApplicationBuildVO.setIsSuccess(appBuildSuccessful);
androidApplicationBuildVO.setApplication(applicationVO);
androidApplicationBuildVO.setSoftwareVersion(androidSoftwareVersionVO);
androidApplicationBuildVO.setS3BucketName(mobileAppsBucketName);
androidApplicationBuildVO.setS3ArtifactKey(androidArtifact);
applicationVO.addBuild(androidApplicationBuildVO);
applicationVO.setIsCurrentlyBeingBuilt(false);
boolean updateApplicationResult = applicationServices.updateApplication(applicationVO);
}
如果 applicationVO
public void addBuild(ApplicationBuildVO buildVo) {
applicationBuilds.add(buildVo);
}
注意 equals
和 hashcode
ApplicationBuildVO 中的实现不要基于 id 添加未保存的元素时不会有意外 applicationBuilds
设置。