2017-01-27 4 views
0

私はデータベーストランザクションを処理するためにhibernateを使用しています。Hibernate:org.hibernate.NonUniqueObjectException

  • SegmentFileEntity

  • SegmentFileMappingEntity

SegmentFileEntity一つ以上のSegmentFileMappingEntityを持つことができます。

私は2つのエンティティを持っています。参加鍵はSegmentFileEntityため

関連するテーブル構造の主キーであるSEGMENT_FILE_IDです:

CREATE TABLE OAP_META_NEW.SEGMENT_FILE 
(
    SEGMENT_FILE_ID NUMBER(10)     DEFAULT OAP_META_NEW.SEGMENT_FILE_SEQ.NEXTVAL CONSTRAINT SEGMENTFILEID_NOTNULL NOT NULL, 
    SEGMENT_FILE_PATH VARCHAR2(500 BYTE)   CONSTRAINT SEGMENTFILEPATH_NOTNULL NOT NULL, 
    CLIENT_ID   NUMBER(10)     CONSTRAINT SEGMENTFILE_CLIENTID_NOTNULL NOT NULL, 
    INSERT_DATE  DATE      NOT NULL 
) 

そして、そのテーブルの上にcontraintsの詳細:

[[ここに画像の説明を入力します! ] [1]] [1]

SegmentFileMappingEnti TY:

CREATE TABLE OAP_META_NEW.SEGMENT_FILE_MAPPING 
(
    SEGMENT_FILE_MAPPING_ID NUMBER(10)   DEFAULT OAP_META_NEW.SEGMENT_FILE_MAPPING_SEQ.NEXTVAL CONSTRAINT SFM_SFMID_NOTNULL NOT NULL, 
    SEGMENT_FILE_ID   NUMBER(10) CONSTRAINT SFM_SEGMENTFILEID_NOTNULL NOT NULL, 
    ATTRIBUTE_POSITION  NUMBER(3) CONSTRAINT SFM_ATTRIBUTEPOSITION_NOTNULL NOT NULL, 
    ATTRIBUTE_NAME   VARCHAR2(100 BYTE) CONSTRAINT SFM_ATTRIBUTENAME_NOTNULL NOT NULL 
) 

そして、そのテーブル上の制約の詳細:

[2]ここで

は私のテストである[[ここに画像の説明を入力します] [2]!]これらのエンティティ上で実行しています:

public class SegmentFileTest 
    extends AbstractTest 
{ 
    private long attCatId; 
    private int attCatTypeId; 
    private long attDelimitedSavedId; 
    private long attFixedSavedId; 
    private long attDerivedSavedId; 

    SegmentFileService segmentFileService; 

    @BeforeClass 
    public void setUpAttributeCategoryTypeAttributeCategory() 
    { 
     segmentFileService = context.getBean(SegmentFileService.class); 


    } 

    @Test 
    public void saveSegmentFile() 
    { 

     //Create segment-file 
     SegmentFileEntity segmentFile = new SegmentFileEntity(); 
     segmentFile.setClientId(0); 
     segmentFile.setSegmentFilePath("/fakepath/"); 
     segmentFile.setInsertDate(new Date((new java.util.Date()).getTime())); 

     //Create segment-file-mapping 
     List<SegmentFileMappingEntity> fileMappings = new ArrayList<SegmentFileMappingEntity>(); 

     SegmentFileMappingEntity segmentFileMapping1 = new SegmentFileMappingEntity(); 
     segmentFileMapping1.setAttributeName("attr1"); 
     segmentFileMapping1.setAttributePosition(1); 

     SegmentFileMappingEntity segmentFileMapping2 = new SegmentFileMappingEntity(); 
     segmentFileMapping2.setAttributeName("attr2"); 
     segmentFileMapping2.setAttributePosition(2); 

     fileMappings.add(segmentFileMapping1); 
     fileMappings.add(segmentFileMapping2); 

     segmentFile.setSegmentFileAttributeMappings(fileMappings); 
     segmentFileService.saveSegmentFileEntity(segmentFile); 


    } 
} 

問題:

SegmentFileEntityを保存しているときに1つのSegmentFileMappingEntityしか使用しない場合は問題ありません。 SegmentFileEntityを節約しながら、私は、1以上SegmentFileMappingEntityを使用している場合しかし、私は、エラーを見ています:

SegmentFileEntity **:**

package com.company.online.segment.api.entities; 

import javax.persistence.*; 
import java.io.Serializable; 
import java.sql.Date; 
import java.util.Collection; 
import java.util.List; 




@Entity 
@Table(name = "SEGMENT_FILE", schema = "OAP_META_NEW") 
@SequenceGenerator(name = "segment_file_seq", sequenceName = "OAP_META_NEW.SEGMENT_FILE_SEQ") 
public class SegmentFileEntity implements Serializable 
{ 

    private int segmentFileId; 
    private String segmentFilePath; 
    private int clientId; 
    private Date insertDate; 

    @Id 
    @Column(name = "SEGMENT_FILE_ID" , nullable = false, unique = true, precision = 0) 
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "segment_file_seq") 
    @JoinColumn(name = "SEGMENT_FILE_ID", referencedColumnName = "SEGMENT_FILE_ID") 
    public int getSegmentFileId() 
    { 
     return segmentFileId; 
    } 

    public void setSegmentFileId(int segmentFileId) 
    { 
     this.segmentFileId = segmentFileId; 
    } 

    @Basic @Column(name = "SEGMENT_FILE_PATH") public String getSegmentFilePath() 
    { 
     return segmentFilePath; 
    } 

    public void setSegmentFilePath(String segmentFilePath) 
    { 
     this.segmentFilePath = segmentFilePath; 
    } 

    @Basic @Column(name = "CLIENT_ID") public int getClientId() 
    { 
     return clientId; 
    } 

    public void setClientId(int clientId) 
    { 
     this.clientId = clientId; 
    } 

    @Basic @Column(name = "INSERT_DATE") 
    public Date getInsertDate() 
    { 
     return insertDate; 
    } 

    public void setInsertDate(Date insertDate) 
    { 
     this.insertDate = insertDate; 
    } 

    @Override public boolean equals(Object o) 
    { 
     if (this == o) 
      return true; 
     if (o == null || getClass() != o.getClass()) 
      return false; 

     SegmentFileEntity that = (SegmentFileEntity) o; 

     if (segmentFileId != that.segmentFileId) 
      return false; 
     if (clientId != that.clientId) 
      return false; 
     if (segmentFilePath != null ? !segmentFilePath.equals(that.segmentFilePath) : that.segmentFilePath != null) 
      return false; 
     if (insertDate != null ? !insertDate.equals(that.insertDate) : that.insertDate != null) 
      return false; 

     return true; 
    } 

    @Override public int hashCode() 
    { 
     int result = segmentFileId; 
     result = 31 * result + (segmentFilePath != null ? segmentFilePath.hashCode() : 0); 
     result = 31 * result + clientId; 
     result = 31 * result + (insertDate != null ? insertDate.hashCode() : 0); 
     return result; 
    } 


    private List<SegmentFileMappingEntity> segmentFileAttributeMappings; 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER , orphanRemoval = true) 
    @JoinColumn(name = "SEGMENT_FILE_ID", referencedColumnName = "SEGMENT_FILE_ID", nullable = false) 
    public List<SegmentFileMappingEntity> getSegmentFileAttributeMappings() 
    { 
     return segmentFileAttributeMappings; 
    } 

    public void setSegmentFileAttributeMappings(List<SegmentFileMappingEntity> segmentFileAttributeMappings) 
    { 
     this.segmentFileAttributeMappings = segmentFileAttributeMappings; 
    } 
} 
ここ

org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session. Any insight? 

は私のjava-休止状態のエンティティがあります

SegmentFileMappingEntity:

package com.company.online.segment.api.entities; 

import javax.persistence.*; 
import java.io.Serializable; 


@Entity @Table(name = "SEGMENT_FILE_MAPPING", schema = "OAP_META_NEW") 
public class SegmentFileMappingEntity implements Serializable 
{ 

    private int segmentFileMappingId; 
    private int segmentFileId; 
    private int attributePosition; 
    private String attributeName; 

    @Id @Column(name = "SEGMENT_FILE_MAPPING_ID") public int getSegmentFileMappingId() 
    { 
     return segmentFileMappingId; 
    } 

    public void setSegmentFileMappingId(int segmentFileMappingId) 
    { 
     this.segmentFileMappingId = segmentFileMappingId; 
    } 

    @Basic 
    @Column(name = "SEGMENT_FILE_ID", nullable = false, precision = 0, updatable = false, insertable = false) 
    public int getSegmentFileId() 
    { 
     return segmentFileId; 
    } 

    public void setSegmentFileId(int segmentFileId) 
    { 
     this.segmentFileId = segmentFileId; 
    } 

    @Basic @Column(name = "ATTRIBUTE_POSITION") public int getAttributePosition() 
    { 
     return attributePosition; 
    } 

    public void setAttributePosition(int attributePosition) 
    { 
     this.attributePosition = attributePosition; 
    } 

    @Basic @Column(name = "ATTRIBUTE_NAME") public String getAttributeName() 
    { 
     return attributeName; 
    } 

    public void setAttributeName(String attributeName) 
    { 
     this.attributeName = attributeName; 
    } 

    @Override public boolean equals(Object o) 
    { 
     if (this == o) 
      return true; 
     if (o == null || getClass() != o.getClass()) 
      return false; 

     SegmentFileMappingEntity that = (SegmentFileMappingEntity) o; 

     if (segmentFileMappingId != that.segmentFileMappingId) 
      return false; 
     if (segmentFileId != that.segmentFileId) 
      return false; 
     if (attributePosition != that.attributePosition) 
      return false; 
     if (attributeName != null ? !attributeName.equals(that.attributeName) : that.attributeName != null) 
      return false; 

     return true; 
    } 

    @Override public int hashCode() 
    { 
     int result = segmentFileMappingId; 
     result = 31 * result + segmentFileId; 
     result = 31 * result + attributePosition; 
     result = 31 * result + (attributeName != null ? attributeName.hashCode() : 0); 
     return result; 
    } 
} 

答えて

0

SegmentFileMappingEntityには、segmentFileMappingIdのアクセサーに@Idと注釈を付けたので、hibernateはそれをデータベース識別子として使用します。つまり、すべてのオブジェクト行に対して一意でなければなりません。

しかし、あなたは価値を提供しませんでした。

したがって、デフォルト値は0です。作成されたSegmentFileMappingEntityインスタンスはすべて、オブジェクトの作成時に識別子として0を取得します。あなたの現在のセッション/永続性の文脈の中で、これは1つのエントリーのために "偶然にもOK"です。

解決策は、アプリケーションレベルのすべてのインスタンスに対して一意の値を生成するか、またはハイバーネーションで生成することです(SegmentFileEntityアクセサのデータベースシーケンスですでに行ったように)getSegmentFileId())。

詳細については、hereを参照してください。