Вопрос

Чтобы сделать это покороче: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 не включать никаких ограничений в свой запрос, что означает, что он получил все списки записей.Что касается ошибки гибернации, о которой сообщалось, я вижу, что она исправлена, но мне совершенно не удалось загрузить патч.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top