【问题标题】:How to inherit from multiple base abstract classes in JPA如何从 JPA 中的多个基本抽象类继承
【发布时间】:2018-03-23 19:00:39
【问题描述】:

我遇到了一个问题,我如何创建扩展 多个 基本抽象类的 JPA 实体(无需创建额外的表)。我知道有一个注解@MappedSuperclass,但只要我们使用extends,它就可以只创建一个基类,并且多重继承不是Java特性。

例如,我有两个基地:

@MappedSuperclass
public abstract class Authored {
    @ManyToOne
    private User user;
}

@MappedSuperclass
public abstract class Dated {
    private String creationDate;
}

我希望我的一些模型将仅扩展Authored,一些——仅扩展Dated,还有一些——两者兼而有之。 虽然只能写

@Entity
public class MyEntity extends Authored {
    ...
}

@Entity
public class MyEntity extends Dated {
    ...
}

一些讨论建议沿行继承类(例如AuthoredAuthoredAndDated),但这似乎太脏了,这些基础在逻辑上都不能扩展另一个。

添加

我必须注意,这种风格在 Django 等其他框架中得到支持(由于 python 中的多重继承),所以奇怪的是 JPA 不支持它。

【问题讨论】:

  • 在 Java 中你不能“扩展”多个类。 JPA 只是持久化你的类,因为你不能定义这样的类......

标签: java jpa


【解决方案1】:

很抱歉让您失望了,但除了按照您的建议创建 AuthoredAndDated 之外,没有其他解决方案。

我们的实体面临同样的问题,并采用了相同的程序。

我们有一个

@MappedSuperclass
public class TimestampedObject {

    @CreationTimestamp
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created_at")
    private Date createdAt;

    @UpdateTimestamp
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "updated_at")
    private Date updatedAt;
}

还有一个

@MappedSuperclass
public class IdObject {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "id", updatable = false, columnDefinition = "serial")
    private Long id;

}

因此我们为此创建了一个TimestampedIdObject

编辑:

如果您找到其他合适的解决方案,如果您可以在此处发布,那就太好了,因为我们有同样的问题......

【讨论】:

    【解决方案2】:

    您应该使用@Embeddable / @Embedded 作为目标,将继承替换为组合。

    首先,不要使用@MappedSuperClass,而是使用@Embeddable 来代替您要与之共享属性的类:

    @Embeddable
    public class Authored {...}
    
    @Embeddable
    public class Dated {...}
    

    在下一步中,您的实体不应继承自 AuthoredDated,而是获取引用它们的属性:

    @Entity
    public class MyEntity {
    
        @Embedded
        private Authored authored;
    
        @Embedded
        private Dated dated;
    
    }
    

    如果您想从中获得行为,您可以在没有这些新属性的情况下进行一般访问,您需要引入一个公开必要方法的接口。

    例如,如果MyEntity 应该能够提供有关上次更新和创建的详细信息,您将引入一个接口Authorable,它定义了访问相关数据的方法。

    public interface Authorable { /* necessary methods */ }
    

    MyEntity 会实现这个接口:

    @Entity
    public class MyEntity implements Authorable { 
        /* previous content plus implemented mehtods from interface */ 
    }
    

    【讨论】:

    • 感谢您的回答,这不是一个坏主意。但首先在模型中添加一个简单的字段似乎并不太远,其次在@Embeddable JPA wiki 中插入关系存在一些问题
    • 利用接口和关联的组合以某种方式让您体验到 java 中的多继承,这根本不可用。关系问题似乎不适用于您的示例恕我直言。
    猜你喜欢
    • 2021-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多