使用@ElementCollection进行查询的DTO投影会导致“无法在类上找到适当的构造函数”错误

时间:2019-04-03 08:24:47

标签: spring hibernate jpa kotlin jpql

我正在使用投影编写自定义查询,以减少一个会话中的查询数量(当需要使用antity中的几个字段并使用Fetch连接时)。 不幸的是,当返回的dto中的一个类型是集合时,就会陷入一个问题。

我有@ElementCollection以下类(为此目的是简化版):

@Entity
class MyClass(

    val someString: String,

    @ElementCollection
    @Enumerated(EnumType.STRING)
    var enums: MutableSet<Enum>,

    @ManyToOne
    var condition: Condition

    //And so on...
)

DTO用于投影:

data class ProjectionDTO(
    val aString: String,
    val enumList: List<Enum>
)

但是使用查询时:

fun query(condition: Condition): List<ProjectionDTO> =
        entityManager.createQuery(
            """SELECT NEW com.xxx.ProjectionDTO( m.someString, e ) FROM MyClass m
                INNER JOIN FETCH m.enums e
                WHERE m.condition = :condition""", ProjectionDTO::class.java)
            .setParameter("condition", condition)
            .resultList
}

我收到以下异常:

Exception:[org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [com.xxx.ProjectionDTO]. Expected arguments are: com.xxx.String, com.xxx.Enum [SELECT NEW com.xxx.ProjectionDTO( m.someString, e ) FROM MyClass m
                INNER JOIN FETCH m.enums e
                WHERE m.condition = :condition]]

已经尝试了不同类型的集合,其他构造函数和给定@ElementCollection的调用字段,例如查询参数中的e.enum。 是否可以通过这种查询返回列表(或其他集合)?如果是这样,我该如何解决?

1 个答案:

答案 0 :(得分:0)

不允许在构造函数查询中使用集合路径表达式。 link

仅将根实体放入构造函数中:

SELECT NEW com.xxx.ProjectionDTO(m) WHERE m.condition = :condition

在构造函数中,将m.enums,m.someString分配给字段。