我有以下持久课程:
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;
...
}
我试图通过 propertiesMap 中的某些属性来获取代码列表(例如,属性名为&#34;颜色&#34;具有该值的代码&#34;绿色&#34;
我使用以下基本标准:
Criteria criteria = currentSession()
.createCriteria(Code.class, "code")
.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
当我尝试执行收集过滤器时(建议here):
criteria.createAlias("code.properties", "p");
criteria.add(Restrictions.eq("p.foo", "test1"));
criteria.setFetchMode("code.properties", FetchMode.JOIN);
criteria.list();
我收到以下错误:
org.hibernate.QueryException: could not resolve property: foo of: com.example.CodeValue
这意味着,我真的不明白为什么,hibernate正在考虑 code.properties 是 CodeValue 而不是地图 !!!
我还试图在不创建别名的情况下访问此字段,这样hibernate似乎可以访问正确的 Code 类。我使用了 properties.indeces (如建议的here):
criteria.add(Restrictions.eq("properties.indeces", "foo"));
criteria.list();
但是有了这个,我得到以下错误:
could not resolve property: properties.indeces of: com.example.Code
有人可以帮我理解什么是错的吗?正确的Criteria查询将找到绿色代码?
您可以结帐the Github project that demonstrates this problem。
由于
答案 0 :(得分:2)
请确认您是否使用过indeces或index。正确用法如下:
criteria.createAlias("code.properties", "p");
criteria.add(Restrictions.eq("p.indices", "foo"));
criteria.list();
或者,您可以使用
eq("p." + CollectionPropertyNames.COLLECTION_INDICES)
限制中的。
如果它仍然不适合你,请告诉我。
答案 1 :(得分:1)
这可能不是你所期望的,但是在更高版本的hibernate中,别名没有得到解决我在使用别名引用时在Projections中遇到了问题 https://stackoverflow.com/questions/36607042/hibernate-criteria-query-using-projections-aggregate-function-alias-throws-sette
答案 2 :(得分:1)
您的方法存在各种问题: 在项目github中观察MapTest文件夹我可以建议您始终将变量名称作为列名称,并在Criteria中使用这些相同的名称。 Criteria是maps,其第一个参数是属性名称,第二个参数是attribute的值。 对于多对多关系,您可以尝试使用:
@JoinTable(
name="docente_classe",
joinColumns=
@JoinColumn(name="id_dipendente", referencedColumnName="id_dipendente"),
inverseJoinColumns=
@JoinColumn(name="id_classe", referencedColumnName="id_classe")
)
这是JPA注释,我不知道你的项目是否编译。
对于多对多关系的查询,请看这篇文章:
答案 3 :(得分:0)
我不相信您可以使用传统的Hibernate Criteria API执行此操作,并且使用JPA条件API的Hibernate实现存在一个小的限制。解决这个问题的一种方法是:
通过直接使用谓词要求查询该实体来获取List<CodeProperty>
。
List<CodeProperty> propertyKeys = entityManager
.createQuery( "FROM CodeProperty p WHERE p.name = :name" )
.setParameter( "name", "foo" )
.getResultList();
使用JPA标准查询您的Code
实体。
// setup the query
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Code> query = cb.createQuery( Code.class );
Root<Code> root = query.from( Code.class );
MapJoin<Code, CodeProperty, CodeValue> mapRoot = root.joinMap( "propertiesMap" );
query.select( root ).where( mapRoot.key().in( propertyKeys ) );
// get results
List<Code> results = entityManager.createQuery( query ).getResultList();
我尝试将这些结合使用:
query
.select( root )
.where ( cb.eq( mapRoot.key().get( "name" ), "foo" ) )
问题是导致NotYetImplemented
例外:(。