使用SINGLE_TABLE的JPA继承 - 鉴别器值与类不匹配

时间:2012-06-15 12:25:50

标签: hibernate java-ee jpa

我使用单个表在JPA类层次结构中遇到了奇怪的行为。 基本上我有两个实体EntityMapA和EntityMapB都扩展了EntityMap。鉴别器值是'ENTITY_TYPE'它对于EntityMapA是A,对于EntityMapB是B. 不知怎的,我得到了EntityMapA类型的对象,其中鉴别器值被设置为' B'!

我正在使用Hibernate 3.3作为JPA提供程序。

以下是代码:

@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中有一个映射:

    @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_MAP行,其中包含ENTITY_TYPE =&#34; B&#34;和ENTITY_ID =&#34; 12345&#34; 有一个EntityA,ID为#34; 12345&#34;和具有相同ID的实体B&#34; 12345&#34;。

现在当我使用id&#34; 12345&#34;加载EntityA时在EntityMapA类型的getEntityMaps()中有一个条目,但该EntityMapA上的鉴别器值是&#39; B&#39;。

这里出了什么问题?为什么一行有鉴别器&#39; B&#39;映射到EntityMapA实体?

是因为我在父类上映射EntityId两次(一次是@Column(name =&#34; ENTITY_TYPE&#34;,insertable = false,updatable = false),然后每次JoinColumn再映射到实际实体?

更新 顺便说一句,EntityA上的集合中列出的EntityMapA从未真正创建过。当您尝试加载实体时,您会收到一个异常,告诉您该实体不存在。所以看起来像Hibernate中的一个bug给我。

1 个答案:

答案 0 :(得分:2)

问题是您使用相同的列来映射两个不同的关联。 AFAIK,不支持此功能。

这实际上是一件好事,因为使用两个单独的列来引用不同的东西会更清晰。它允许在这些列上定义FK约束,例如,这对于当前解决方案是不可能的,因为该列根据行保存EntityA或EntityB的ID。