使用SINGLE_TABLE的JPA继承-鉴别值与类不匹配 [英] JPA inheritance using SINGLE_TABLE - discriminator value doesn't match class

查看:127
本文介绍了使用SINGLE_TABLE的JPA继承-鉴别值与类不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用单个表的JPA类层次结构中,我有一个奇怪的行为. 基本上,我有两个实体EntityMapA和EntityMapB都扩展了EntityMap.鉴别符值为"ENTITY_TYPE",对于EntityMapA而言为A,对于EntityMapB而言为B. 我不知何故获得了EntityMapA类型的对象,其中鉴别值设置为'B'!

I've got a strange behaviour with a JPA class hierarchy using a single table. Basically I have two entities EntityMapA and EntityMapB which both extend EntityMap. The discriminator value is 'ENTITY_TYPE' and it is A for EntityMapA and B for EntityMapB. Somehow I get Objects of type EntityMapA where the discriminator value is set to 'B'!

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

I am using Hibernate 3.3 as the JPA provider.

这是代码:

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

And then finally I have a mapping in 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 ="B"和ENTITY_ID ="12345" 既有ID为"12345"的EntityA,也有ID为"12345"的EntityB.

Now I have a ENTITY_MAP row with ENTITY_TYPE = "B" and ENTITY_ID = "12345" There are both a EntityA with the id "12345" and a EntityB with the same ID "12345".

现在,当我以id"12345"加载EntityA时,在EntityMapA类型的getEntityMaps()中有一个条目,但是该EntityMapA上的鉴别符值为'B'.

Now when I load EntityA with the id "12345" is has one entry in the getEntityMaps() of type EntityMapA but the discriminator value on that EntityMapA is 'B'.

这是怎么回事?为什么将带有标识符"B"的行映射到EntityMapA实体?

What is going wrong here? Why is a row with the discriminator 'B' mapped to a EntityMapA entity?

是因为我在父类上两次映射了EntityId(一次与@Column(name ="ENTITY_TYPE",insertable = false,updatable = false)映射,然后又将每个JoinColumn映射到实际实体)?

Is it because I map the EntityId twice (once with @Column(name="ENTITY_TYPE",insertable=false,updatable=false) on the parent class and then again per JoinColumn to the actual entity?

更新 顺便说一句,在EntityA的集合中列出的EntityMapA从未真正创建过.当您尝试加载实体时,会收到一个异常消息,告诉您该实体不存在.所以对我来说,这似乎像是休眠中的错误.

UPDATE Btw, the EntityMapA listed in the collection on EntityA is never really created. When you try to load the entity you get an exception telling you that that entity doesn't exists. So looks like a bug in Hibernate to me.

推荐答案

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

The problem is that you use the same column to map two different associations. AFAIK, this is not supported.

这实际上是一件好事,因为使用两个单独的列来引用不同的东西要干净得多.例如,它允许在这些列上定义FK约束,这在您当前的解决方案中是不可能的,因为该列包含EntityA或EntityB的ID,具体取决于行.

And it's actually a good thing, because it's much cleaner to use two separate columns to refer to different things. It allows defining an FK constraint on those columns, for example, which isn't possible with your current solution since the column holds IDs of EntityA or EntityB depending on the row.

这篇关于使用SINGLE_TABLE的JPA继承-鉴别值与类不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆