自定义Hibernate多对一连接子句



是否有可能调整hibernate在检索给定实体的关联时执行的查询?更具体地说,我想在连接子句中添加一个额外的条件,以满足我正在使用的遗留数据库中的设计缺陷。

我面临的问题如下。表b的主键由两个字段组成,一个类别id和一个类别value_id。然而,在表A中,我只存储了value_id,并且假设类别id是硬编码的:

@Entity
@Table(name = "table_a")
public class A {
   @ManyToOne
   @JoinColumn(name = "b_id")
   private B b;
}
@Entity
@Table(name = "table_b")
public class B {
   @Id
   private int id;
}

当查询A的实例时,hibernate生成以下连接子句:

SELECT *
FROM table_a a LEFT OUTER JOIN table_b b
  ON a_.b_id = b_.value_id

而我要求它执行的查询是:

SELECT *
FROM table_a a LEFT OUTER JOIN table_b b
  ON a_.b_id = b_.value_id
 AND b.category_id = 2

我知道我可以使用视图来解决这个问题,但是这需要我创建大约70个视图,如果可能的话,我想避免。

我解决了这个问题。这不是最漂亮的解决方案,但却是唯一可行的。

基本上我要做的是:

  1. 模拟a类的嵌入ID
  2. 与公式
  3. 比较,使用实键列和categoryId在a -> B之间建立连接

:

Obs:我没有测试这段代码,只是改编自我的。

@Entity
@Table(name = "table_a")
public class A {
   @ManyToOne(fetch=FetchType.LAZY)
   @JoinColumnsOrFormulas(value={
        @JoinColumnOrFormula(column=
                @JoinColumn(name="B_ID", referencedColumnName="B_ID")),
        @JoinColumnOrFormula(formula=
                @JoinFormula(referencedColumnName="CATEGORY_ID", 
                        value = "(SELECT 2 from DUAL)"))}) //I am using Oracle
   @JoinColumn(name = "b_id")
   private B b;
}
@Entity
@Table(name = "table_b")
class B {
   @Id
   private BId id;
}
@Embeddable
class BId{
    private int id;
    private Integer categoryId;
}

你可以这样做:

@OneToMany(mappedBy = "b")
@Cascade(CascadeType.ALL)
private List<A> aList = new ArrayList<A>(0);

class B上获得连接和命名查询以获得category_id(也在class B中)

@NamedQueries({
@NamedQuery(name = "B.findByCategoryId", query = "SELECT b FROM B b WHERE b.Id = :categoryId")
})

最新更新