Запрос 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));

Кто-нибудь использовал прогнозы и запросы на примере?

вы могли бы показать полностью сгенерированный sql?

Arthur Thomas 17.09.2008 19:56

Я добавил решение, которое включает SQL, сгенерированный, когда у меня была аналогичная проблема.

Ryan Cook 06.06.2009 22:45
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
23
2
127 497
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

Могу я увидеть ваш класс пользователя? Это просто использование ограничений ниже. Я не понимаю, почему ограничения действительно будут отличаться от примеров (хотя я думаю, что пустые поля по умолчанию игнорируются в примерах).

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 ? ) 

Вот и все! Довольно простое решение болезненной проблемы. Я не знаю, как это исправление отразится на проблеме запроса на примере, но оно может приблизить вас.

Пол: Я рад, что это помогло. Я был удивлен, что этот ответ оставался незамеченным до тех пор, пока он казался большой проблемой, а это решение не было интуитивно понятным и не задокументировано.

Ryan Cook 09.10.2009 19:18

Связанная ошибка Hibernate - hibernate.onjira.com/browse/HHH-817 и отмечена как исправленная в версии 3.6.0Beta4 Hibernate.

FGreg 12.12.2012 00:10

@RyanCook Привет! Это решение работает, но мне было интересно, есть ли обходной путь с примерами, поскольку у нас может быть до 10 фильтров (т.е. 10 ограничений), и нам нужно будет проверять для каждого, является ли поле нулевым или пустым).

Tarek 19.11.2013 17:10

Я убил 2 дня в этом выпуске. Ключевое слово this решает эту проблему очень хорошо. Большое спасибо @Ryan

Mr. Mak 31.10.2017 16:16

У меня другая проблема с Order.asc("sectionHeader"). Когда я использую то же свойство в Projection, Restriction & Order. !!

Mr. Mak 31.10.2017 16:18

У меня аналогичная проблема. Я использую запрос по примеру и хочу отсортировать результаты по настраиваемому полю. В 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, который будет использоваться при заказе

singh 13.02.2016 18:22

Другие вопросы по теме