Спящий запрос по примерам и прогнозам
Чтобы сделать его коротким: hibernate не поддерживает прогнозы и запрос по примеру? Я нашел этот пост:
Код выглядит так:
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));
Кто-нибудь использовал прогнозы и запрос на примере?
Ответы
Ответ 1
Могу ли я увидеть ваш пользовательский класс? Это просто использует ограничения ниже. Я не понимаю, почему ограничения действительно будут отличаться от примеров (я думаю, что пустые поля по умолчанию игнорируются в примерах).
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 таким образом.
Своеобразное затруднение для изучения проблемы без дополнительной информации для диагностики проблемы.
Ответ 2
Проблема возникает, когда у вас есть псевдоним с тем же именем, что и свойство объектов. 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 ? )
Вот, это! Довольно простая проблема с болезненной проблемой. Я не знаю, как это исправление будет переводить на запрос по проблеме примера, но оно может приблизиться к вам.
Ответ 3
Настоящая проблема заключается в том, что в hibernate имеется ошибка, в которой в предложении where-where используются псевдонимы select-list:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-817
На всякий случай кто-то приземляется здесь, ища ответы, иди посмотри на билет. Потребовалось 5 лет, но теоретически это будет в одном из следующих выпусков, а затем я подозреваю, что ваша проблема исчезнет.
Ответ 4
Я столкнулся с аналогичной проблемой. Я использую Query by Example, и я хочу сортировать результаты по настраиваемому полю. В 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, все вышеизложенное относится в основном к пробному и ошибочному подходу
Ответ 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);
Ответ 6
Я действительно не думаю, что я могу найти слово "это". заставляет спящий режим не включать никаких ограничений в свой запрос, что означает, что он получил все списки записей. Об ошибке спящего режима, о котором сообщалось, я вижу, что это сообщение фиксировано, но я полностью не смог загрузить Патч.