用于过滤@OneToMany关联结果的注释

时间:2011-08-02 22:54:23

标签: java hibernate jpa jointable

我有两个表之间的父/子关系,以及我的Java类中的相应映射。表大致如下:

A (ref number, stuff varchar2(4000))
B (a_ref number, other number, foo varchar2(200))

和Java代码:

@Entity
class A {
    @Id
    @Column(name = "REF")
    private int ref;

    @OneToMany
    @JoinColumn(name = "A_REF", referencedName = "REF")
    private Set<B> bs;
}

@Entity
class B {
    @Id
    @Column(name = "A_REF")
    private int aRef;

    @Id
    @Column(name = "OTHER")
    private int other;
}

这很好用,但我想在从子表中检索的行上添加一个过滤器。生成的查询如下所示:

select a_ref, other, foo from B where a_ref = ?

我希望它是:

select a_ref, other, foo from B where a_ref = ? and other = 123

附加过滤器只是列名和硬编码值。有没有办法使用hibernate注释来做到这一点?

我查看了@JoinFormula,但是我总是要从父表中引用一个列名(在JoinFormula的name属性中)。

提前感谢任何建议。

4 个答案:

答案 0 :(得分:27)

JPA不支持它,但如果您使用hibernate作为JPA提供程序,那么您可以使用注释@FilterDef@Filter

  

Hibernate Core Reference Documentation

     

Hibernate3能够预先定义过滤条件并附加   那些类级别和集合级别的过滤器。一个过滤器   criteria允许您定义类似于的限制子句   现有的“where”属性可用于类和各种   集合元素。然而,这些过滤条件可以是   参数。然后,应用程序可以在运行时决定是否   应启用某些过滤器以及它们的参数值   应该。过滤器可以像数据库视图一样使用,但它们是   在应用程序内参数化。

例如

@Entity
public class A implements Serializable{
    @Id
    @Column(name = "REF")
    private int ref;

    @OneToMany
    @JoinColumn(name = "A_REF", referencedColumnName = "REF")   
    @Filter(name="test")
    private Set<B> bs;
}

@Entity
@FilterDef(name="test", defaultCondition="other = 123")
public class B implements Serializable{
    @Id
    @Column(name = "A_REF")
    private int aRef;

    @Id
    @Column(name = "OTHER")
    private int other;
}

Session session = entityManager.unwrap(Session.class);
session.enableFilter("test");
A a = entityManager.find(A.class, new Integer(0))
a.getb().size() //Only contains b that are equals to 123

答案 1 :(得分:2)

使用JPA 1,您可以使用提供的解决方案,但更改unwrap到getDelegate就像那样

Session session = (Session)entityManager.getDelegate();

它会起作用。

答案 2 :(得分:1)

另一种解决方案是使用Hibernate的@Where:https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#pc-where

    @OneToMany
    @JoinColumn(name = "A_REF", referencedName = "REF")
    @Where(clause = "other = 123")
    private Set<B> bs;

答案 3 :(得分:0)

如果我理解正确的问题,有一种方法可以使用javax.persistence注释(我自己在ManyToOne上使用它,并根据here定制答案):

@JoinColumns({
    @JoinColumn(name = "A_REF", referencedColumnName = "REF"),
    @JoinColumn(name = "B_TABLE_NAME.OTHER", referencedColumnName = "'123'")})
@OneToMany
private Set<B> bs;

请注意referencedColumnName中的单个引号,这是您要查找的值。

更多信息here