【发布时间】:2014-11-08 01:36:21
【问题描述】:
我有以下 POJO:
@Entity(name = "member")
@Table(name = "member")
public class Member {
@Column(name = "identifier")
@Id
@GeneratedValue
private int mIdentifier;
@Column(name = "name", columnDefinition = "text")
private String mName;
@ManyToMany(mappedBy = "mMembers")
private Set<Project> mProjects = new HashSet<Project>();
public int getIdentifier() {
return mIdentifier;
}
public String getName() {
return mName;
}
public void setName(final String pName) {
mName = pName;
}
public Set<Project> getProjects() {
return mProjects;
}
public Member() {
}
}
和
@Entity(name = "project")
@Table(name = "project")
public class Project {
@Column(name = "identifier")
@Id
@GeneratedValue
private int mIdentifier;
@ManyToMany(cascade = CascadeType.ALL)
private Set<Member> mMembers = new HashSet<Member>();
public int getIdentifier() {
return mIdentifier;
}
public Set<Member> getMembers() {
return mMembers;
}
public Project() {
}
}
以下代码获取某个项目,并返回所有成员:
Project project = (Project) db.load(Project.class, 1);
System.out.println(project);
System.out.println(project.getMembers());
如何过滤项目的成员?例如,假设我只想要名称以“a”开头的成员。我当然可以做一些客户端过滤(例如使用 Guava 和 Predicate),但让 Hibernate 更改 SQL 查询更有意义。
我知道Hibernate filters,但我认为它们不是为此而设计的。我认为它们对于全局过滤更有用,而不是对特定对象的临时关系过滤。
非常欢迎指向文档、术语等。我对 Hibernate 还很陌生,很难获得这个问题的文档。
编辑
我尝试了标准。我有两个成员,“John Snow”和“Snow”。以下仍然返回两个成员。
final Criteria criteria = db.createCriteria(Project.class)
.createCriteria("mMembers")
.add(Restrictions.eq("mName", "John Snow"));
for (final Project project : (List<Project>) criteria.list()) {
System.out.println(project.getIdentifier());
for (final Member member : project.getMembers()) {
System.out.println(member.getName());
}
}
有什么想法吗?
编辑(2)
似乎执行了第二个查询,以获取所有成员。我们如何才能防止这种情况发生,并且只依赖基于标准的数据?
Hibernate:
select
this_.identifier as identifi1_1_1_,
mmembers3_.mProjects_identifier as mProject1_1_,
mmembers1_.identifier as mMembers2_2_,
mmembers1_.identifier as identifi1_0_0_,
mmembers1_.name as name2_0_0_
from
project this_
inner join
project_member mmembers3_
on this_.identifier=mmembers3_.mProjects_identifier
inner join
member mmembers1_
on mmembers3_.mMembers_identifier=mmembers1_.identifier
where
mmembers1_.name=?
1
Hibernate:
select
mmembers0_.mProjects_identifier as mProject1_1_1_,
mmembers0_.mMembers_identifier as mMembers2_2_1_,
member1_.identifier as identifi1_0_0_,
member1_.name as name2_0_0_
from
project_member mmembers0_
inner join
member member1_
on mmembers0_.mMembers_identifier=member1_.identifier
where
mmembers0_.mProjects_identifier=?
Snow
John Snow
编辑 (3)
看上面的第一个查询,这并不是我想要的。本质上,我想要两个查询:
- 第一个查询获取某个项目。此查询从表 project 中选择。
- 第二个查询获取所有成员,匹配特定条件。当调用
getMembers()时,该查询会延迟执行。此查询从表 member 中选择并加入 project_member。
我不想将其合并到一个查询中并从表 project_member 中进行选择,因为这会导致大量的解析开销。我不想以笛卡尔积结束。
这可能吗?
【问题讨论】:
-
好吧,标准或 hql 怎么样?
标签: java hibernate runtime filtering relation