hibernate проекция NumberFormatException для входной строки

Я использую Spring MVC + Hibernate

Общий Дао

// getAll
@SuppressWarnings("unchecked")
public <T> List<T> getAll(Class<T> entityClass) throws DataAccessException {
    Criteria criteria = sessionFactory.getCurrentSession().createCriteria(entityClass);
    return criteria.list();
}

@Контроллер

    @RequestMapping(value = "/genCompanyInfoUpdate", method = RequestMethod.POST)
public String genCompanyInfoUpdate(Model model) {

    List<GenCountryModel> countryList=pt.getAll(GenCountryModel.class);
    List<GenCurrencyModel> currencyList=pt.getAll(GenCurrencyModel.class);

    GenCompanyInfoModel companyInfo=pt.getById(GenCompanyInfoModel.class, 1);

    model.addAttribute("countryList", countryList);
    model.addAttribute("currencyList", currencyList);
    model.addAttribute("companyInfo", companyInfo);

    return "gen/genCompanyInfoUpdate";
}

JSP

<c:if test="${not empty currencyList}">
    <c:forEach items="${currencyList}" var="get" varStatus="counter">
    <ct:Options setValue="${get.id}" setName="${get.isoCode}" selected="${companyInfo.genCurrencyModel.id}" setState="1" />
</c:forEach>
</c:if>

Все работает хорошо, но когда я меняю и использую проекцию в методе следующим образом, это дает исключение

java.lang.numberformatexception for input string id 
java.lang.numberformatexception for input string isoCode

Изменения: использование ProjectionList в методе

    @SuppressWarnings("unchecked")
public <T> List<T> getAll(Class<T> entityClass, String[] nameList) throws DataAccessException {
    Criteria criteria = sessionFactory.getCurrentSession().createCriteria(entityClass);

ProjectionList pl = Projections.projectionList();

    for (int i=0; i<nameList.length; i++) {
        pl.add(Projections.property(nameList[i].toString()));   
    }

    criteria.setProjection(pl);

    return criteria.list();
}

Изменения в списке передачи @Controller [GenCurrencyModel]

    @RequestMapping(value = "/genCompanyInfoUpdate", method = RequestMethod.POST)
public String genCompanyInfoUpdate(Model model) {

    String []list={"id","isoCode"};

    List<GenCountryModel> countryList=pt.getAll(GenCountryModel.class);
    List<GenCurrencyModel> currencyList=pt.getAll(GenCurrencyModel.class,list);

    GenCompanyInfoModel companyInfo=pt.getById(GenCompanyInfoModel.class, 1);

    model.addAttribute("countryList", countryList);
    model.addAttribute("currencyList", currencyList);
    model.addAttribute("companyInfo", companyInfo);

    return "gen/genCompanyInfoUpdate";
}

Тот же JSP

<c:if test="${not empty currencyList}">
    <c:forEach items="${currencyList}" var="get" varStatus="counter">
    <ct:Options setValue="${get.id}" setName="${get.isoCode}" selected="${companyInfo.genCurrencyModel.id}" setState="1" />
</c:forEach>
</c:if>

GenCurrencyModel

public class GenCurrencyModel implements Serializable{

private static final long serialVersionUID = 1L;


@Id
@Column(name = "CURRENCYID")
@GeneratedValue
private long id;


@Column(name = "CODE")
private String currencyCode;

@Column(name = "DESCRIPTION")
private String currencyDesc;

@Column(name = "ISACTIVE")
private int isActive;

@Column(name = "MADELETE")
private int markAsDelete;

@Column(name = "ISOCODE")
private String isoCode;

@Column(name = "CURRENCYUNIT")
private String currencyUnit;

@Column(name = "CONNECTOR")
private String connector;

@Column(name = "SUBUNIT")
private String subUnit;

@Column(name = "RECENTUSERID")
private long recentUserId;

@Column(name = "RECENTUSERIP")
private String recentUserIp;

@Column(name = "DATETIME")
private Date dateTime;

@Column(name = "ISUPDATED")
private int isUpdated;

private GenCompanyInfoModel genCompanyInfoModel;


public GenCurrencyModel() {
    super();
}

//Getter Setter 

}

Я проверяю запрос из файла журнала. он успешно выполняется

и когда я удаляю следующую строку со страницы jsp, никаких исключений не возникает

<ct:Options setValue="${get.id}" setName="${get.isoCode}" 

Примечание. ct:Options — это специальный тег JSP, который просто печатает значения, ничего особенного

После проекции результат запроса выглядит следующим образом

Hibernate: select this_.CURRENCYID as y0_, this_.ISOCODE as y1_ from GENCURRENCY this_

и оба возвращают список, и я проверяю оба size(), размер тоже одинаков!

Обнови меня!


person Shahid Ghafoor    schedule 05.06.2013    source источник


Ответы (1)


Как правило, при использовании проекционного списка определенных свойств в Hibernate вы не сможете преобразовать результат запроса в тип объекта, по крайней мере, в более старых версиях Hibernate, с которыми я знаком (например, 3.2.x). Вместо этого возвращаемым типом по умолчанию будет List<Object[]> (при вызове Criteria#list), где каждый массив представляет кортеж свойств, указанных вами в списке проекций. (Вы можете указать Hibernate изменить тип возвращаемого значения, указав Criteria на ResultTransformer, но это может привести к еще большей путанице.) Таким образом, вместо того, чтобы ожидать частично гидратированные объекты типа T и вызывать его методы получения (через выражение JSTL), ожидайте массив из Objects и получить значение каждого свойства по индексу (в зависимости от порядка свойств в списке проекций).

В противном случае кажется, что вы передаете строковые значения "id" и "isoCode" в свою библиотеку тегов ct (вместо значений полей id и isoCode, которые вы хотите), что, я полагаю, ожидает строки, которые можно разобрать на числа, используя что-то вроде Integer#parseInt(String) , и это вызывает ошибку NumberFormatExceptions.

Если это не поможет, не могли бы вы предоставить дополнительную информацию? Конкретно:

  • Какие имена свойств вы указываете в списке проекций?
  • Какие типы объектов отображают эти свойства, как в классе сущностей? Предоставление полного сопоставления сущностей поможет.
  • Является ли ct:Options пользовательским тегом JSP? Если да, можете ли вы предоставить логику класса тега?
person superEb    schedule 05.06.2013
comment
Я отредактировал пост! пусть тебе будет ясно. почему во втором случае есть исключение. но первый случай работает нормально. на самом деле проекция не должна изменять структуру возврата... Если структура меняется, как контролировать это в spring MVC? не могу понять причину исключения - person Shahid Ghafoor; 05.06.2013
comment
Снова изменить: также предоставить класс GenCurrencyModel - person Shahid Ghafoor; 05.06.2013
comment
Можете ли вы добавить следующие строки в свой метод контроллера и опубликовать вывод? System.out.println("First element of currencyList has type: "+currencyList.get(0).getClass()); System.out.println("Id value of first element in currencyList is: "+((GenCurrencyModel)currencyList.get(0)).getId()); - person superEb; 05.06.2013
comment
Без проекции: First element of currencyList has type: class com.soft.erp.gen.model.GenCurrencyModel Id value of first element in currencyList is: 1, но с проекцией nested exception is java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.soft.erp.gen.model.GenCurrencyModel] - person Shahid Ghafoor; 05.06.2013
comment
Итак, тот, у кого есть проекция, возвращает List<Object[]>. Возможно, вы могли бы обойти это вручную в dao с помощью кода вроде: List<Object[]> l = (List<Object[]>) criteria.list(); List<GenCurrencyModel> c = new ArrayList<GenCurrencyModel>(); for(Object[] tuple : l) { `GenCurrencyModel m = new GenCurrencyModel();` - person superEb; 05.06.2013
comment
Извините, заканчивая предыдущий комментарий: вы можете попробовать использовать ResultTransformer или, возможно, обойти это вручную в dao с кодом вроде: 0]).longValue());` ` m.setIsoCode((String) tuple[1]);` ` c.add(m);` } return c; Но это, очевидно, не является динамическим и может иметь последствия для объектов объектов если сеанс гибернации остается открытым. - person superEb; 05.06.2013
comment
почему это ведет себя так! потому что criteria.setProjection(pl) в основном возвращает критерии, результат которых должен быть таким же, как criteria use without projection. Спасибо за указание на первопричину! поразительнй - person Shahid Ghafoor; 05.06.2013
comment
давайте продолжим это обсуждение в чате - person Shahid Ghafoor; 05.06.2013