【问题标题】:Inherited abstract class with JPA (+Hibernate)使用 JPA (+Hibernate) 继承抽象类
【发布时间】:2011-04-19 03:43:47
【问题描述】:

您将如何在以下示例代码中配置注释?我只想坚持使用 JPA 注释并避免 Hibernate 特定的依赖项。 下面的代码正确吗?

@Entity
public class RefExample extends RefData {

}

(这些类将有多个版本,RefSomeOtherExample 等,每个类一个 db 表。有些可能会添加额外的字段(列),但大多数会简单地使用从“RefData”基类继承的基本字段.)

基类:

@Entity
public abstract class RefData {

    private long id;
    private String code;
    private String desc;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    public long getId() {

        return id;
    }

    public void setId(long id) {

        this.id = id;
    }

    @Column(unique = true, nullable = false, length=8)
    public String getCode() {

        return code;
    }

    public void setCode(String code) {

        this.code = code;
    }

    @Column(unique = true, nullable = false, length=80)
    public String getDesc() {

        return desc;
    }

    public void setDesc(String desc) {

        this.desc = desc;
    }
}

最终我想使用 Hibernate 的 SchemaExport 类从中生成模式创建脚本。在上述情况下,这两个类只应导致创建一个名为“RefExample”的表,其中包含来自“RefData”的三列。这行得通吗?

【问题讨论】:

    标签: java hibernate jpa annotations


    【解决方案1】:

    来自 JPA 1.0 规范:

    抽象类和具体类都可以是实体。 抽象类和具体类都可以使用实体注释进行注释,映射为实体,并作为实体查询。

    实体可以扩展非实体类,非实体类可以扩展实体类

    如果你想要一个表,你应该使用Single Table继承。

    只需定义一个鉴别器列如下:

    @Entity
    @DiscriminatorColumn(name="REF_TYPE")
    public abstract class RefData {
    

    但如果你不想依赖 JPA 继承策略,你可以使用 MappedSuperclass 代替:

    @MappedSuperclass
    public abstract class RefData {
    

    JPA 规范

    实体可以从提供持久实体状态和映射信息的超类继承,但它本身不是实体。通常,这种映射超类的目的是定义多个实体类共有的状态和映射信息

    请记住您不能同时使用@Entity 和@MappedSuperclass。

    【讨论】:

    • @Crusader 参见此处:stackoverflow.com/questions/2700680/… 在处理继承时我如何解决性能问题。 如果要使用 TABLE PER CLASS 策略,目标数据库必须支持身份生成策略
    • 目前还不能 100% 确定,但我认为 MappedSuperclass 可能是我最好的选择。所有这些表的真正用途是存储下拉字段中显示的值,这些值被分配(一对多)到实际数据记录。
    • 是否可以查询(HQL 或 JPQL)存在于带有 @MappedSuperclass 注释的超类中的属性
    【解决方案2】:

    @MappedSuperclass 为我工作。我正在努力将视图映射到 2 个对象,它们是父类和子类。我的观点是从 2 张桌子加入的。两个表中的主键都出现在视图中。 @DiscriminatorColumn 对我不起作用,因为它需要一个专门分配给对象数据类型的列,而且它会抛出我无法解决的 'repeated Column in object exception'

    我阅读了这个论坛并尝试了 @MappedSuperclass 注释。它成功了。

    我已将 @MappedSuperclass 放在超类中,并将 @Id@GeneratedValue 放在超类标识符中。在我给出的子类中

    @Entity
    @Table(name="view_name")
    

    并使用子类对象从视图中获取数据。而已。

    不使用 @DiscriminatorColumn 的联接表的休眠注释中的继承对我有用。

    【讨论】:

      【解决方案3】:

      您可以使用其中一种继承策略来实现这一点。您的情况看起来是层次结构的 Single 类的情况。

      查看this

      【讨论】:

      • 那篇文章把我难住了。我实际上是在描述那里描述的每个具体类策略的表(每个具体的“RefExample”类一个表),但它说这种方法在 JPA 中“不流行”并且是可选的。这三个选项似乎都不完全符合我的要求。老鼠!
      • 这篇文章的链接好像失效了。
      猜你喜欢
      • 2011-05-15
      • 1970-01-01
      • 1970-01-01
      • 2012-05-20
      • 1970-01-01
      • 1970-01-01
      • 2011-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多