Joined collection expressions not properly "rendered" in JPA Criteria queries

Description

The situation is as follow:
I have an User class which has a collection of elements which is a Set of Role enum values and I want to search for users which have one of more roles. I want to use the CriteriaBuilder, because I have a search form with a lot of fields which are optional.

The User class:
@Entity
@Table(name = "USERS")
@Access(AccessType.FIELD)
public class User implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
private Long id;

@Column(name = "USERNAME", unique = true, nullable = false, length = 128)
private String username;

@ElementCollection
@Enumerated(EnumType.STRING)
@Column(name = "ROLE")
@CollectionTable(name = "USER_ROLES", joinColumns = @JoinColumn(name = "USER_ID"))
private Set<Role> roles = new HashSet<Role>();

...
}

The enum Role:
public enum Role {
ROLE_1, ROLE_2, ROLE_3;
}

Creating the query with the CriteriaBuilder
Set<Role> roles = new HashSet<Role>();
roles.add(Role.ROLE_1);
roles.add(Role.ROLE_2);

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<User> criteriaQuery = criteriaBuilder.createQuery(User.class);

Root<User> root = criteriaQuery.from(User.class);

criteriaQuery.where(root.join("roles").in(roles));

TypedQuery<User> query = entityManager.createQuery(criteriaQuery);
query.getResultList();

This is the exception:
java.lang.IllegalArgumentException: Parameter value [ROLE_2] was not matching type [java.util.Set]
at org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:360)
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:359)
at org.hibernate.ejb.criteria.CriteriaQueryCompiler$1$1.bind(CriteriaQueryCompiler.java:194)
at org.hibernate.ejb.criteria.CriteriaQueryCompiler.compile(CriteriaQueryCompiler.java:247)
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:437)
...

This all works with OpenJPA 2.0.0

Environment

hibernate-core 3.5.4, hibernate-entitymanager 3.5.4, hsqldb 2.0.0, mac os x 10.6, java 1.6.0_20

Activity

Show:
Koen Molkenboer
August 6, 2010, 8:45 AM

This is a maven project with the situation I described.

Steve Ebersole
August 19, 2010, 4:16 PM

After numerous failed attempts at using your test case, I got a test case running that shows this behavior

SebastianB
October 20, 2010, 1:27 PM

Hi,

I still have this kind of problem.
I have 2 Entites (Employee/Projects, m:n) and so both of them have a Set of each other: Employee has Set<Project> and Project has Set<Employee>.

Now I want to get all Employees they belong to given Projects:

Set<Project> projects = new HashSet<Project>();

projects.add(...);

List<Predicate> predicates = new ArrayList<Predicate>();

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();

CriteriaQuery<Employee> query = criteriaBuilder.createQuery(Employee.class);

Root<Employee> root = queryfrom(Employee.class);

predicates.add(cb.in(root.get("projects")).value(values));

return em.createQuery(query.where(cb.and(predicates.toArray(new Predicate[0]))).distinct(true)).getResultList()

Exception in thread "main" java.lang.IllegalArgumentException: Parameter value [hibernate.test.Project@7f8062] was not matching type [java.util.Set]

at org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:340)
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:364)
at org.hibernate.ejb.criteria.CriteriaQueryCompiler$1$1.bind(CriteriaQueryCompiler.java:194)
at org.hibernate.ejb.criteria.CriteriaQueryCompiler.compile(CriteriaQueryCompiler.java:247)
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:441)
at hibernate.test.DefaultCriteriaBuildCommand.executeQuery(DefaultCriteriaBuildCommand.java:143)
at hibernate.test.EmployeeConditionBuilder.getResults(EmployeeConditionBuilder.java:83)
at hibernate.test.DBAccessManager.getElements(DBAccessManager.java:127)
at hibernate.test.TestumgebungClient.<init>(TestumgebungClient.java:38)
at hibernate.test.TestumgebungClient.main(TestumgebungClient.java:46)

Enviroment:
java version 1.6.0_16
hibernate-core 3.6.0.Final
Windows XP SP3

Thanks in advance

Sebastian

Fixed

Assignee

Steve Ebersole

Reporter

Koen Molkenboer

Fix versions

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Affects versions

Priority

Major