2017-01-04 7 views
0

난처한 상황에 빠진를 포함 복합 기본 키와 엔티티를 저장할 수 없습니다. 부모의 기본 키 유형은 java.util.UUID이며 하위 키의 기본 키는 부모의 UUID와 시퀀스 번호의 합성어입니다. java.lang.IllegalArgumentException가 :스프링 데이터 JPA는 : <p></p> 한 부모에 많은 하위 기관과 두 개의 실체, 부모와 자식, 가정 ... 완전히 난처한 상황에 빠진 외래 키

에 의해 발생 : 유형 [의 값을 변환 할 수 없습니다 닷컴 내가 childRepository.save(child)을 사용하여 새 아이, 나는 다음과 같은 예외가를 저장하려고하면

문제의 짧은이다 .package.entities.ParentEntity는 $$ _ jvst149_0] 필요한 타입은 [java.util.UUID] 속성 '부모'님의 PropertyEditor [org.springframework.beans.propertyeditors.UUIDEditor] 형 [COM의 부적절한 값을 반환. package.entities.ParentEntity _ $$ _ jvst149_0]

아래 내 수업을 살펴보십시오. 가장 좋은 나는 (비슷한 일 전에 일어난 DATAJPA-269 참조) 내가 제대로 JPA 사양에 따라하고, 따라서이 유형의 ID를 UUID 할 아마도 특정 Spring Data JPA의 버그 인 경우 내가 궁금하네요 말해 내가 사용하고

주 수 spring-boot-starter-data-jpa 1.4.1.RELEASE

Parent.java :

@Entity 
@Table(name = "parent") 
public class Parent implements Serializable { 

    @Id 
    @GeneratedValue(generator = "uuid") 
    @GenericGenerator(name = "uuid", strategy = "uuid2") 
    private UUID id; 

    //...other fields, getters + setters... 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 
     Parent that = (Parent) o; 
     return Objects.equals(id, that.id); 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hash(id); 
    } 
} 

Child.java

@Entity 
@Table(name = "child") 
@IdClass(ChildKey.class) 
public class Child implements Serializable { 

    @Id 
    @ManyToOne 
    @JoinColumn(name = "parent_id", referencedColumnName = "id", insertable = false, updatable = false) 
    private Parent parent; 
    @Id 
    private Integer seqNum; 

    //...other fields, getters + setters... 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 
     Child that = (Child) o; 
     return Objects.equals(parent, that.parent) && 
       Objects.equals(seqNum, that.seqNum); 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hash(parent, seqNum); 
    } 
} 

ChildKey 의 .class

public class ChildKey implements Serializable { 

    private UUID parent; 
    private Integer seqNum; 

    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 
     ChildKey that = (ChildKey) o; 
     return Objects.equals(parent, that.parent) && 
       Objects.equals(seqNum, that.seqNum); 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hash(parent, seqNum); 
    } 
} 

ParentRepository.java는 ChildRepository.java

@Repository 
public interface ChildRepository extends CrudRepository<Child, ChildKey> { 
} 

그리고

@Repository 
public interface ParentRepository extends JpaRepository<Parent, UUID> { 
} 

마지막으로, 코드는 내가 실행 :

@Transactional 
public void createChild(Parent parent) { 
    // needed to do this to get over "detached entity passed to persist" 
    parent = parentRepository.getOne(parent.getId()); 
    child = new Child(); 
    child.setParent(parent); 
    child.setSeqNum(1); 
    childRepository.save(child); 
} 

답변

0

을 대일에서 당신의 자녀 엔티티가 가진 관계 자신의 ID 및 상위 엔티티의 ID는 PK의 일부가 아닌 FK입니다. Example

+0

감사합니다. 답변을 주셔서 감사합니다.하지만 따라갈 것이라고 생각하지 않습니다. 내가 사용한 모든 RDBMS에서 외래 키로 구성된 자식의 기본 키에 문제가 없었습니다. 실제로 데이터베이스를 정규화하는 일반적인 방법입니다. – Jpnh

0

이 질문을 올린 지 몇 달 후 적절한 답을 찾지 못했습니다. 나는 불행하게도 @ManyToOne를 사용하지 않음으로써 문제를 해결했고 대신 UUID에 의해 부모를 참조 :

public class Child implements Serializable { 

    @Id 
    private UUID parentId; 
    @Id 
    private Integer seqNum; 

내가 외부 키의 무지 JPA를 떠나 단지 데이터베이스가 내가 참조 무결성을 위반해야 오류가 발생 할 수 있습니다.

public class ChildKey implements Serializable { 

    private Parent parent; // <-- Parent type instead of UUID 
    private Integer seqNum; 
    ... 

UPD :

0

당신은 당신의 ChildKey 클래스를 변경해야 내가 JPA 스펙을 참조하십시오. 그것을 잘못 이해했습니다. 하지만 제 경우에는 효과가 있습니다.

+0

흥미 롭습니다! 감사. 나는이 질문에 영감을 준 코드 기반에서 더 이상 일하지 않지만, 다음 번에 나는 이것을 시도하려고 노력한다. – Jpnh