2012-04-25 26 views
0

私のエンティティは以下のとおりです。 deiveID あるデバイスのIDが JPA主キー違反

私のテストをRIDされるのLibのIDと多対多の関係を持っていますコードは次のとおりです。 私はその2つの新しいデバイスエンティティを永続化するために同じEntityManagerを使用している場合、それはOKになります。 二つの新しいデバイスの実体は、問題がある同じ新しいlibentityを設定する

をしたいです。 しかし、2つの異なるentitymanagerインスタンスを使用してそれらを永続化すると、エラー "プライマリキー違反"が出てきます。エンティティ・マネージャーは、初めて初めて持続された2回目の資格を維持しようとしていると思います。

-------------- deviceinfoエンティティ------------------------------ ------------------

@Entity 
@Table(name="deviceInfo") 
public class DeviceInfoEntity extends BaseEntity implements Serializable{ 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
private long deviceId; 
.... 
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY) 
@JoinTable(name = "device_lib", joinColumns = @JoinColumn(name = "deviceInfo_id", 
    referencedColumnName="deviceId"), 
    inverseJoinColumns = @JoinColumn(name = "lib_id", referencedColumnName="rId")) 
private List<LibEntity> resourceList = null; 
...... 
} 

------------------------- libエンティティ---------------------------------------------

@Entity 
    @Table(name="lib") 
    public class LibEntity extends BaseEntity implements Serializable{ 
      @Id 
     @GeneratedValue(strategy = GenerationType.AUTO) 
     private long rId; 

      @ManyToMany(mappedBy = "resourceList", cascade=CascadeType.ALL, 
        fetch=FetchType.LAZY, targetEntity=DeviceInfoEntity.class) 
     private List<DeviceInfoEntity> deviceInfolist = null; 

      ..... 
    } 

私のテストコードは次のとおりです。

EntityManagerFactory emFactory = Persistence.createEntityManagerFactory("testPU"); 
      EntityManager em = emFactory.createEntityManager(); 


    LibEntity libEntity = new LibEntity(); 


    DeviceInfoEntity dEntity = new DeviceInfoEntity(); 
    dEntity.setName("dadadada"); 
    dEntity.setLibEntity(libEntity); 


    DeviceInfoEntity dEntity2 = new DeviceInfoEntity(); 
    dEntity2.setName("dadadadadddddd"); 
    dEntity2.setLibEntity(libEntity); 


    em.getTransaction().begin(); 
    em.persist(dEntity); 
    em.getTransaction().commit(); 

    em.close(); 

    EntityManager em2 = emFactory.createEntityManager(); 
    em2.getTransaction().begin(); 
    em2.persist(dEntity2); 
    em2.getTransaction().commit(); 

それはエラーになります。

Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.LIB(RID)"; SQL statement: 
INSERT INTO lib (RID) VALUES (?) [23505-165] 

ただし、同じEntityManagerを使用してもエラーは発生しません。理由は何ですか?それはcascade=CascadeType.ALLによって引き起こされますか?

+0

[JPAカスケードの永続性と分離されたエンティティへの参照は、PersistentObjectExceptionをスローします。なぜですか?](http://stackoverflow.com/questions/4294671/jpa-cascade-persist-and-references-to-detached-entities-throws-persistentobjecte) – axtavt

答えて

2

デタッチされたオブジェクトを管理対象オブジェクトに割り当てて、永続コンテキストを破損しています。管理対象オブジェクトは、他の管理対象オブジェクトのみを参照する必要があります。

dEntity2の場合は、libEntityのfind()、getReference()またはmerge()の結果をlibEntityに設定する必要があります。

すなわち

dEntity2.setLibEntity(em2.find(libEntity.getClass(), libEntity.getId()); 

あなたはおそらくもマージ呼び出すことができます()の代わりに存続の()、それは分離オブジェクトを解決する必要があります。

+0

あなたの助けに感謝〜 – Xiwen

関連する問題