Hello,
In some mapping, I have a Map<Locale, String> relation that I want to query (see actual entities below).
It seems that restricting my query with a predicate that uses the actual map key class (Locale) doesn't work. Using a string instead works perfectly, although I'd expect to have to use Locale.
MapJoin<LocaleText, Locale, String> localeTextMapJoin = localeTextPath.join(LocaleText_.localeTextMap, JoinType.LEFT);
Path<Locale> localePath = localeTextMapJoin.key();
Predicate localePredicate = criteriaBuilder.equal(localePath, locale);
Path<String> nameTextPath = localeTextMapJoin.value();
Predicate namePredicate = criteriaBuilder.equal(nameTextPath, name);
query.where(localePredicate, namePredicate);
This returns 0 rows, while replacing the 3rd line with this:
String language = locale.getLanguage();
Predicate predicate = criteriaBuilder.equal(localePath, language);
... returns actual results.
The sql log is misleading, as it appears as if the query is ok. Running it in a db ui returns actual results.
I suspect this is a bug in EclipseLink (tested in GF 4.1 & 4.1.1 + upgrade to EL 2.6.1). Correct? Is this a known one (couldn't find it), should I log another?
Here is the actual query if it helps:
Fine: SELECT DISTINCT t1.ID AS a1, t1.ACTIVE AS a2, t1.REFERENCE AS a3, t1.COMPANY_ID AS a4, t1.current_price_id AS a5, t1.DESCRIPTION_ID AS a6, t1.main_picture_id AS a7, t1.NAME_ID AS a8 FROM ITEM t1 LEFT OUTER JOIN locale_text t3 ON (t3.ID = t1.NAME_ID) LEFT OUTER JOIN locale_text_value t4 ON (t4.locale_text_id = t3.ID) LEFT OUTER JOIN locale_text t0 ON (t0.ID = t1.DESCRIPTION_ID) LEFT OUTER JOIN locale_text_value t2 ON (t2.locale_text_id = t0.ID) WHERE (((t1.ACTIVE = ?) AND (t1.COMPANY_ID = ?)) AND ((((LOCATE(?, LOWER(t1.REFERENCE)) > ?) OR (LOCATE(?, LOWER(t4.localized_text)) > ?)) OR (LOCATE(?, LOWER(t2.localized_text)) > ?)) AND ((t4.locale = ?) AND (t2.locale = ?)))) LIMIT ?, ?
bind => [true, 1001, coussin, 0, coussin, 0, coussin, 0, fr, fr, 0, 20]
And here are my entities:
@Entity
public class Item implements Serializable, WithId, Activable {
/* ... */
@NotNull
@ManyToOne(cascade = CascadeType.ALL, optional = false)
private LocaleText description;
/* ... */
}
@Entity
@Table(name = "locale_text")
public class LocaleText implements Serializable {
@Id
@GeneratedValue
private Long id;
@ElementCollection(fetch = FetchType.EAGER)
@MapKeyColumn(name = "locale", columnDefinition = "VARCHAR(16)", nullable = false)
@Column(name = "localized_text", columnDefinition = "TEXT")
@CollectionTable(name = "locale_text_value", joinColumns = @JoinColumn(name = "locale_text_id", nullable = false))
private Map<Locale, String> localeTextMap;
/* ... */
}
Cheers,
Yannick