ae6*_*6rt 12 java polymorphism hibernate
这是Hibnerate多态性问题和数据模型设计问题; 他们正在交织.我过去曾经使用过Hibernate,并且很享受它,但有时我发现很难想到除了琐碎的设计之外的任何东西.不是对Hibernate的敲门声; 只是观察到ORM通常具有挑战性.
我认为这是一个Hibernate 101问题,但我不确定.我想要实现的目标甚至可能无法实现.
我有一个抽象类Fruit,它将被子类化为Apple和Orange.我有一个Note类,代表关于苹果和橘子的注释或评论.Apple或Orange可以有许多与之关联的Notes,但只有一个Apple或Orange将与给定的Note相关联.
这是类的草图,我现在在这里省略对象id的去向,以及将它们与Orange区分开的Apples的属性.目前,我对使用哪种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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是当前实现的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;
}
...
}
Run Code Online (Sandbox Code Playgroud)
但是,这是Note类,我认为我想基于我的设计,但我不确定如何考虑Hibernate注释和表映射:
// A note about a fruit:
public class Note {
private String theNote;
private Fruit fruit;
...
}
Run Code Online (Sandbox Code Playgroud)
因此水果将是Apple或Orange实例.
可以使用后面的Note类,它实际上持有Apple或Orange的Fruit,甚至可以与Hibernate ORM映射协调一致吗?如果是,有人可以谈谈如何.
Hen*_*ing 15
这绝对是可能的.您可以将注释与抽象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;
...
}
Run Code Online (Sandbox Code Playgroud)
Étvoilà!
- 基于注释的添加: JPA提供了多种处理继承的策略.Java EE教程中的相关部分应该可以帮助您入门.
基本上,您的选择是:
另一个编辑: 注意这是一个Hibernate,而不是一个JPA问题.但是,不会产生太大的差别,因为选项是相同的.这是Hibernate文档中的相关部分.
这种模式在基于Hibernate的数据层中非常常见。它在内部的工作方式很大程度上取决于使用哪种继承策略。
当使用每个类的表或每个子类的继承表时,将为每个子类/类创建一个表。例如,在您的情况下,您将有一个表Fruit和两个表Apple和Orange,并且在Fruit和Apple / Orange之间具有外键引用。当通过ID请求单个水果(苹果或橙子)时,Hibernate会将Fruit表与Apple和Orange表外部连接。每行将转换为Apple或Orange,具体取决于从中检索字段的表。
另一种可能性是使用鉴别符。Fruit将使用单个表,该表将包含一个鉴别符字段(例如fruit_type,取值apple和orange)。根据该字段的值,Hibernate将确定相应的对象是Apple还是Orange。
在您的情况下,在急于加载的情况下,当Hibernate加载Note对象时,它将急切地获取相应的Fruit并相应地用Apple或Orange实例填充Fruit字段。
在延迟获取的情况下,fruit字段将是实现Fruit接口的代理。在实际的水果田被装载之前,其类型尚未确定。
希望这能回答您的一些疑问。
| 归档时间: |
|
| 查看次数: |
14116 次 |
| 最近记录: |