2017-10-12 98 views
0

我试图在我的hibernate 5项目中使用envers以监视数据库中的更改。但我正面临着与@Embeddable元素有关的问题。Envers&“具有相同标识符值的不同对象已与会话相关联”

当我保存包含@Embeddable元素的实体,我得到以下错误:Caused by: javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [entity_embedded_entity_AUD#{SETORDINAL=1, REV=com.bl.dpi.appl[email protected]7a814310, AuditedEntityWithEmedded_id=d9b141ce-5ac1-4209-969e-8229845dd606, REVTYPE=ADD}]

我试过多的东西来解决这个(计算器FTW!),但没有更迭

这里是我的班

EmbeddableEntity.class

@Embeddable 
@AllArgsConstructor 
@NoArgsConstructor 
@ToString 
@Getter 
@Setter 
public class EmbeddableEntity { 
    @NotNull 
    @Column(name = "text") 
    private String text; 

    @NotNull 
    @Column(name = "value") 
    private Float value; 
} 

AuditedEntityWithEmedded.class

@Entity 
@AllArgsConstructor 
@ToString 
@Getter 
@Setter 
@EqualsAndHashCode 
@Table(name = "AuditedEntityWithEmedded") 
@Audited 
public class AuditedEntityWithEmedded { 

    public AuditedEntityWithEmedded() { 
     this(UUID.randomUUID().toString()); 
    } 

    public AuditedEntityWithEmedded(String id) { 
     this.id = id; 
    } 

    @Id 
    @NotNull 
    private final String id; 

    @Column 
    private String nom; 

    @ElementCollection(targetClass = EmbeddableEntity.class) 
    @CollectionTable(name = "entity_embedded_entity", joinColumns = @JoinColumn(name = "AuditedEntityWithEmedded_id")) 
    private List<EmbeddableEntity> embeddedList; 
} 

而我的测试类:AuditedEntityWithEmeddedTest.class

public class AuditedEntityWithEmeddedTest extends AbstractAuditedTest<AuditedEntityWithEmedded, String> { 

    @Autowired 
    private JpaRepository<AuditedEntityWithEmedded, String> repo; 

    private static final String nom10 = "1.0"; 

    private static final String TEXT0 = "Text0"; 
    private static final String TEXT1 = "Text1"; 
    private static final Float VAL0 = 0f; 
    private static final Float VAL1 = 1f; 

    @Test 
    public void saveEntity() { 
     AuditedEntityWithEmedded auditedEntityWithEmedded = new AuditedEntityWithEmedded(); 
     auditedEntityWithEmedded.setNom(nom10); 
     auditedEntityWithEmedded.setEmbeddedList(createEmbeddableList()); 

     repo.save(auditedEntityWithEmedded); 
    } 

    private List<EmbeddableEntity> createEmbeddableList() { 
     ArrayList<EmbeddableEntity> list = new ArrayList<EmbeddableEntity>(); 

     list.add(new EmbeddableEntity(TEXT0, VAL0)); 
     list.add(new EmbeddableEntity(TEXT1, VAL1)); 

     return list; 
    } 
} 

当我运行测试类,我得到以下异常:

org.springframework.dao.DataIntegrityViolationException: A different object with the same identifier value was already associated with the session : [entity_embedded_entity_AUD#{SETORDINAL=1, REV=com.bl.dpi.appl[email protected]375084c9, AuditedEntityWithEmedded_id=d773bace-a59e-46ac-833a-53d8210f21bd, REVTYPE=ADD}]; nested exception is javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [entity_embedded_entity_AUD#{SETORDINAL=1, REV=com.bl.dpi.appl[email protected]375084c9, AuditedEntityWithEmedded_id=d773bace-a59e-46ac-833a-53d8210f21bd, REVTYPE=ADD}] 
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:410) 
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246) 
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:504) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) 
    at com.sun.proxy.$Proxy103.save(Unknown Source) 
    at com.bl.dpi.appli.example.hibernate.envers.embedded.AuditedEntityWithEmeddedTest.saveEntity(AuditedEntityWithEmeddedTest.java:38) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) 
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) 
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) 
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 
Caused by: javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [entity_embedded_entity_AUD#{SETORDINAL=1, REV=com.bl.dpi.appl[email protected]375084c9, AuditedEntityWithEmedded_id=d773bace-a59e-46ac-833a-53d8210f21bd, REVTYPE=ADD}] 
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:116) 
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155) 
    at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:56) 
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:71) 
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517) 
    ... 48 more 

是否有人有想法? (我已经测试并readed计算器上类似的帖子)

回答

0

最后,加入@OrderColumn似乎解决异常

public class AuditedEntityWithEmedded { 

    public AuditedEntityWithEmedded() { 
     this(UUID.randomUUID().toString()); 
    } 

    public AuditedEntityWithEmedded(String id) { 
     this.id = id; 
    } 

    @Id 
    @NotNull 
    private final String id; 

    @Column 
    private String nom; 


    @ElementCollection(targetClass = EmbeddableEntity.class, fetch = FetchType.EAGER) 
    @JoinTable(name = "entity_embedded_entity", joinColumns = @JoinColumn(name = "AuditedEntityWithEmedded_id")) 
    @OrderColumn // <--- HERE 
    private List<EmbeddableEntity> embeddedList; 
} 
+1

更改'List'到'Set',你不应该申请'@ OrderColumn'注解来解决这个问题。问题是,除非容器是'Set'类型,否则序数位置不会从我记得的位置被推入PK中。 – Naros

相关问题