DTO Проекция запроса с @ElementCollection вызывает ошибку «Невозможно найти соответствующий конструктор в классе» - PullRequest
3 голосов
/ 03 апреля 2019

Я пишу пользовательский запрос, используя проекцию, чтобы уменьшить количество запросов в одном сеансе, когда требуется пара полей из antity и используя Fetch join. К сожалению, возникла проблема, когда один из возвращаемых 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 Ответ

1 голос
/ 03 апреля 2019

Нельзя использовать выражения пути коллекции в запросе конструктора. ссылка

Поместить в конструктор только корневую сущность:

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

В конструкторе присвойте m.enums, m.someString полям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...