带有SINGLE_TABLE @Inheritance的EclipseLink JPA问题无法继承

时间:2014-08-05 15:26:22

标签: java spring inheritance jpa eclipselink

我有3个类扩展抽象基类,所有类都具有相同的正式结构。它们都是使用Hibernate / Spring数据工具构建并正常工作的,现在已经在生产系统中使用了几个月。但是,Hibernate不支持开箱即用的鉴别器列多租户,所以我一直在努力转换到EclipseLink 2.5.2,据说这样做。

我花了至少一天的时间试图让以下人员上班 - 如果我能列出我在那段时间尝试过的所有配置,我会道歉,因为他们是军团。我希望这个现有的配置至少能解决那些比我更熟悉EclipseLink的人的错误。基类,减去访问器和构造函数:

@Converters(
    @Converter(name = "UUIDConverter", converterClass = UUIDToStringConverter.class)
)
@MappedSuperclass
@Table(name = "label_type_definitions")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "scope", columnDefinition = "varchar(20) not null")
public abstract class LabelTypeDefinition implements LabelType {

    @Id
    @Convert("UUIDConverter")
    @Column(name = "id", length = 40, columnDefinition = "VARCHAR(40)")
    @GeneratedValue(generator = "uuid")
    @UuidGenerator(name = "uuid")
    protected final UUID id;
    @Column(name = "name", nullable = false)
    protected String name;
    @Column(name = "description")
    protected String description;

...
}

子类。树:

@Entity
@DiscriminatorValue(value = "TREE")
public class LabelTreeDefinition extends LabelTypeDefinition implements LabelTree {
    ....
}

情景:

@Entity
@DiscriminatorValue(value = "SCENARIO")
public class LabelScenarioDefinition extends LabelTypeDefinition implements LabelScenario {
    ...
}

节点:

@Entity
@DiscriminatorValue(value = "NODE")
public class LabelNodeDefinition extends LabelTypeDefinition implements LabelNode {
    ...
}

LabelType接口扩展了Serializable和我自己的Identifiable,并描述了模型的访问者合同(模型的接口=不是我的设计,是由我的前任烘焙的单独的Maven项目的结果)。 LabelTree / Node / Scenario接口都扩展LabelType而不添加合同。

问题:当此配置构造我的数据库时,它会忽略表规范并且不构建范围列。

LABELTREEDEFINITION
    id
    name
    description
LABELNODEDEFINITION
    id
    name
    description
LABELSCENARIODEFINITION
    id
    name
    description

对我而言,这意味着它完全忽略了@Inheritance注释并且正在默默地这样做。我可以通过在每个子类中添加@Table注释并包含一个范围列(后者是使用Hibernate时的构建方式)来强制它构建所有内容并使其看起来非常正确,但当然我的所有Spring数据查询忽略了鉴别器。

所有这些都是实现不同接口的结果吗?如果是这样,那让我担心,因为它看起来非常脆弱。在我看来,这与其他所有内容完全相同,例如。在这里(http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Entities/Inheritance)。是否有我遗漏的东西或者我忽略了一些EclipseLink的怪癖?

1 个答案:

答案 0 :(得分:1)

好的,所以我通过在调试器中痛苦地运行EclipseLink的代码来解决问题。我碰巧注意到,当它试图在org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor中分配继承时,它没有找到超类LabelTypeDefinition。这对Hibernate来说不是问题,因此我并没有想到抽象基类也必须包含在persistence.xml中,即。

<persistence-unit name="[MYPROJECT]" transaction-type="RESOURCE_LOCAL">
    ...
    <class>com.[MYPROJECT].persistence.labeltype.LabelNodeDefinition</class>
    <class>com.[MYPROJECT].persistence.labeltype.LabelTreeDefinition</class>
    <class>com.[MYPROJECT].persistence.labeltype.LabelScenarioDefinition</class>
    <class>com.[MYPROJECT].persistence.labeltype.LabelTypeDefinition</class>
    ...
</persistence-unit>

然而,当我第二次运行它时,我发现仍然无法找到该类。作为一个Hail Mary,我在我的父类中用@Entity替换了@MappedSuperclass并且一切正常。

现在,修复的第一部分是一个小问题,即。我应该想到EclipseLink需要比Hibernate更明确的配置。然而,第二个问题让我觉得是一个错误,特别是因为我在很多地方找到了文档(包括我上面发布的eclipse wiki链接),这表明它应该可行。而且因为在语义上它似乎更正确:我的抽象基类实际上不是一个&#34;实体&#34;因为没有LabelType对象被持久化。但它是一个超级类别&#34;映射&#34;由我的实体。