hibernate - 为什么此枚举参数适用于单个字段而不适用于集合?

标签 hibernate jpa jpql

考虑以下 JPA 实体(实现是 Hibernate 4.3.0):

@Entity
public class MyEntity {

    @Id
    protected long myEntityId;

    @Enumerated(EnumType.STRING)
    public Condition myCondition = Condition.BAD;

    @Enumerated(EnumType.STRING)
    @ElementCollection
    public Set<Condition> conditions = new HashSet<Condition>();

    public enum Condition {
        GOOD, FAIR, BAD, SOL
    }
}

当我使用枚举参数运行以下查询时,我得到 0 个结果(没有错误):

//Produces no results
String queryString = "FROM MyEntity me WHERE :condition MEMBER OF me.conditions";
List<MyEntity> things = JPA.em().createQuery(queryString, MyEntity.class).setParameter("condition", Condition.BAD).getResultList();

此查询生成以下 SQL:

select myentity0_.myentityid as myentity1_38_, myentity0_.mycondition as mycondit2_38_ 
from MyEntity myentity0_ 
where ? in (
    select conditions1_.conditions 
    from MyEntity_conditions conditions1_ 
    where myentity0_.myentityid=conditions1_.MyEntity_myEntityId)

如果我使用字符串文字,我会得到结果。如果我对非集合字段使用相同的参数策略,我也会得到结果:

// Produces results
queryString = "FROM MyEntity me WHERE 'BAD' MEMBER OF me.conditions";
things = JPA.em().createQuery(queryString, MyEntity.class).getResultList();

// Also produces results
queryString = "FROM MyEntity me WHERE me.myCondition = :condition";
things = JPA.em().createQuery(queryString, MyEntity.class).setParameter("condition", Condition.BAD).getResultList();

//So does this
String queryString = "from MyEntity me join me.conditions c where c = :condition";
List<MyEntity> things = JPA.em().createQuery(queryString, MyEntity.class).setParameter("condition", Condition.BAD).getResultList();

这些查询生成以下 SQL:

select myentity0_.myentityid as myentity1_38_, myentity0_.mycondition as mycondit2_38_ 
from MyEntity myentity0_ 
where 'BAD' in (
    select conditions1_.conditions 
    from MyEntity_conditions conditions1_ 
    where myentity0_.myentityid=conditions1_.MyEntity_myEntityId)

select myentity0_.myentityid as myentity1_38_, myentity0_.mycondition as mycondit2_38_ 
from MyEntity myentity0_ 
where myentity0_.mycondition=?

select myentity0_.myentityid as myentity1_38_, myentity0_.mycondition as mycondit2_38_ 
from MyEntity myentity0_ 
    inner join MyEntity_conditions conditions1_ on myentity0_.myentityid=conditions1_.MyEntity_myEntityId 
where conditions1_.conditions=?

当您使用参数时,Hibernate 应该处理 EnumType.STRINGEnumType.ORDINAL 的假设是错误的吗?至少,这是不一致的。查询枚举字段时填充参数有效,但查询枚举集合时则无效。我错过了什么?

最佳答案

您的映射错误,因此结果无法预测。

您错过了 @ElementCollection,仅在 Collection 上使用 @Enumerated,这不是有效的映射。


更新

问题似乎出在其他地方。

您应该添加生成的 SQL,以便我们获得更多信息。

我尝试过等效的架构,并且查询运行良好:

return em.createQuery("from DocumentType x where :family member of x.families", DocumentType.class)
    .setParameter("family", DocumentFamily.GENERIC)
    .setMaxResults(5)
    .getResultList();

还有

from DocumentType x where 'GENERIC' member of x.families
from DocumentType x join x.families f where f = :family
from DocumentType x join x.families f where f = 'GENERIC'
from DocumentType x join x.families f where f = it.shape.edea2.jpa.enums.DocumentFamily.GENERIC

有两个不同的生成的 SQL 查询:

select ...
from ELEMENT_TYPE documentty0_ 
where documentty0_.DTYPE='DocumentType' 
    and ('GENERIC' in (
        select families1_.FAMILY 
        from DOCUMENT_TYPE_FAMILY families1_ 
        where documentty0_.ID=families1_.DOCUMENT_TYPE_ID)) 
limit 5

select ...
from ELEMENT_TYPE documentty0_ 
    inner join DOCUMENT_TYPE_FAMILY families1_ on documentty0_.ID=families1_.DOCUMENT_TYPE_ID 
where documentty0_.DTYPE='DocumentType' 
    and families1_.FAMILY='GENERIC' 
limit 5

但是有一些奇怪的事情:

from DocumentType x where it.shape.edea2.jpa.enums.DocumentFamily.GENERIC member of x.families

抛出

org.hibernate.QueryException: Unrecognized Hibernate Type for handling query constant (it.shape.edea2.jpa.enums.DocumentFamily.GENERIC); expecting LiteralType implementation or AttributeConverter

您使用的是哪个版本的 Hibernate?

我使用的是 5.2.2

关于hibernate - 为什么此枚举参数适用于单个字段而不适用于集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41624557/

相关文章:

java - jpa/hibernate 如何通过带注释的外键映射元素集合

hibernate - Spring Boot JPA不会在查询表中添加模式名称

java - 在 JPQL 中将 native 查询转换为命名查询

java - 意外标记 : part near line 1, 第 155 列 [选择新

mysql - Spring Boot 应用程序 : java. lang.IllegalArgumentException:必须至少存在一个 JPA 元模型

java - 使用 HQL 时出现 ClassCastException

mysql - Java EE/JPA 向数据库添加新表/实体的方法

java - 将日期时间转换为 yyyy-MM-dd HH :mm:ss"format

java - 如何使用一组可变的字符串进行类似查询?

java - 没有 jpa 的 Spring 和 Hibernate