2011-11-14 13 views
1

JPAアノテーションと抽象クラスを使用してエンティティ継承を設定しようとしています。JPA抽象クラスによるエンティティ継承 - ConstrainViolationException

私たちの目標は、プロバイダとマネージャを変更することなく、異なるエンティティ拡張、ポイントカットとオーバーライドを使用して、同じアプリケーションの変更を行うことができるように、DAOをベースオブジェクトと一緒に使用することです。

例: ベースアプリケーションスタックが会社を拡張するすべてのオブジェクトを永続化する抽象企業エンティティを使用DAOプロバイダを有する:

@Entity 
@Inheritance(strategy = InheritanceType.JOINED) 
public abstract class Company extends AbstractPersistable<Long> { 

    @Column(unique = true) 
    private String register_number;   

    // ... 
} 

@Component 
public class CompanyProvider extends JpaProvider<Company, Long> { 
// provides CRUD methods via an EntityManager 
} 

(参考JPAProviderセットアップ:)

public abstract class JpaProvider<T, ID extends Serializable> implements JpaRepository<T, ID>, JpaSpecificationExecutor<T>, QueryDslPredicateExecutor<T> { 

    @PersistenceContext 
    private EntityManager em; 

アプリケーションAは、独自の列を追加するが、DAOを変更することなくCompanyDefaultに会社を拡張します。アプリケーションBは同じことを行う必要があります。

@Entity 
@Table(name = "company") 
public class CompanyDefault extends Company {  

    private String name; 

} 

persistence.xmlのは、各アプリケーション(またはunittestの)のために一度に存在するので、これは実際のエンティティ定義する必要があります:私は会社を作成するために、今すぐ

<persistence ... > 
    <persistence-unit name="persistanceUnit" transaction-type="RESOURCE_LOCAL"> 

    <class>path.to.CompanyDefault</class> 

    </persistence-unit> 
</persistence> 

@Inject 
private CompanyProvider companyProvider;  

@Test 
public void testAbstractCompany() { 
    Company company = new CompanyDefault("123"); 
    ((CompanyDefault)company).setName("test"); 

    companyProvider.save(company); 
} 

不満足な結果は、私が主キーの重複したエントリを持っている私に言っConstraintVioloationExceptionである:以下

javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not insert: [...CompanyDefault] 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1215) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1148) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1154) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:678) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240) 
    at $Proxy37.persist(Unknown Source) 
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:328) 
    at ....JpaProvider.save(JpaProvider.java:287) 
    at ....JpaProvider$$FastClassByCGLIB$$2caf68f6.invoke(<generated>) 
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191) 
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:617) 
    at ....CompanyProvider$$EnhancerByCGLIB$$d3a45b31.save(<generated>) 
    at ....PersonManagerTest.testAbstractCompany(PersonManagerTest.java:111) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) 
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82) 
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    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:236) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 
Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [....CompanyDefault] 
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96) 
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2454) 
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2854) 
    at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71) 
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273) 
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:320) 
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203) 
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129) 
    at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:69) 
    at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:179) 
    at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135) 
    at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61) 
    at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:808) 
    at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:782) 
    at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:786) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:672) 
    ... 42 more 
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '8' for key 'PRIMARY' 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513) 
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:406) 
    at com.mysql.jdbc.Util.getInstance(Util.java:381) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1038) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3563) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3495) 
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959) 
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2113) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2693) 
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2102) 
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2395) 
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2313) 
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2298) 
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2437) 
    ... 56 more 

なぜ今は休止状態で同じエンティティを2回持続しようとしますか?

セットアップと注釈はどうなりますか?

私たちができることは何ですか?抽象クラスの拡張を使用してエンティティを保存しますか?

ありがとうございました!

編集:私は作成して、直接拡張オブジェクトを保存した場合

同じことが起こります:

@Test 
public void testAbstractCompany() {  
    CompanyDefault companyDefault = new CompanyDefault("123"); 
    companyProvider.save(companyDefault); 
} 

EDIT2 - 解決:

私のテキストの壁を気にしない、それを解決すでに..単純な間違いコピーを躊躇してGoogle検索結果:

明らかにInheritanceType.SINGLE_TABLEを使用しなければならない。私はできるだけ早くこれを閉じます。

+0

ありがとう@Pete ... edit2解決済みの問題=) – adelarsq

答えて

2

編集ごとに解決済み2:あなたを迷惑して申し訳ありません。

関連する問題