Hibernate 中有很多关于抽象映射的主题,但我找不到与我的情况相匹配的内容。
问题:
我的域模型由几个实体组成,它们不相互继承。例如:
- 员工
- 团体
- 部门
- 报告
在哪里:
员工 <-> 组 (n:m),员工 -> 部门 (n:1)
就这点而言,没有问题。但:
我希望能够将报告映射到员工、组或部门之一 (1:1)。(示例被简化为 Report 应该可以映射到更多不同的其他实体)。每个实体都必须驻留在自己的表中,因为不同的外部想要连接到数据库,并且模型不会因其他实体的一般表结构而改变。
我试过的
我尝试使用 Hibernate Inheritance 策略和 Table per Class,而 User、Employee 和 Department 是从新的AbstractEntity子类化的,共享父类的 ID 和 Name 属性。所以 User、Employee 和 Department 仍然有自己的表。我现在可以映射Report <-> AbstractEntity并且这有效。但是:正如人们所预料的那样,当有超过 20 个左右的报告时,这会导致严重的性能问题,因为 Hibernate 内部必须对所有子类表进行大量连接。
每个层次结构的单个表不是一个选项,因为表结构的变化(见问题)。此外,所有实体仅共享 ID 和名称作为公共属性。
可能的解决方案
一种可能的解决方案是自己实现映射。即我将Id和实体类存储在Report中。AbstractEntity 的 getter 现在可以根据保存的值来决定从哪个表加载并返回正确的实体。
但是:这里的问题是,我不能在实体类中做会话的东西,因为报告类不知道会话。此外,这会混淆逻辑和模型层。
解决方法是在 DAO 中编写某种包装器,从数据库中加载正确的实体并将其注入结果中。但这很容易出错,因为每个 DAO 方法都必须被覆盖。
问题
所以我的问题是:有没有办法以某种方式捕获或拦截从数据库中检索报告实体并在那里注入正确的 AbstractEntity 加载?
还是有另一种更优雅的方式来做我想做的事(必须是;))?
我在带有 DAO 的 Java EE 环境中使用 Hibernate 3.6,使用没有 EntityManager 的注释,如http://community.jboss.org/wiki/GenericDataAccessObjects。