java - SINGLE_TABLE @Inheritance 不继承的 EclipseLink JPA 问题

标签 java spring inheritance jpa eclipselink

我有 3 个类扩展了一个抽象基类,它们都具有相同的形式结构。它们都是使用 Hibernate/Spring 数据工具构建并正常工作的,并且已经在生产系统中运行了几个月。然而,Hibernate 不支持开箱即用的鉴别器列 Multi-Tenancy ,因此我一直致力于过渡到 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 接口(interface)扩展了 Serializable 和我自己的 Identificable,并描述了模型的访问器契约(模型的接口(interface) = 不是我的设计,是我的前任为 API 烘焙的单独 Maven 项目的结果)。 LabelTree/Node/Scenario 接口(interface)都扩展了 LabelType,但没有添加到契约中。

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

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

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

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

最佳答案

好的,所以我通过在调试器中痛苦地运行 EclipseLink 的代码解决了这个问题。我碰巧注意到,当它尝试在 org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor 中分​​配继承时,它没有找到父类(super class) 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>

但是,当我第二次运行它时,我发现它仍然找不到该类。作为万福玛丽,我在父类中用 @Entity 替换了 @MappedSuperclass,这一切都有效。

现在修复的第一部分有点令人头疼,即。我应该想到 EclipseLink 可能需要比 Hibernate 更明确的配置。然而,第二个让我觉得是一个错误,特别是因为我在很多地方找到了表明它应该可以工作的文档(包括我上面发布的 eclipse wiki 链接)。因为从语义上来说,它似乎更正确:事实上,我的抽象基类并不是一个“实体”,因为没有 LabelType 对象会被持久保存。但它是一个由我的实体“映射”的父类(super class)。

关于java - SINGLE_TABLE @Inheritance 不继承的 EclipseLink JPA 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25142607/

相关文章:

spring - 静态代码分析与 Spring 和其他抽象的配合如何?

java - SLF4J 的 NoSuchMethodError

c# - 是否扩展接口(interface),当基类已经扩展了同一个接口(interface)

Scala:如何设置在抽象父类(super class)构造函数中定义的实例字段?

java - 组播错误: Multicast Address Not Found

java - 翻译给定输入流的字节序列

java - 如何在 Java 中针对较低的语言级别

java - 返回响应后,RequestContextHolder 中设置的属性丢失

java - 在子类中强制使用 Java 属性类型

java - spring oauth2sso 是如何工作的?为什么会发生这个重定向序列?