Hibernate:在TABLE_PER_CLASS继承模式下获取多态属性

时间:2012-12-30 23:58:05

标签: hibernate jpa jpql

正如Hibernate文档中所述,TABLE_PER_CLASS在获取多态关系时执行得非常好

  

2.2.4.1. Table per class

     

这种策略有许多缺点(尤其是   多态查询和   协会)在JPA中解释   spec,Hibernate参考   文档,Hibernate in Action,   和许多其他地方。 Hibernate的工作   他们中的大多数人实施这一点   使用SQL UNION查询的策略。它   通常用于顶级   继承层次结构:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Flight implements Serializable { ... }            
     

此策略支持一对多   协会提供它们   双向即可。这个策略可以   不支持IDENTITY生成器   策略:必须共享id   跨几个表。所以,   在使用这种策略时,你应该这样做   不要使用AUTO也不要使用IDENTITY。

但在这种情况下我没有其他选择继承策略,所以我正在寻找改进查询的方法。 Comment是我的具体类,它与抽象的Commentable类有M:1的关系。

我希望在Comment 中存储一个鉴别器列,它可以区分它所指的哪个具体类型的Commentable,并在我的查询中使用CASE:

@NamedQuery(name = "Comments.withItemTitle",
            query = "select c.commentBody, " +
                    "case " +
                    "when n.targetType = 'video' THEN (select v.title from Video v where v.id = c.target.id) " +
                    "when n.targetType = 'message' THEN (select m.title from Message m where m.id = n.target.id) " +
                    "when n.targetType = 'blog' THEN (select b.title from Blog b where b.id = n.target.id) " +
                    "end " +
                    "from Comment c")

但是hibernate会抛出有关嵌套选择的错误,说它无法确定它的类型。 This appears to be legal in postgre - 如果Hibernate以这种方式支持嵌套的SELECT表达式,它不会解决问题吗?

我的下一个想法是对每个评论进行去标准化并存储相关的commentable.title,但出于显而易见的原因,我对此犹豫不决。出于这个问题的目的,我无法改变Commentable的继承结构。

有没有其他方法可以执行此查询而不强制hibernate与UNION一起使用每个表?

1 个答案:

答案 0 :(得分:0)

我认为问题在于JPQL没有case语句。您需要更改代码以使用@NamedNativeQuery并在SQL而不是JPQL中重写查询。