У меня есть следующие объекты 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, но я не думаю, что они предназначены для этого. Я думаю, что они более полезны для глобальной фильтрации, а не для фильтрации ad-hoc-отношений одного конкретного объекта.
Указатели на документацию, терминологию и т. Д. Очень приветствуются. Я довольно новичок в Hibernate, и мне сложно получить документацию по этому вопросу.
редактировать
Я попытался с критериями. У меня есть два члена: «Джон Сноу» и «Снег». Следующий элемент возвращает оба члена.
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)
Глядя на первый запрос выше, это на самом деле не хочу я хочу. В сущности, я хочу два запроса:
- Первые запросы выбирают определенный проект. Этот запрос выбирает из таблицы проект.
- Второй запрос извлекает все элементы, соответствующие определенным критериям. Этот запрос выполняется лениво, когда вызывается
getMembers()
. Этот запрос выбирает из таблицы участник и присоединяется к project_member.
Я не хочу, чтобы объединить это в один запрос и выбрать из таблицы project_member, так как это привело бы к большому разбору накладных расходов. Я не хочу в конечном итоге декартовой продукции.
Возможно ли это?
Ну, как насчет критериев или hql? – kamil
http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#querycriteria - Я изучу это! Благодаря! –