【发布时间】:2017-06-13 17:52:03
【问题描述】:
我正在使用休眠来处理数据库事务。
我有 2 个实体:
SegmentFileEntity
SegmentFileMappingEntity
SegmentFileEntity 可以有一个或多个 SegmentFileMappingEntity。连接键是 SEGMENT_FILE_ID 是主键
SegmentFileEntity 的关联表结构:
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
)
以及该表的约束细节:
[![在此处输入图片描述][1]][1]
SegmentFileMappingEntity 的关联表结构:
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,那很好。但是如果我使用超过 1 个 SegmentFileMappingEntity ,在保存 SegmentFileEntity 时,我会看到错误:
org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session. Any insight?
这是我的 java-hibernate 实体:
**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;
}
}
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;
}
}
【问题讨论】:
标签: hibernate join hibernate-mapping