2017-01-24 5 views
1

Section.class에서 계단식 저장을 수행 할 수 있습니까? Section 개체를 만들고 id가없는 새 질문을 추가합니다.@IdClass 주석이있는 클래스의 삽입 가능한 객체

org.postgresql.util.PSQLException: ERROR: insert or update on table "question_to_section" violates foreign key constraint "fk_2br9f09ok965403a9rv5y2n10" Details: Key (question_id)=(0) is not present in table "question".

가 나는 또한 @Embedded 주석을 사용하려고했으나 실패 : 나는 그것을 저장하려고하면 나는 오류가 발생합니다.

제 클래스 :

@Table(name = "section") 
@Entity(name = "section") 
public class Section implements Serializable{ 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", unique = true, nullable = false) 
    @JsonProperty 
    long id;  

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "section") 
    Set<QuestionToSection> questions = new HashSet<QuestionToSection>(0); 
    ... 
} 

질문 섹션 클래스에

@Entity(name = "question_to_section") 
@Table(name = "question_to_section") 
@IdClass(QuestionSectionId.class) 
public class QuestionToSection implements Serializable { 

    @Id 
    long sectionId; 

    @Id 
    long questionId; 

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
    @JoinColumn(name = "sectionId", nullable = false, updatable = false, insertable = false, referencedColumnName = "id") 
    Section section; 

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
    @JoinColumn(name = "questionId", nullable = false, updatable = false, insertable = false, referencedColumnName = "id") 
    Question question; 
    ... 
} 

QuestionSectionId는

public class QuestionSectionId implements Serializable { 

    long questionId; 
    long sectionId; 

} 
+0

여기에 진정한 관계가 '질문'과 '섹션'사이의 다 대다 (many-to-many) 것 같습니다. 'QuestionToSection' 엔티티를 끼워 넣는 시점은 무었입니까? –

+0

당신의 문제가 updatable = false, insertable = false와 관계가 있습니다. MM을 캐스케이드 삽입을 허용하지 않기 위해서입니다. – cralfaro

답변

0

데이터베이스의 모든 테이블을 엔티티에 매핑 할 필요는 없습니다. 특히 순수 조인 테이블은 대개 엔터티로 매핑 된 이 아니며이 매핑됩니다. 예를 들어, 다 대다 관계를 들어

Question 엔티티에 주석을 대응 쌍방향 관계를 추정
@Table(name = "section") 
public class Section implements Serializable{ 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", unique = true, nullable = false) 
    @JsonProperty 
    long id;  

    // Note: probably do not want to cascade REMOVE operations 
    @ManyToMany(fetch = FetchType.LAZY, 
     cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH}, 
     mappedBy = "sections") 
    @JoinTable(
     name = "question_to_section" 
     joinColumns = 
      @JoinColumn(name="sectionId", referencedColumnName="ID"), 
     inverseJoinColumns= 
      @JoinColumn(name="questionId", referencedColumnName="ID") 
    ) 
    Set<Question> questions = new HashSet<Question>(0); 
    ... 
} 

; 단방향 인 경우 의 mappedBy 특성을 제거하십시오. 어느 쪽이든이 방법을 사용하면 question_to_entity 테이블을 직접 관리 할 필요가 없으며 시스템에있는 개별 엔터티의 수를 줄일 수 있습니다.


다른 한편으로는, 당신은 필요하면 선의의QuestionToSection 약한 엔티티 - 인스턴스가 질문 섹션 이외의 속성이있는 경우 들이는 연결 - 당신은 참으로 계단식에 문제가 고집. 당신이하려고하는 것은 하나의 엔티티 프라퍼티를 DB의 같은 열에 매핑하여 불일치의 기회를 제공합니다.

그리고 아직 ID가되지 않도록 관련 QuestionSection 기관 중 하나 또는 둘 모두가 새로운 경우 는 불일치가있다. JPA는 연결된 QuestionSection 엔티티의 ID에서 QuestionToSection의 id 필드를 설정해야한다는 것을 알 수있는 방법이 없습니다. 자동 생성 된 ID를 수신하면 연결된 QuestionToSection 엔티티가 일치하지 않게됩니다.

QuestionToSection에 설정하고 영구 속성 접근 메서드로 게임하는 것이 문제의 원인이 될 수 있지만 이는 다소 괴롭습니다. 약한 엔티티가 필요하다면 여기에 PERSIST 연산을 캐스케이드하지 않는 것이 좋습니다.하지만 다른 연산을 캐스케이드 할 수는 있습니다. 사실,이 경우 약한 엔티티가 에서까지 캐스케이드되고 싶지만 이 아닌에서 다른 연관된 엔티티로 캐스케이드하고 싶을 것입니다.

+0

@JohnBolliner 응답 해 주셔서 감사합니다. QuestionToSection 테이블에 몇 가지 추가 속성을 추가하여 간단한 다 대다 관계를 사용할 수 없도록해야합니다. 데이터베이스의 구조를 변경해야한다고 생각합니다. – luke

0

당신은 클래스 QuestionToSection 모두 @JoinColumn에서 insertable = false을 제거해야합니다. 이 작업을 수행하는 캐스케이드 삽입 작업을 오버라이드하고 있으므로 JPA는 존재하지 않을 경우 삽입하지 않습니다. 주석에서 삽입 기능을 제거하면 문제가 해결 될 수 있습니다.

+0

나는'insertable = false'을 제거하려고 시도했으나 hibernate는'org.hibernate.MappingException : 엔티티 : com.norbsoft.beviado.models.article.QuestionToSection 열 : question_id (insert = "false"update = "false"로 매핑해야 함) ' – luke