Reputation: 3753
I have an entity which has a list of enums, stored in a collection table as strings.
enum Color {
RED,
GREEN,
BLUE
}
@Entity
class Product {
@Id
private Long id;
@Column
private String name;
@ElementCollection
@Enumerated(EnumType.STRING)
@CollectionTable(name = "ProductColors", joinColumns = @JoinColumn(name = "product_id"))
@Column(name="color")
private List<Color> availableColors;
}
This works fine for creating, and fetching products through spring-rest-webmvc. But I'd like to be able to find all the products in a given color.
I tried the following:
@RepositoryRestResource
public interface ProductRepository extends CrudRepository<Long, Product> {
@Query("select p from Product p where :color in p.availableColors")
List<Product> findByColor(@Param("color") Color color);
}
But that gives an error:
... CROSS JOIN PRODUCTCOLORS COLORS1_ WHERE PRODUCT0_.ID = COLORS1_.PRODUCT_ID AND (? in (.[*])) ...
... expected "NOT, EXISTS, INTERSECTS, SELECT, FROM" ...
Is it possible to query against a simple ElementCollection like this, or do I have to move to a full-fledged entity to store the color relationship?
The answer at https://stackoverflow.com/a/34132646/153225 suggests it's possible to do it like this, but I can't see what I'm doing wrong.
Upvotes: 2
Views: 803
Reputation: 11531
Quoting the JPQL BNF in the JPA spec.
in_expression ::=
{state_valued_path_expression | type_discriminator} [NOT] IN
{ ( in_item {, in_item}* ) | (subquery) | collection_valued_input_parameter }
in_item ::= literal | single_valued_input_parameter
In your case "p.availableColors" is not a "collection_valued_input_parameter" (or subquery, or the other option either). It is a field of your entity. Consequently that is not JPQL portable syntax you're trying.
However, using
select p from Product p where :color MEMBER OF p.availableColors
ought to give what you need, and the JPA implementation will likely do an INNER JOIN to the enum join table, adding a WHERE clause on the particular enum member required.
Upvotes: 3