2010-12-16 6 views
5

두 엔터티가 모두 포함 된 두 개의 엔터티를 만들려고합니다. 엔티티 중 하나는 다른 엔티티에 대한 두 개의 참조를 가지며, 두 참조 모두 ManyToOne과 관련됩니다.Java EE 6 JPA 2 ManyToOne 관계가 잘못된 외부 키를 만듭니다.

예제 코드는 다음과 같습니다.

@Embeddable 
public class ItemPK { 
    @Column(nullable = false, length = 100) 
    private String itemId; 
    @Column(name = "item_client_id", nullable = false) 
    private int clientId; 
    ... 
} 

@Entity 
@Table(name = "item") 
public class Item { 
    @EmbeddedId 
    private ItemPK id; 

    @ManyToOne 
    @JoinColumn(name = "item_client_id") 
    private Client client; 

    @OneToMany(mappedBy="item", cascade = CascadeType.ALL, orphanRemoval = true) 
    private Set<RelatedItem> relatedItems; 

    @OneToMany(mappedBy="relatedItem", cascade = CascadeType.ALL, orphanRemoval = true) 
    private Set<RelatedItem> relatedItemsRHS; 
    ... 
} 

@Embeddable 
public class RelatedItemPK { 
    @Column(name = "itemId", length = 100, nullable = false) 
    private String itemId; 
    @Column(name = "item_client_id", nullable = false) 
    private int clientId; 
    @Column(name = "relatedItemId", length = 100, nullable = false) 
    private String relatedItemId; 
    @Column(name = "related_item_client_id", nullable = false) 
    private int relatedItemClientId; 
    ... 
} 

@Entity 
@Table(name = "related_item") 
public class RelatedItem { 
    @EmbeddedId 
    private RelatedItemPK id; 

    @ManyToOne(cascade = CascadeType.ALL, optional = false) 
    @JoinColumns({ 
    @JoinColumn(name="itemId", referencedColumnName="itemId", insertable=false, updatable=false), 
    @JoinColumn(name="item_client_id", referencedColumnName="item_client_id", insertable=false, updatable=false) 
    }) 
    private Item item; 
    @ManyToOne(cascade = CascadeType.ALL, optional = false) 
    @JoinColumns({ 
    @JoinColumn(name="related_item_client_id", referencedColumnName="item_client_id", insertable=false, updatable=false), 
    @JoinColumn(name="relatedItemId", referencedColumnName="itemId", insertable=false, updatable=false) 
    }) 
    private Item relatedItem; 
    ... 
} 

문제점은 RelatedItem 엔티티에 대한 외래 키를 작성하는 중 SQLException이 발생합니다. 실패한 두 번째 ManyToOne 관계입니다. 외래 키 생성 SQL은이 사항이 오류가 발생하는 인해 MySQL, 항목 테이블 이후

ALTER TABLE related_item ADD CONSTRAINT FK_related_item_related_item_client_id FOREIGN KEY (related_item_client_id, relatedItemId) REFERENCES item (item_client_id, itemId) 

다음 item_client_id에 의해 해당 itemId에 의해 처음 인덱싱, 다음과 같습니다.

나는 SQL은 다음과 같아야 있도록 열 장소를 전환하려면

,

ALTER TABLE related_item ADD CONSTRAINT FK_related_item_relatedItemId FOREIGN KEY (relatedItemId, related_item_client_id) REFERENCES item (itemId,item_client_id) 

나는 "JoinColumn"의 순서를 변경 시도했지만 결과는 변하지 않았다. 또한 영속성 공급자가 열 이름별로 순서를 선택했는지 확인하기 위해 필드의 이름을 바꾸려고했지만 결과는 변경되지 않았습니다.

그래서 열 순서를 적용하는 방법이 있습니까?

p.s.

  • MySQL은 5.1
  • 는 EclipseLink 2.0.0
  • 자바 EE 6
  • JPA 2
  • 글래스 피쉬 v3의

편집 : 나는 다음과 같은 재료 사용은 EclipseLink는 생산 다음과 같은 SQL을하는 실행에 실패했습니다.

CREATE TABLE related_item (SIMILARITY DOUBLE, widget_id INTEGER NOT NULL, relatedItemId VARCHAR(100) NOT NULL, itemId VARCHAR(100) NOT NULL, related_item_client_id INTEGER NOT NULL, item_client_id INTEGER NOT NULL, PRIMARY KEY (widget_id, relatedItemId, itemId, related_item_client_id, item_client_id)); 
CREATE TABLE item (IMAGEURL VARCHAR(2048), STATUS VARCHAR(64), URL VARCHAR(2048), PRICE DOUBLE, STOCK INTEGER, DESCRIPTION TEXT(64000), NAME VARCHAR(255), ITEMID VARCHAR(100) NOT NULL, item_client_id INTEGER NOT NULL, PRIMARY KEY (ITEMID, item_client_id)); 
ALTER TABLE related_item ADD CONSTRAINT FK_related_item_itemId FOREIGN KEY (itemId, item_client_id) REFERENCES item (itemId, item_client_id); 
ALTER TABLE related_item ADD CONSTRAINT FK_related_item_related_item_client_id FOREIGN KEY (related_item_client_id, relatedItemId) REFERENCES item (item_client_id, itemId); 
ALTER TABLE item ADD CONSTRAINT FK_item_item_client_id FOREIGN KEY (item_client_id) REFERENCES client (ID); 
+0

무엇이 오류입니까? 제약 조건에서 필드의 순서는 영향을 미치지 않아야합니다.(오류를 생성하기 위해 생성 된 SQL을 포함하십시오.) – James

+0

제약 조건의 순서는 MySQL에서 중요합니다. 인덱스의 첫 번째 키가 제약 목록의 첫 번째 열과 동일한 대상 테이블에 해당 인덱스가 있어야합니다. – bdaylik

답변

1

스택 추적을 포함하십시오. 그러나 VERY 외래 키를 직접 지정해야하는 경우가 아니라면 @JoinColumn 태그를 건너 뛰는 것이 좋습니다. 한 방향에서 mappedBy 속성을 지정함으로써 JPA는 스스로 수행 할 작업을 파악할 수 있습니다.

Java EE 6 및 JPA는 컨벤션을 통한 컨벤션 (Convention over Configuration)을 활성화하는 데 많은 노력을 기울였습니다. 즉, 대부분의 경우 일은 즉시 처리됩니다. 보일러 플레이트 코드가 적기 때문에 프로그래머에게는 바람직합니다. JPA 및 Jave EE 컨테이너 구현 자에게는 최상의 성능 솔루션을 자유롭게 선택할 수 있으므로 바람직합니다. 외래 키 관계를 직접 선언하면 JPA와 JPA 모두 이점을 잃게됩니다.

편집 : 실제로, mappedBy를 지정하고 @JoinTable을 지정하면 문제의 근본 원인이 될 수 있습니다. 하지만 확실하게 말해 스택 추적을 확인해야합니다.

+0

mappedBy와 @JoinColumns를 여러 곳에서 사용하고 있지만 문제가있는 것은 단 하나입니다 BTW : @JoinColumns를 제거하려고했지만 다음 예외가 발생했습니다 필드에 여러 개의 쓰기 가능 매핑이 있습니다. [related_item.item_client_id]. 하나만 쓰기 가능으로 정의되고 다른 모든 필드는 읽기 전용으로 지정되어야합니다. 및 필드를 읽기 전용으로 지정하는 다른 방법을 알지 못합니다. – bdaylik

0

열의 순서는 중요하지 않습니다. 그렇다면 색인의 순서를 변경하여 기본 키를 나열하는 순서를 변경하거나 스크립트를 사용하여 DDL을 생성 할 수 있습니다.