Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to query for a M:N relationship using enums with CriteriaBuilder

I am curently working on a Company entity which contains a List of Area enum values. These are the areas, the company is working in. They are mapped as @ElementCollection.

@Entity
public class Company {

  @ElementCollection
  @CollectionTable(name = "company2area")
  @Enumerated(EnumType.STRING)
  private List<Area> areas = new ArrayList<Area>();

  ...
}

Area is a simple enum, containing the available areas.

 public enum Area {
    ASIA,
    AMERICA,
    EUROPE;
}

I tried to query for all companies that are currently working in ASIA and AMERICA like this:

CriteriaQuery<Company> query = this.entityManager.getCriteriaBuilder()
                                             .createQuery(Company.class);
query.where(query.from(Company.class)
        .get("areas")
        .in(Arrays.asList(Area.ASIA, Area.AMERICA)));
List<Company> result = entityManager.createQuery(q)
                                    .getResultList();

But all I got is an exception:

Caused by: java.lang.IllegalArgumentException: Parameter value [ASIA]
did not match expected type [java.util.Collection]  at
org.hibernate.ejb.AbstractQueryImpl.validateParameterBinding(AbstractQueryImpl.java:375)
    at
org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:348)
    at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:375)     at
org.hibernate.ejb.criteria.CriteriaQueryCompiler$1$1.bind(CriteriaQueryCompiler.java:195)
    at
org.hibernate.ejb.criteria.CriteriaQueryCompiler.compile(CriteriaQueryCompiler.java:241)
    at
org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:587)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)     at
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
    at $Proxy61.createQuery(Unknown Source)     ... 29 more

What am I doing wrong? Is there a special trick about the enums?

I'm well aware of the question How to query an M:N relationship with JPA2? I asked some months ago. Unfortunately, the solution from there does not work with enums.

Thanks for your help. :)

Edit:

Here's the description of my MySQL database:

create table company2area (
    Company_fk bigint not null,
    areas varchar(255)
) ENGINE=InnoDB;

create table company (
    id bigint not null auto_increment,
    fullName varchar(255),
    ...,
    primary key (id)
) ENGINE=InnoDB;

alter table company2area 
    add index FK52BA7162CE087250 (Company_fk), 
    add constraint FK52BA7162CE087250 
    foreign key (Company_fk) 
    references company (id);
like image 211
Pumuckline Avatar asked Oct 29 '12 14:10

Pumuckline


1 Answers

It works, if I join the tables explicitly:

query.where(query.from(Company.class)
    .join("areas", JoinType.INNER)
    .in(Arrays.asList(Area.ASIA, Area.AMERICA)));

As far as I thought, both ways should result in the same query as inner join is the default, but obviously, only this one here works.

like image 61
Pumuckline Avatar answered Sep 19 '22 17:09

Pumuckline