Search code examples
javahibernatecriteria-apiprojection

Hibernate with ProjectionList error: cannot be cast to [Ljava.lang.Object;


I have problem with returnig list of my objects. I am working with entity class which has @EmbeddedId as you can see in my code below, ther are two lines with similar text: id.*.

Criteria cr = createCriteria(true);
cr.add(Restrictions.eq("id.qwerty", "QWERTY"));

ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.property("id.qwerty"));
projectionList.add(Projections.property("text"));
projectionList.add(Projections.property("id.property"));
cr.setProjection(projectionList);
cr.setResultTransformer(Transformers.aliasToBean(My.class));

List<My> myList = (List<My>) cr.list();

return myList;

At line List<My> messagesList = (List<My>) cr.list(); the below error has occured.

java.lang.ClassCastException: my.package.dao.domain.My cannot be cast to [Ljava.lang.Object;
at org.hibernate.cache.StandardQueryCache.put(StandardQueryCache.java:104)
at org.hibernate.loader.Loader.putResultInQueryCache(Loader.java:2274)
at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2206)
at org.hibernate.loader.Loader.list(Loader.java:2164)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1706)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)

How can I defined Criteria or ProjectionList in this case?

EDIT

@javax.persistence.Entity
@Table(name = "my_table")
public class My extends MyEntity<MyPK> {

   @EmbeddedId
   private MyPK id;

   @Column(name = "text", nullable = false)
   protected String text;

   @ManyToOne
   @JoinColumn(name = "property", nullable = false, insertable = false, updatable = false)
   protected Option option;

   @Override
   public MyPK getId() {
       return id;
   }

   @Override
   public void setId(MyPK id) {
       this.id = id;
   }

   //getters and setter
   //equlas and hashCode
}

And MyPK class:

@Embeddable
public class MyPK implements Serializable {

   @Column(name = "qwerty")
   protected String qwerty;

   @Column(name = "property")
   protected String property;

   //constructors, getters and setters
}

Solution

  • If you are using setProjection() on your Criteria, then the list() method will return a type of List<Object> or List<Object[]>, depending on how many properties you have added to your projection list.

    This means you will have to do your own creation of My instances.

        List<My> myList = new ArrayList<My>();
        for (Object[] row : cr.list()) {
             My m = new My();
             m.setQwerty((String) row[0]);
             // set the rest of the properties
             myList.add(m);
        }
    

    I believe the ClassCastException you are seeing is because the list() method is returning Object instances but you have explicitly asked for My instances by setting the ResultTransformer

    Similar question here, answered by JBNizet