Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Hibernate Criteria for filtering keys and values in Map

I have the following persisted class:

public class Code {

  @ElementCollection(targetClass = CodeValue.class)
  @MapKeyClass(CodeProperty.class)
  @JoinTable(name="code_properties")
  @CreateIfNull( value = false )
  private Map<CodeProperty,CodeValue> propertiesMap =
      new HashMap<CodeProperty, CodeValue>();

  ...
}

public class CodeProperty {
    private String name;
    ...
}

public class CodeValue {
    private String value;
    ...
}

And I'm trying to get a list of Code filtered by some properties I have in propertiesMap (e.g. the codes where the property named "color" has the value "green".

I'm using the following base criteria:

Criteria criteria = currentSession()
    .createCriteria(Code.class, "code")
    .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);

When I try to perform a collection filter (as suggested here):

criteria.createAlias("code.properties", "p");
criteria.add(Restrictions.eq("p.foo", "test1"));
criteria.setFetchMode("code.properties", FetchMode.JOIN);
criteria.list();

I get the following error:

org.hibernate.QueryException: could not resolve property: foo of: com.example.CodeValue

Which means that, I don't really understand why, hibernate is considering that code.properties is a CodeValue instead of a map!!!

I also tried to access this field without creating the alias, and this way hibernate seems to access the correct Code class. I used properties.indeces (as suggested here):

criteria.add(Restrictions.eq("properties.indeces", "foo"));
criteria.list();

But with this I get the following error:

could not resolve property: properties.indeces of: com.example.Code

Can someone help me out understanding whats wrong? What would the correct Criteria query be to find the Codes with color green?

You can checkout the Github project that demonstrates this problem.

Thanks

like image 390
micdcar Avatar asked Aug 19 '16 16:08

micdcar


2 Answers

Please confirm if you've used indeces or indices. The correct usage is as follows:

criteria.createAlias("code.properties", "p");
criteria.add(Restrictions.eq("p.indices", "foo"));
criteria.list();

Alternatively, you can use

eq("p." + CollectionPropertyNames.COLLECTION_INDICES)  

in the Restriction.

Please let me know if it still doesn't work for you.

like image 98
Akash Mishra Avatar answered Sep 18 '22 20:09

Akash Mishra


This may not be what you are expecting, but in higher version of hibernate the alias is not being resolved i had an issue in Projections when using the alias refer https://stackoverflow.com/questions/36607042/hibernate-criteria-query-using-projections-aggregate-function-alias-throws-sette

like image 42
Tim Avatar answered Sep 17 '22 20:09

Tim