Java 冬眠多态性

Java 冬眠多态性,java,hibernate,polymorphism,Java,Hibernate,Polymorphism,这是一个Hibnerate多态性问题和一个数据模型设计 问题,;它们缠绕在一起。我以前用过Hibernate, 我很享受,但有时我觉得很难思考 除了琐碎的设计,什么都可以。没有敲打冬眠;只是 观察到ORM通常具有挑战性 我认为这是一个Hibernate 101问题,但我不确定。我试图实现的目标可能根本不可能实现 我有一个抽象类Fruit,它将被子类化为Apple 还有橘子。我有一个表示注释或注释的Note类 关于苹果和桔子。苹果或桔子可以有很多音符 与之关联,但只有一个苹果或橘子会被关联 与给定

这是一个Hibnerate多态性问题和一个数据模型设计 问题,;它们缠绕在一起。我以前用过Hibernate, 我很享受,但有时我觉得很难思考 除了琐碎的设计,什么都可以。没有敲打冬眠;只是 观察到ORM通常具有挑战性

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

我有一个抽象类Fruit,它将被子类化为Apple 还有橘子。我有一个表示注释或注释的Note类 关于苹果和桔子。苹果或桔子可以有很多音符 与之关联,但只有一个苹果或橘子会被关联 与给定的音符相关联的

这里是课程的草图,我现在在这里略去了其中的内容 对象id的go,以及区分 他们从桔子上摘下来。目前,我对我使用哪种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类 继续设计,但我不知道如何尊重这一点 要休眠注释和表映射,请执行以下操作:

// A note about a fruit:
public class Note {
   private String theNote;
   private Fruit fruit;
   ...
}
因此,水果要么是苹果,要么是桔子


后一个Note类,以及它对水果的引用,实际上会包含一个苹果或桔子,甚至可以与Hibernate ORM映射相协调吗?如果是,请有人谈谈如何做。

这是绝对可能的。您可以将注释与抽象的
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;
   ...
}
@实体
@继承权
公共抽象类水果{
私人定票;
...
@OneToMany(cascade=CascadeType.ALL,mappedBy=“fruit”)
公共集getNotes(){
回条;
}
}
@实体
公营苹果延伸水果{
...
}
@实体
公共级橙汁{
...
}
@实体
公开课堂讲稿{
私人字符串注释;
@许多酮
私家水果;
...
}

--根据评论添加: JPA提供了多种处理继承的策略。这将有助于你开始

基本上,您的选择是:

  • 将所有内容存储在一个表中,并使用鉴别器列了解哪一行是哪种类型
  • 将每个混凝土类别(苹果和橙色)存储在单独的表格中
  • 具有带鉴别器列的通用水果表,以及带有水果表外键的苹果和橙色表
另一次编辑:
注意这是一个Hibernate问题,不是JPA问题。不过,这并没有太大区别,因为选项是相同的。下面是一个例子。

这种模式在基于Hibernate的数据层中非常常见。它的内部工作方式在很大程度上取决于使用的继承策略

当使用每个类表或每个子类表继承时,将为每个子类/类创建一个表。例如,在您的例子中,您将有一个表Fruit和两个表
Apple
Orange
,其中Fruit和Apple/Orange之间有外键引用。当通过ID请求单个水果(无论是苹果还是橘子)时,Hibernate将把水果表与苹果和橘子表连接起来。根据从哪个表中检索字段,每行将转换为苹果或橙色

另一种可能是使用鉴别器。将使用单个表
水果
,其中包含一个鉴别器字段(例如
水果类型
取值
苹果
橙色
)。根据此字段的值,Hibernate将确定相应的对象是苹果还是橙色

在您的情况下,在急切加载的情况下,当Hibernate加载Note对象时,它将急切地获取相应的水果,并用相应的Apple或Orange实例填充水果字段

在延迟抓取的情况下,水果字段将是实现水果接口的代理。在实际果园装载之前,其类型尚未确定


希望这能回答您的一些疑问。

暂时-1:这不能回答问题,是吗?您已经告诉Hibernate水果和便笺之间的关系。你如何告诉它如何将水果与苹果或橙子区分开来?@杰森:事实上,它是这样做的,而且非常准确。如果你再次阅读这个问题,特别是从第二个代码块开始的最后几段,我提供的代码正是ae6rt所要求的。-1删除。。。你能详细说明一下苹果在数据库中的存储方式与橘子不同吗?+1:谢谢,这有助于澄清问题。看起来鉴别器列+每个表子类是我在本例中希望采用的方式。找到此链接以获取更多示例:我尝试了您的方法,但它生成了一个与超类中定义的id列相关的错误。你愿意帮我吗?这里是链接:我有一个类似的问题,因为我的代码运行在MySQL数据库上。你愿意帮我解决相关问题吗?以下是链接:
@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;
   ...
}