Короче: спящий режим не поддерживает проекции и запросы по примеру? Я нашел этот пост:
Код такой:
User usr = new User();
usr.setCity = 'TEST';
getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Example.create(usr))
Как сказал другой плакат, сгенерированный sql продолжает иметь класс where, ссылающийся только на y0_ =? вместо this_.city.
Я уже пробовал несколько подходов и искал систему отслеживания проблем, но ничего не нашел об этом.
Я даже пробовал использовать псевдоним Projection и Transformers, но это не работает:
User usr = new User();
usr.setCity = 'TEST';
getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Example.create(usr)).setResultTransformer(Transformers.aliasToBean(User.class));
Кто-нибудь использовал прогнозы и запросы на примере?
Я добавил решение, которое включает SQL, сгенерированный, когда у меня была аналогичная проблема.




Могу я увидеть ваш класс пользователя? Это просто использование ограничений ниже. Я не понимаю, почему ограничения действительно будут отличаться от примеров (хотя я думаю, что пустые поля по умолчанию игнорируются в примерах).
getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Restrictions.eq("city", "TEST")))
.setResultTransformer(Transformers.aliasToBean(User.class))
.list();
Я никогда не использовал alaistToBean, но только что читал об этом. Вы также можете просто просмотреть результаты.
List<Object> rows = criteria.list();
for(Object r: rows){
Object[] row = (Object[]) r;
Type t = ((<Type>) row[0]);
}
Если вам нужно, вы можете вручную заполнить User таким образом.
Трудно разобраться в проблеме без дополнительной информации для диагностики.
Проблема, кажется, возникает, когда у вас есть псевдоним с тем же именем, что и у свойства objects. Кажется, что Hibernate подбирает псевдоним и использует его в sql. Я нашел эти задокументированные здесь и здесь, и я считаю, что это ошибка в Hibernate, хотя я не уверен, что команда Hibernate согласна.
В любом случае, я нашел простое решение, которое работает в моем случае. Ваш пробег может отличаться. Подробности ниже, я попытался упростить код для этого образца, поэтому прошу прощения за любые ошибки или опечатки:
Criteria criteria = session.createCriteria(MyClass.class)
.setProjection(Projections.projectionList()
.add(Projections.property("sectionHeader"), "sectionHeader")
.add(Projections.property("subSectionHeader"), "subSectionHeader")
.add(Projections.property("sectionNumber"), "sectionNumber"))
.add(Restrictions.ilike("sectionHeader", sectionHeaderVar)) // <- Problem!
.setResultTransformer(Transformers.aliasToBean(MyDTO.class));
Произведет этот sql:
select
this_.SECTION_HEADER as y1_,
this_.SUB_SECTION_HEADER as y2_,
this_.SECTION_NUMBER as y3_,
from
MY_TABLE this_
where
( lower(y1_) like ? )
Что вызывало ошибку: java.sql.SQLException: ORA-00904: "Y1_": недопустимый идентификатор
Но когда я изменил свое ограничение на использование «this», вот так:
Criteria criteria = session.createCriteria(MyClass.class)
.setProjection(Projections.projectionList()
.add(Projections.property("sectionHeader"), "sectionHeader")
.add(Projections.property("subSectionHeader"), "subSectionHeader")
.add(Projections.property("sectionNumber"), "sectionNumber"))
.add(Restrictions.ilike("this.sectionHeader", sectionHeaderVar)) // <- Problem Solved!
.setResultTransformer(Transformers.aliasToBean(MyDTO.class));
Он создал следующий sql, и моя проблема была решена.
select
this_.SECTION_HEADER as y1_,
this_.SUB_SECTION_HEADER as y2_,
this_.SECTION_NUMBER as y3_,
from
MY_TABLE this_
where
( lower(this_.SECTION_HEADER) like ? )
Вот и все! Довольно простое решение болезненной проблемы. Я не знаю, как это исправление отразится на проблеме запроса на примере, но оно может приблизить вас.
Пол: Я рад, что это помогло. Я был удивлен, что этот ответ оставался незамеченным до тех пор, пока он казался большой проблемой, а это решение не было интуитивно понятным и не задокументировано.
Связанная ошибка Hibernate - hibernate.onjira.com/browse/HHH-817 и отмечена как исправленная в версии 3.6.0Beta4 Hibernate.
@RyanCook Привет! Это решение работает, но мне было интересно, есть ли обходной путь с примерами, поскольку у нас может быть до 10 фильтров (т.е. 10 ограничений), и нам нужно будет проверять для каждого, является ли поле нулевым или пустым).
Я убил 2 дня в этом выпуске. Ключевое слово this решает эту проблему очень хорошо. Большое спасибо @Ryan
У меня другая проблема с Order.asc("sectionHeader"). Когда я использую то же свойство в Projection, Restriction & Order. !!
У меня аналогичная проблема. Я использую запрос по примеру и хочу отсортировать результаты по настраиваемому полю. В SQL я бы сделал что-то вроде:
select pageNo, abs(pageNo - 434) as diff
from relA
where year = 2009
order by diff
Он отлично работает без предложения по порядку. Что у меня есть
Criteria crit = getSession().createCriteria(Entity.class);
crit.add(exampleObject);
ProjectionList pl = Projections.projectionList();
pl.add( Projections.property("id") );
pl.add(Projections.sqlProjection("abs(`pageNo`-"+pageNo+") as diff", new String[] {"diff"}, types ));
crit.setProjection(pl);
Но когда я добавляю
crit.addOrder(Order.asc("diff"));
Я получаю исключение org.hibernate.QueryException: не удалось разрешить свойство: diff. Обходной путь с это тоже не работает.
PS: поскольку я не смог найти какой-либо подробной документации по использованию QBE для Hibernate, все вышеперечисленное - в основном метод проб и ошибок.
Настоящая проблема здесь в том, что в спящем режиме есть ошибка, когда он использует псевдонимы списка выбора в предложении where:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-817
На всякий случай, если кто-то приземлится здесь в поисках ответов, посмотрите билет. На исправление потребовалось 5 лет, но теоретически это будет в одном из следующих выпусков, и тогда я подозреваю, что ваша проблема исчезнет.
Я так не думаю, я могу найти слово «это». заставляет спящий режим не включать никаких ограничений в свой запрос, что означает, что он получил все списки записей. Что касается ошибки гибернации, о которой сообщалось, я вижу, что она исправлена, но мне полностью не удалось загрузить патч.
ProjectionList pl = Projections.projectionList();
pl.add(Projections.property("id"));
pl.add(Projections.sqlProjection("abs(`pageNo`-" + pageNo + ") as diff", new String[] {"diff"}, types ), diff); ---- solution
crit.addOrder(Order.asc("diff"));
crit.setProjection(pl);
добавить псевдоним после sqlProjection, который будет использоваться при заказе
вы могли бы показать полностью сгенерированный sql?