2012-06-15 2 views
1

과 일치하지 않습니다. 하나의 테이블을 사용하여 JPA 클래스 계층 구조에서 이상한 동작이 발생했습니다. 기본적으로 EntityMap을 확장하는 두 개의 엔티티 EntityMapA 및 EntityMapB가 있습니다. 판별 자 값은 'ENTITY_TYPE'이며 EntityMapA에 대해서는 A이고 EntityMapB에 대해서는 B입니다. 어떻게 든 구분 기호 값이 'B'로 설정된 EntityMapA 유형의 객체를 얻습니다!SINGLE_TABLE을 사용하는 JPA 상속 - 판별 자 값이 클래스

JPA 프로 바이더로서 Hibernate 3.3을 사용하고 있습니다. = "12345 ENTITY_ID 내가 ENTITY_TYPE ="B "와 ENTITY_MAP 행이 이제

@OneToMany(cascade=CascadeType.ALL,fetch = FetchType.LAZY, mappedBy = "entityA") 
    public List<EntityMapA> getEntityMaps() { 
     return entityMaps; 
    } 

    public void setEntityMaps(List<EntityMapA> entityMaps) { 
     this.entityMaps = entityMaps; 
    } 

과 : 여기

코드입니다 :

@Entity 
@Table(name="ENTITY_MAP") 
@DiscriminatorColumn(name = "ENTITY_TYPE") 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
public class EntityMap implements Serializable { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    private Long entityMapId; 

    //This is a ID of another entity we map to. It is a different entity type depending on 
    //The subclass. For EntityMapA it would map to EntityA and for EntityMapB it would map 
    // to EntityB 
    private Long entityId; 


    private String discriminator; 

    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    @Column(name = "ENTITY_MAP_ID", unique = true, nullable = false) 
    public Long getEntityMapId() { 
     return entityMapId; 
    } 
    public void setEntityMapId(Long EntityMapId) { 
     this.entityMapId = entityMapId; 
    } 


    @Column(name="ENTITY_TYPE",insertable=false,updatable=false) 
    public String getDiscriminator() { 
     return discriminator; 
    } 
    public void setDiscriminator(String discriminator) { 
     this.discriminator = discriminator; 
    } 

    @Column(name="ENTITY_ID",insertable=false,updatable=false) 
    public Long getEntityId() { 
     return entityId; 
    } 
    public void setEntityId(Long entityId) { 
     this.entityId = entityId; 
    } 

    //there are other common fields in here which are left out  
} 


@Entity 
@DiscriminatorValue("A") 
public class EntityMapA extends EntityMap { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -8709307036005000705L; 

    private EntityA entityA; 

    public static final String DISCRIMINATOR = "A"; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "ENTITY_ID", nullable = false) 
    @NotNull 
    public EntityA getEntityA() { 
     return entityA; 
    } 

    public void setEntityA(EntityA entityA) { 
     this.entityA = entityA; 
    } 

} 



@Entity 
@DiscriminatorValue("B") 
public class EntityMapB extends EntityMap { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -8709307036005000705L; 

    public static final String DISCRIMINATOR = "B"; 

    private EntityB entityB; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "ENTITY_ID", nullable = false) 
    @NotNull 
    public EntityB getEntityB() { 
     return entityB; 
    } 

    public void setEntityB(EntityB entityB) { 
     this.entityB = entityB; 
    } 
} 

그리고 마지막으로 나는 EntityA에 매핑이 " ID가"12345 "인 EntityA와 ID가"12345 "인 EntityB가 모두 있습니다.

id가 "12345"인 EntityA를로드 할 때 EntityMapA 유형의 getEntityMaps()에 하나의 항목이 있지만 해당 EntityMapA의 판별 자 값은 'B'입니다.

여기에 무슨 문제가 있습니까? Discriminator 'B'가있는 행이 EntityMapA 엔티티에 매핑되는 이유는 무엇입니까? 내가 한 번 @Column (이름 = "ENTITY_TYPE"두 번합니다 (ENTITYID을지도하기 때문에

는 삽입 = false를 갱신 =) 거짓 부모 클래스에 다음 다시 JoinColumn 당 실제 엔티티에?

을인가 UPDATE Btw, EntityA의 컬렉션에 나열된 EntityMapA는 실제로 생성되지 않습니다. 엔티티를로드하려고하면 그 엔티티가 존재하지 않는다는 예외가 발생합니다. 따라서 최대 절전 모드의 버그처럼 보입니다.

답변

2

두 개의 서로 다른 연결을 매핑하는 데 동일한 열을 사용하는 것이 문제입니다 .AFAIK, 지원되지 않습니다.

사실 서로 다른 두 개의 열을 사용하는 것이 훨씬 깔끔하기 때문에 실제로 좋은 방법입니다. 예를 들어, 열에 따라 EntityA 또는 EntityB의 ID가 열에 있으므로 현재 솔루션에서는 불가능한 해당 열에 대해 FK 제약 조건을 정의 할 수 있습니다.

+1

여전히 버그라고 생각합니다. 판별자를 B로 설정 한 행은 절대로 EntityMapA를 작성해서는 안됩니다. – Ben

+0

Hibernate의 버그가 아니고, 이미 당신에게 지적한 의심스러운 매핑입니다. 올바른 매핑은 EntityMap에 대한 연관을 EntityMap으로 매핑하는 것입니다. 원한다면 EntityMapA 및 EntityMapB에서 공변 리턴 유형을 사용할 수 있습니다. –

관련 문제