Привет! Я пытаюсь перевести мою старую инфраструктуру запросов на основе SQL на Hibernate Criteria, в настоящее время я использую Hibernate версии 3.2.и mysql v 5.0.54
Мой вопрос заключается в том, что я хочу написать критерий, который возвращает все Бины, которые не имеют значение в отдельном наборе элементов.
Сводка файла конфигурации hibernate для bean-компонента:
<hibernate-mapping package="com.mydomain.beans">
<typedef class="com.mydomain.dao.util.HibernateAgentOptionType" name="agent-option"/>
<class name="Agent" table="agent">
...
<set name="agentOptions" table="agent_options" fetch="join" lazy="true">
<key column="agt_id"/>
<element column="identifier" type="agent-option"/>
</set>
</class>
</hibernate-mapping>
Файл класса выглядит примерно так:
public class Agent {
...
public Set<Option> getAgentOptions() {
return agentOptions;
}
public void setAgentOptions(Set<Option> _agentOptions) {
this.agentOptions = _agentOptions;
}
public enum Option {
WEB_SITE_SYNDICATE ("web-site-syndicate"),
RECEIVE_PREMIUM_ENQUIRIES ("receive-premium-enquiries"),
DO_NOT_SYNDICATE_ADS_TO_THIRD_PARTIES ("do-not-syndicate-ads-to-third-parties")
}
}
Я бы хотел получить всех агентов, которые не имеют параметр "DO_NOT_SYNDICATE_ADS_TO_THIRD_PARTIES" в их agentOptions
sql, который я использовал для этого ранее, был что-то вроде:
SELECT agt.id
FROM agent agt
WHERE agt.id NOT IN (
SELECT sub_agt.id FROM agent sub_agt
JOIN agent_options AS agt_options ON agt_options.agt_id = sub_agt.id
WHERE agt_options.identifier = 'do_not_syndicate_ads_to_third_parties'
)
я пробовал это:
...
Criteria crit = getHibernateSession().createCriteria(Agent.class);
crit.addRestriction(Restriction.not(Restriction.in("agentOptions", noSyndicatedAds)));
...
Который выдает плохой sql
Я также пробовал использовать псевдонимы:
...
crit.createAlias("agentOptions", "agentOption");
crit.add(Restrictions.not(Restrictions.in("agentOption", options)));
...
Который выдает исключение:
org.hibernate.MappingException: коллекция не была ассоциацией: Agent.agentOptions
Наконец я решил попробовать грубый sql критерий:
...
crit.add(Restrictions.sqlRestriction(" {alias}.id not in " +
"(select agt_sub.id " +
"from agent agt_sub " +
"join agent_options as agent_options_sub on agent_options_sub.agt_id = agt_sub.id " +
"where agent_options_sub.identifier in (?)) ",
Agent.Option.DO_NOT_SYNDICATE_ADS_TO_THIRD_PARTIES.getIdentifier(),
new org.hibernate.type.StringType()
));
...
, который работал, но кажется немного уродливым.
Кто-нибудь знает, есть ли способ с помощью API-интерфейса std Criteria wi?без необходимости прибегать к sql.
Любая помощь или предложения будут приветствоваться.Даже если они требуют обновления до более поздней версии Hibernate.
Cheers Simon