Спящий список проекций

Мне нужно было получить только несколько значений столбца из таблицы. Поэтому я использовал Projections для достижения этой цели. Код работает, но я не думаю, что он эффективен.

Моя проблема заключалась в том, что я использовал ProjectionsList, а затем установил в списке критерии.list значение ArrayList - объект бюллетеня имеет значение null. Я не уверен, как объяснить это лучше. Поэтому я помещу код, а затем, пожалуйста, прочитайте ниже:

 List<Bulletin> list = new ArrayList<Bulletin>();
 BulletinList bulletinList = null;

 Criteria criteria = null;

 criteria = this.getSession().createCriteria(Bulletin.class)
            .setProjection(Projections.projectionList()
            .add(Projections.property(bulletinIdAttr))
            .add(Projections.property(docNameAttr))   
            .add(Projections.property(docTypeCodeAttr))
            );        
    criteria.addOrder(Order.desc(createdTimeAttr));

    List<Object> rows = criteria.list();
    for (Object r : rows) {
        Object[] row = (Object[]) r;
        Bulletin bull = new Bulletin();
        bull.setBulletinId((Long) row[0]);
        bull.setDocumentName((String) row[1]);
        bull.setDocumentTypeCode((String) row[2]);
        list.add(bull);
      }

    bulletinList = new BulletinList();
    bulletinList.setBulletins(list);

    return bulletinList;

Мне просто нужно установить в критерии.list значение BulletinList (класс, который содержит список объектов Bulletin). Но когда я использую проекции, объект бюллетеня имеет значение null.

Я также читал другую ветку для использования

setResultTransformer(Transformers.aliasToBean

Но это тоже не работает. Так может кто-нибудь помочь в этом, как сделать код лучше.

Спасибо

резкий


person Harry    schedule 15.06.2012    source источник


Ответы (3)


  1. Projections.property() принимает строку в качестве аргумента. В предоставленном вами коде значение этой строки должно быть именем члена класса Bulletin. Предположительно, bulletinIdAttr, например, является строкой с таким значением, иначе вы получите ошибки времени выполнения.
  2. Когда вы вызываете setProjection в экземпляре Criteria, вы неявно устанавливаете ResultTransformer в PROJECTIONS, и это то, что вы хотите. Не нужно звонить setResultTransformer самостоятельно. Я бы немного упростил рутину вот так

    List<Object[]> rows = criteria.list();
    for (Object[] row : rows) {
       Bulletin bull = new Bulletin();
       bull.setBulletinId((Long) row[0]);
       bull.setDocumentName((String) row[1]);
       bull.setDocumentTypeCode((String) row[2]);
       list.add(bull);
    }
    

Но это не должно иметь никакого значения для ваших результатов. Вы проверили, что rows пусто?

person carbontax    schedule 16.06.2012
comment
Большое спасибо за ваш ответ. Как я уже сказал, мой код выше работает, как и ожидалось, но просто хотел узнать, эффективен ли он. И да, Projections.property() принимает String в качестве аргумента. Когда я попытался использовать ваш блок кода, я получаю эту ошибку: - person Harry; 18.06.2012
comment
Несоответствие типов: невозможно преобразовать тип элемента Object в Object[] в строке для (Object[] row : rows). Что мне здесь не хватает? Пожалуйста, дайте знать. - person Harry; 18.06.2012
comment
Извините, Хариш, мой первоначальный ответ был отформатирован неправильно, что сделало объявление строк неправильным. Это должно работать так, как сейчас. - person carbontax; 18.06.2012
comment
Это прекрасно работает. Большое спасибо. Но можете ли вы сообщить diff. использования List‹Object[]› vs List‹Object› и почему это лучше. - person Harry; 19.06.2012
comment
Вероятно, это не имеет большого значения после компиляции. Но код становится яснее, когда вы приводите результирующий набор один раз, а не дважды. (Один раз как объект, а затем один раз в строке как объект []). - person carbontax; 19.06.2012

Ты можешь использовать

 criteria = this.getSession().createCriteria(Bulletin.class)
            .setProjection(Projections.projectionList()
            .add(Projections.property(bulletinIdAttr),"bulletinIdAttr")
            .add(Projections.property(docNameAttr),"docNameAttr")   
            .add(Projections.property(docTypeCodeAttr),"docTypeCodeAttr")
            );        
criteria.addOrder(Order.desc(createdTimeAttr));
criteria.setResultTransformer(new AliasToBeanResultTransformer(Bulletin.class));
List<Bulletin> bulletinList = criteria.list();

Здесь критерии.setResultTransformer(новый AliasToBeanResultTransformer(Bulletin.class)) преобразует ваш результат в желаемый класс POJO, но убедитесь, что ваш класс POJO (в вашем случае Bulletin.class) должен иметь соответствующие установщики для установки значений свойств.

Теперь критерии.list() будет возвращать класс POJO List of Bulletin вместо Object.

person Shiva Agrawal    schedule 07.04.2014
comment
Больше не на этом проекте. Но большое спасибо за ваши усилия, хотя это старая тема. - person Harry; 17.04.2014
comment
эта проблема застряла у меня много дней, я не могу получить все сведения о свойствах с помощью Projections.projectionList(), но теперь я выполнил свой проект, использованный таким образом, большое спасибо, сэр @Shiva Agrawal - person Vasantha Raj; 03.08.2016

Если вы хотите выполнить повторный поиск по тем же критериям, вам необходимо изменить или удалить проекцию. Например, если вы сначала ищете число:

criteria.setProjection(Projections.rowCount());
Integer count = criteria.list().get(0);

а затем хотите получить все объекты:

criteria.setProjection(null);
List<Object> returnedObjects = criteria.list();
person krystine.e    schedule 23.03.2016