2016-10-24 3 views
0

간단한 부모 하위 테이블을 통해 시나리오를 설명했습니다.복합 외래 키 JPA TypeMismatchException

내 복합 기본 키는 상위 테이블을 참조하는 복합 외래 키입니다. 나는 다음과 같이 나의 실체를 저장하는 봄의 데이터를 사용하고

@Entity 
@Table(name="parent") 
@NamedQuery(name="Parent.findAll", query="SELECT p FROM Parent p") 
public class Parent implements Serializable { 
private static final long serialVersionUID = 1L; 

@EmbeddedId 
private ParentPK id; 

@Column(length=10) 
private String parentcol; 

//bi-directional one-to-one association to Child 
@OneToOne(mappedBy="parent") 
private Child child; 

public Parent() { 
} 

/* getters and setters */ 

} 

@Embeddable 
public class ParentPK implements Serializable { 
//default serial version id, required for serializable classes. 
private static final long serialVersionUID = 1L; 

@Column(unique=true, nullable=false, length=10) 
private String code; 

@Column(unique=true, nullable=false) 
private int id; 

    /* getters and setters */ 

/** Overridden equals and hashcode **/ 
} 



@Entity 
@Table(name="child") 
@NamedQuery(name="Child.findAll", query="SELECT c FROM Child c") 
public class Child implements Serializable { 
private static final long serialVersionUID = 1L; 

@EmbeddedId 
private ChildPK id; 

@Column(nullable=false, length=10) 
private String childcol; 

//bi-directional one-to-one association to Parent 
@OneToOne 
@JoinColumns({ 
    @JoinColumn(name="code", referencedColumnName="code", nullable=false, insertable=false, updatable=false), 
    @JoinColumn(name="id", referencedColumnName="id", nullable=false, insertable=false, updatable=false) 
    }) 
private Parent parent; 

    /* getters and setters */ 

} 

@Embeddable 
public class ChildPK implements Serializable { 
//default serial version id, required for serializable classes. 
private static final long serialVersionUID = 1L; 

@Column(insertable=false, updatable=false, unique=true, nullable=false, length=10) 
private String code; 

@Column(insertable=false, updatable=false, unique=true, nullable=false) 
private int id; 

/* overridden equals and hashcode */ 

만들어

create table parent(
code varchar(10) not null, 
id int not null, 
parentcol varchar(10), 
primary key(code,id) 
); 

create table child(
code varchar(10) not null, 
id int not null, 
childcol varchar(10) not null, 
primary key(code, id), 
foreign key(code, id) references parent(code,id) 
); 

엔티티 (이 이클립스 JPA 플러그인을 통해). 부모 테이블은 코드가 "code"이고 Id가 1 인 레코드로 구성됩니다.

Child child = new Child(); 
ChildPK childPK = new ChildPK(); 
childPK.setCode("code"); 
childPK.setId(1); 
child.setId(childPK); 
child.setChildcol("child1"); 
childRepository.save(child); 

새 레코드를 삽입해야 할 때 첫 번째 실행에 성공합니다. 하지만 문제는 내가 자식 테이블 등의 ParentPk의 참조를 제공하기 위해 노력

child.setChildcol("child2"); 

가 나는 경우 오류

HHH000327: Error performing load command : org.hibernate.TypeMismatchException: Provided id of the wrong type for class com.xebia.eTechLog.entities.Parent. Expected: class com.xebia.eTechLog.entities.ParentPK, got class com.xebia.eTechLog.entities.ChildPK 

에 직면, 그것의가 말할 수 있도록 업데이트해야하는 두번째 실행에

@Entity 
@Table(name="child") 
@NamedQuery(name="Child.findAll", query="SELECT c FROM Child c") 
public class Child implements Serializable { 
private static final long serialVersionUID = 1L; 

@EmbeddedId 
private ParentPK id; 

@Column(nullable=false, length=10) 
private String childcol; 

//bi-directional one-to-one association to Parent 
@OneToOne 
@JoinColumns({ 
    @JoinColumn(name="code", referencedColumnName="code", nullable=false, insertable=false, updatable=false), 
    @JoinColumn(name="id", referencedColumnName="id", nullable=false, insertable=false, updatable=false) 
    }) 
private Parent parent; 

작동하지만 실제 시나리오 인 상위 클래스에 필드가 더 이상 존재하지 않을 수 있습니다.

답변

0

파생 된 ID를 사용해야합니다. 어떤 의미 당신은 부모에 대한 자녀의 참조 (A @MapsId 주석) 아동의 ID를 매핑하는 것을 표시해야합니다 :

@Entity 
public class Child implements Serializable { 
    @EmbeddedId 
    private ChildPK id; 

    @Column(nullable=false, length=10) 
    private String childcol; 

    @OneToOne 
    @MapsId // <<< NB 
    @JoinColumns({ 
     @JoinColumn(name="code", referencedColumnName="code"), 
     @JoinColumn(name="id", referencedColumnName="id") 
    }) 
    private Parent parent; 

    ... 
} 

파생 정체성은 섹션 2.4.1에서 JPA 2.1 스펙에서 설명합니다.

+0

감사합니다. Brian. 나는 전에 대답을 알아낼 수 있었고, 당신이 언급 한 것과 꽤 일치합니다. 부모 테이블에 매핑되는 복합 기본 키 부분에 @MapsId를 사용해야합니다. – bitscanbyte