Search code examples
springhibernateprojectionhibernate-criterianumberformatexception

hibernate projection NumberFormatException for input string


I am using Spring MVC + Hibernate

Generic Dao

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

@Controller

    @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>

All working well but when I change and use Projection in Method as the following , then it give exception

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

Changes: ProjectionList use in Method

    @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();
}

Changes in @Controller passing List [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";
}

Same 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 

}

I check the query from log file . it successfully execute

and when I remove the following line from jsp page, then there is no any exception

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

Note: ct:Options is a custom JSP tag, that just print values, nothing special

After Projection the result of query is as follow

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

and both returning the list , and I have check both of size(), the size is also same !

Update me !


Solution

  • Typically, when using a projection list of specific properties in Hibernate, you won't be able to cast the query result as an entity type, at least not in the older versions of Hibernate I'm familiar with (i.e. 3.2.x). Instead, the default return type will be a List<Object[]> (when calling Criteria#list), where each array represents a tuple of the properties you specified in the projection list. (You can tell Hibernate to change the return type by giving the Criteria a ResultTransformer, but that may cause more confusion.) So instead of expecting partially-hydrated entities of type T and calling its getter methods (via JSTL expression), expect an array of Objects and get each property value by index (based on the order of the properties in the projection list).

    Otherwise, it appears that you're passing the string values "id" and "isoCode" to your ct tag library (instead of the id and isoCode field values that you want), which I assume is expecting strings that can be parsed into numbers using something like Integer#parseInt(String), and this is causing the NumberFormatExceptions.

    If this doesn't help, can you please provide more information? Specifically:

    • What are the property names you're specifying in the projection list?
    • What object types are those properties mapped as in the entity class? Providing the full entity mapping would help.
    • Is the ct:Options a custom JSP tag? If so, can you provide the logic of the tag class?