Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate projections with collections ArrayIndexOutOfBoundsException

Tags:

java

hibernate

Hello guys I have this code:

Criteria criteria = session.createCriteria(Department.class);

ProjectionList properties = Projections.projectionList();
properties.add(Projections.property("id"), "id");
properties.add(Projections.property("name"), "name");
properties.add(Projections.property("children"), "children");

criteria.setProjection(properties);
criteria.setFetchMode("children", FetchMode.JOIN);
criteria.setResultTransformer(Transformers.aliasToBean(Department.class));

criteria.add(Restrictions.isNull("parent.id"));
criteria.add(Restrictions.eq("active", true));

return criteria.list();

and entity class

public class Department extends Model {

    @Size(max = 200)
    private String name;

    @Size(max = 10)
    private String sg;

    @Size(max = 1000)
    private String description;

    @ManyToOne
    @JoinColumn(name = "id_parent")
    private Department parent;

    private boolean active;

    @OneToMany(mappedBy = "parent")
    private List<Department> children;

... plus getters and setters...

I execute the criteria and give me the stacktrace exception:

java.lang.ArrayIndexOutOfBoundsException: 2
at org.hibernate.loader.criteria.CriteriaLoader.getResultRow(CriteriaLoader.java:166)
at org.hibernate.loader.criteria.CriteriaLoader.getResultColumnOrRow(CriteriaLoader.java:146)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:747)
at org.hibernate.loader.Loader.processResultSet(Loader.java:949)
at org.hibernate.loader.Loader.doQuery(Loader.java:917)
at 

What am I doing wrong?

thanks in advance.

like image 596
EderRoger Avatar asked Feb 12 '14 13:02

EderRoger


1 Answers

Without knowing what you are trying to do with that Projection query, it's hard to say how to fix it. I think your main problem is that you need to create an alias to the children and then use that alias in your projection. In your projection, you'd also need to reference properties of children. You could do this:

Criteria criteria = session.createCriteria(Department.class);

ProjectionList properties = Projections.projectionList();
properties.add(Projections.property("id"), "id");
properties.add(Projections.property("name"), "name");
properties.add(Projections.property("children.id"), "id");
properties.add(Projections.property("children.name"), "name");

criteria.setProjection(properties);
criteria.createAlias("children",  "children", JoinType.FULL_JOIN);
criteria.setResultTransformer(Transformers.aliasToBean(Department.class));

criteria.add(Restrictions.isNull("parent.id"));
criteria.add(Restrictions.eq("active", true));
return criteria.list();

That said, I think using a Projection here is a mistake and unnecessary if your intent is to return a list of root Departments with their children Department trees. For that, you could just do this:

Criteria criteria = session.createCriteria(Department.class);
criteria.createAlias("children",  "children", JoinType.FULL_JOIN);
criteria.add(Restrictions.isNull("parent.id"));
criteria.add(Restrictions.eq("active", true));

retun criteria.list();
like image 122
neildo Avatar answered Oct 07 '22 10:10

neildo