一尘不染

休眠多态性

hibernate

这是一个Hibnerate多态性问题和一个数据模型设计问题。他们交织在一起。过去我曾经使用过Hibernate,并且很喜欢它,但是有时候我发现很难想到除了琐碎的设计之外的任何事情。不能敲打hibernate;只是观察到ORM通常可能具有挑战性。

我认为这是一个Hibernate 101问题,但我不确定。我试图实现的目标甚至不可能。

我有一个抽象类Fruit,它将被分为Apple和Orange。我有一个Note类,表示有关Apple和Orange的注释或评论。一个Apple或Orange可以有许多与之关联的注释,但是只有一个Apple或Orange可以与给定的Note关联。

这是这些类的草图,我现在在这里省略了对象ID的去向,以及将它们与Orange区别开的Apple的属性。就目前而言,我对使用哪种Hibernate继承策略并不感到很满意。

abstract public class Fruit {
}

// Apples have notes written about them:
public class Apple extends Fruit {
   private Set<Note> note;
   ...

   @OneToMany(cascade = CascadeType.ALL)
   public Set<Note> getNote() {
       return note;
   }
}


// Oranges have notes written about them:
public class Orange extends Fruit {
   private Set<Note> note;
   ...

   @OneToMany(cascade = CascadeType.ALL)
   public Set<Note> getNote() {
       return note;
   }
}

这是当前实现的Note类,其中我们看到它具有Apple和Orange的字段。这种设计的缺陷或不足之处在于,单个音符实例将仅指向Apple或Orange中的一个,而不会指向两者。因此,如果将Note绑定到Apple,则Orange字段是多余且难看的,反之亦然。

// A note about an Apple or Orange
public class Note {
   private String theNote;
   private Apple apple; 
   private Orange orange;
   ...

   // with the usual many to one mapping
   @ManyToOne
   @JoinColumn(name = "apple_id")
   public Apple getApple() { 
       return apple;
   }

   // with the usual many to one mapping
   @ManyToOne
   @JoinColumn(name = "orange_id")
   public Orange getOrange() {
       return orange;
   }

   ...
}

然而,这是提示类,我 我要我的基础上设计的,但我不知道如何思考这对于Hibernate的注释和表映射:

// A note about a fruit:
public class Note {
   private String theNote;
   private Fruit fruit;
   ...
}

这样,水果将是Apple或Orange实例。

后面的Note类(引用了Fruit)实际上可以容纳Apple或Orange,甚至可以与Hibernate
ORM映射进行协调吗?如果是的话,有人可以谈谈如何。


阅读 204

收藏
2020-06-20

共1个答案

一尘不染

这绝对是可能的。您可以将注释与抽象Fruit类相关联,而不必在每个实现中都重复它们:

@Entity
@Inheritance
public abstract class Fruit {
   private Set<Note> notes;
   ...

   @OneToMany(cascade = CascadeType.ALL, mappedBy = "fruit")
   public Set<Note> getNotes() {
       return notes;
   }
}

@Entity
public class Apple extends Fruit {
   ...
}


@Entity
public class Orange extends Fruit {
   ...
}

@Entity
public class Note {
   private String theNote;

   @ManyToOne
   private Fruit fruit;
   ...
}

瞧!

-基于注释的添加: JPA提供了多种处理继承的策略。Java
EE教程中
相关部分将帮助您入门。

基本上,您可以选择:

  • 将所有内容存储在一个表中,并使用区分符列知道哪一行是哪种类型
  • 将每个具体的类(Apple和Orange)存储在单独的表中
  • 拥有一个带有鉴别符列的通用水果表,以及带有水果表外键的苹果和橙色表

另一个编辑:
注意这是一个Hibernate,而不是JPA问题。但是,因为选项相同,所以差别不大。这是Hibernate文档中相关部分

2020-06-20