当前位置: 首页 > 知识库问答 >
问题:

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

席言
2023-03-14

我有一个奇怪的行为,JPA类层次结构使用一个表。基本上,我有两个实体EntityMap和EntityMapB,它们都扩展了EntityMaps。鉴别器值为“ENTITY_TYPE”,对于EntityMap为A,对于EntityApb为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 = "B "和ENTITY_id = "12345 ",其中既有ID为" 12345 "的EntityA,也有ID为" 12345 "的EntityB。

现在,当我加载id为“12345”的EntityA时,它在EntityMap类型的getEntityMaps()中有一个条目,但该EntityMapA上的鉴别器值为“B”。

这里出了什么问题?为什么将带有鉴别符“B”的行映射到EntityMapA实体?

是因为我将EntityId映射了两次(一次在父类上使用@Col列(name="ENTITY_TYPE",可插入=false,可更新=false),然后再次将每个JoinCol列映射到实际实体?

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

共有1个答案

令狐增
2023-03-14

问题是您使用同一列映射两个不同的关联。AFAIK,这是不支持的。

这实际上是一件好事,因为使用两个单独的列来引用不同的东西要干净得多。例如,它允许在这些列上定义FK约束,而这在您当前的解决方案中是不可能的,因为列根据行保存EntityA或EntityB的id。

 类似资料:
  • 问题内容: 我有一个Client和Affiliate类,它是从Person类继承的。正在使用联接的继承策略类型- 它们中的每一个都与父类共享主键。由于没有鉴别符列,我们选择使用DescriptorCustomizer和ClassExtractor。但是它并没有真正让人们知道它是如何工作的,而且代码似乎也没有编译。如果有人给出一个带有代码片段的漂亮示例以供理解,那将是很好的。 问题答案: 根据上述文

  • 我有一个与鉴别器列连接的继承映射。 父实体: 附注。我使用的是hibernate 5.0.9.Final。

  • 问题内容: 嗨,我是JPA的新手,我在理解它如何处理继承方面遇到困难。 我有一个需要解决的特定问题,而无需更改数据库方案,但是如果您找不到解决方案,我将感谢使用其他数据库方案的解决方案建议(欢迎使用Hibernate / TopLink解决方案)。 如果我不清楚或您需要更多信息,请告诉我。提前致谢! 我有这个数据库: 到目前为止,我的实体看起来像这样: 目前,我能够持久地保存Fruit对象。.仅当

  • 问题内容: 您将如何在以下示例代码中配置注释?我只想保留JPA注释,避免使用Hibernate特定的依赖项。 下面的代码正确吗? (这些类将具有多个版本,RefSomeOtherExample等,并且每个类一个db表。有些可能会添加其他字段(列),但大多数只会使用继承自“ RefData”基类的基本字段。) 基类: 最终,我想使用Hibernate的SchemaExport类从中生成模式创建脚本。

  • 问题内容: 我们对PostgreSQL中的继承以及在JPA中将其映射为实体存在疑问。我们的数据库和我们要映射的表是: 我们在Netbeans 7.1.2中使用自动工具将它们映射到实体。起初我认为仅添加就足够了 因此,它只是 扩大了 ,但无法正常工作。最好的方法是什么?提前致谢。 问题答案: JPA的继承概念基于普通表。它并没有真正“理解” PostgreSQL表继承的想法。这是使用旨在暴露功能的最

  • 在类上使用@DiscriminatorColumn并在子类上使用@DiscriminatorValue时,Hibernate生成的SQL将discriminator值用作涉及discriminator列的子句的文字。 这并不是很糟糕,除非您有几个鉴别器值,并且表可能被多次选择,这样就会出现如下查询: 可能有大量不同的SQL ID和基于文字的执行计划(在本例中为'fam'、'giv'、'pfx',但