Использование Restrictions.disjunction через ассоциацию @JoinTable - PullRequest
2 голосов
/ 18 февраля 2010

Это похоже, но не идентично:

Запрос критериев гибернации для различных свойств различных объектов

У меня есть запись SpecChange, в которой есть набор ResponsibleIndividuals; это пользовательские записи, отображаемые с помощью ассоциации спящих таблиц. Я хочу создать запрос Criteria для SpecChange, в котором указан пользователь в своем наборе ResponsibleIndividuals, ИЛИ некоторые другие условия в SpecChange.

Я опущу большую часть кода для ясности, просто показывая соответствующие аннотации:

@Entity
class SpecChange {
 @OneToMany
 @JoinTable(name = "ri_id_spec_change_id", joinColumns = { @JoinColumn(name = "spec_change_id") }, inverseJoinColumns = @JoinColumn(name = "ri_id"))
 @AccessType("field")
 public SortedSet<User> getResponsibleIndividuals() { ... }

 @Id
 @Column(name = "unique_id")
 @AccessType("field")
 public String getId() { ... }
}

@Entity
class User { ... }
//user does not have a SpecChange association (the association is one-way)

Что я хочу сделать:

User currentUser = ...;
Criteria criteria = session.createCriteria(SpecChange.class);
...
criteria.add(Restrictions.disjunction()
 .add(Restrictions.eq("responsibleIndividuals", currentUser))
 .add(...)
);
criteria.list();

Это порождает неправильный SQL:

select ... from MY_DB.dbo.spec_change this_ ... where ... (this_.unique_id=?)

... и не удается:

java.sql.SQLException: Parameter #2 has not been set.

(я пропустил еще одно условие в предложении where, поэтому показывается параметр # 2. Я уверен, что currentUser не равен нулю.)

Обратите внимание, что ограничение ссылается на неправильную таблицу: this_, то есть SpecChange, а не таблица User

Я попробовал дюжину разных трюков, чтобы заставить его работать правильно (включая создание псевдонима, как упоминалось в предыдущем посте выше). Если есть способ сделать это с использованием псевдонима, я не смог определить его.

Следующее работает (но не выполняет то, что мне нужно, поскольку я не могу использовать его в дизъюнкции): criteria.createCriteria ( "responsibleIndividuals") добавить (Restrictions.idEq (currentUser.getId ()));.

[ Редактировать : обходное решение для ошибки в Hibernate с использованием HQL]

select sc 
from com.mycompany.SpecChange sc
left join fetch sc.responsibleIndividuals as scResponsibleIndividuals
where scResponsibleIndividuals = :p1 or sc.updUser = :p1
order by sc.updDate desc

Это не будет работать без псевдонима "scResponsibleIndividuals"

...