【问题标题】:NonUniqueObjectException: A different object with the same identifier value was already associated with the sessionNonUniqueObjectException:具有相同标识符值的不同对象已与会话关联
【发布时间】:2015-05-06 14:38:50
【问题描述】:

我的 2 个 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;

在我的服务方法中 - 我在 Application bean 上执行查找 创建一个子应用程序 bean - 它具有对父应用程序的引用

然后 - 当我尝试在同一服务方法中更新 Parent 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);          
}

有什么想法可以解决这个问题吗?

【问题讨论】:

  • 你能发布你的更新代码吗?
  • 当然 - 刚刚更新了帖子
  • 您的@Ids 是如何分配的?我假设有某种@GeneratedValue...
  • ID 是自动递增的 - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", unique = true, nullable = false) private Integer id;两个豆子

标签: java hibernate hibernate-mapping


【解决方案1】:

我认为您的问题是由于您首先保存 androidApplicationBuildVO 孩子然后保存父母 applicationVO 您可以将孩子添加到父母并像这样保存父母:

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);
}

注意 ApplicationBuildVO 中的 equalshashcode 实现不要基于 id 添加未保存的元素 applicationBuilds 集时不会有意外。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-27
    • 2014-11-17
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 2014-04-16
    • 2013-08-30
    相关资源
    最近更新 更多