1

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 !

1 Answer 1

2

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?
Sign up to request clarification or add additional context in comments.

8 Comments

I have edited the post ! may it clear to you. why in second case , there is an exception. but the first case working fine. actually projection should not change the structure of returning... If structure change how control this in spring MVC ? I can not understand the reason of exception
Again Edit : Also Provide GenCurrencyModel Class
Can you add the following lines to your controller method and post the output? 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());
Without Projection: First element of currencyList has type: class com.soft.erp.gen.model.GenCurrencyModel Id value of first element in currencyList is: 1 but with projection nested exception is java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.soft.erp.gen.model.GenCurrencyModel]
So the one with the projection is returning List<Object[]>. You could possibly work around this manually in the dao with code like: List<Object[]> l = (List<Object[]>) criteria.list(); List<GenCurrencyModel> c = new ArrayList<GenCurrencyModel>(); for(Object[] tuple : l) { ` GenCurrencyModel m = new GenCurrencyModel();`
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.