Запрос гибернации По Примеру и прогнозам
-
01-07-2019 - |
Вопрос
Чтобы сделать это покороче: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_= ?вместо этого_.city.
Я уже перепробовал несколько подходов и поискал в системе отслеживания проблем, но ничего не нашел по этому поводу.
Я даже пытался использовать псевдоним проекции и Трансформаторы, но это не работает:
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));
Кто-нибудь использовал прогнозы и запрос на примере?
Решение
Могу я посмотреть ваш класс пользователя?Это просто использование приведенных ниже ограничений.Я не понимаю, почему ограничения действительно будут чем-то отличаться от примеров (хотя я думаю, что нулевые поля по умолчанию игнорируются в примерах).
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 (исключение java.sql:ORA-00904:"Y1_":недопустимый идентификатор
Но, когда я изменил свое ограничение на использование "этого", вот так:
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 ? )
Вот и все!Довольно простое решение болезненной проблемы.Я не знаю, как это исправление отразится на задаче query by example, но это может приблизить вас.
Реальная проблема здесь заключается в том, что в hibernate есть ошибка, из-за которой он использует псевдонимы списка выбора в предложении where:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-817
На всякий случай, если кто-то приземлится здесь в поисках ответов, загляните в билет.На исправление ушло 5 лет, но теоретически это будет в одном из следующих выпусков, и тогда, я подозреваю, ваша проблема исчезнет.
Я столкнулся с аналогичной проблемой.Я использую запрос по примеру и хочу отсортировать результаты по пользовательскому полю.В SQL я бы сделал что-то вроде:
select pageNo, abs(pageNo - 434) as diff
from relA
where year = 2009
order by diff
Это прекрасно работает без предложения order-by-.То, что у меня есть, это
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.спящий режим.Исключение QueryException:не удалось разрешить свойство:разница исключение.Обходной путь с помощью это тоже не работает.
PS:поскольку я не смог найти какой-либо подробной документации по использованию QBE для гибернации, все вышеперечисленное в основном основано на методе проб и ошибок
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);
Я действительно так не думаю, что я могу найти слово "это". заставляет hibernate не включать никаких ограничений в свой запрос, что означает, что он получил все списки записей.Что касается ошибки гибернации, о которой сообщалось, я вижу, что она исправлена, но мне совершенно не удалось загрузить патч.