我有两个表之间的父/子关系,以及我的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
属性中)。
提前感谢任何建议。
答案 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。