Использование входного параметра для инициализации объекта внутри JPA @Query - PullRequest
1 голос
/ 03 апреля 2019

Я хотел инициализировать мою модель через ее конструктор внутри @Query, используя предоставленный параметр.

Я пробовал именованный параметр, но ничего не получится. Я тоже протестировал Spel, но он не работает. В большинстве случаев ошибка компиляции. Я пытался зайти в Google, но не смог найти ничего похожего.

Я создал класс Person следующим образом:

@Entity
@Table(name="Person")
class Person{
    @Id
    private int age;
    private String name;

    Person(int age, String name)
    {
        this.age = age;
        this.name = name;
    }
}
@Repository
interface PersonRepo extends CrudRepository<Person, int>{

    @Query("SELECT new Person(:age, person.name) FROM Person person")
    List<Person> findAll(@Param("age") int age);   


    // also have tried this
    @Query("SELECT new Person(:#{#age}, person.name) FROM Person person")
    List<Person> findAll(@Param("age") int age);   

    // also have tried this
    @Query("SELECT new Person(?1, person.name) FROM Person person")
    List<Person> findAll(int age);   

      // also have tried this
    @Query("SELECT new Person(age1, person.name) FROM Person person, :age as age1")
    List<Person> findAll(@Param("age") age);   
}

1 Ответ

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

После исправления очевидных ошибок в вашем коде (без конструктора по умолчанию, примитив в аргументе типа) первые три метода выдают во время запуска приложения:

QuerySyntaxException: Unable to locate appropriate constructor on class [Person]. Expected arguments are: java.lang.String 

Это потому, что конструктор принимает в качестве параметров только выражения выбора, а не узлы параметров, и это опущено. Добавление приведения к выражению решает вышеуказанную проблему, и код работает как ожидалось:

@Repository
interface PersonRepo extends CrudRepository<Person, Integer>{
  @Query("SELECT new Person(cast(:age as int), person.name) FROM Person person")
  List<Person> findAll(@Param("age") int age);  
}

Приведенный выше подход является обходным путем, и это приводит к отправке аргумента в db в sql (пример на диалекте h2):

select cast(? as integer) as col_0_0_, person0_.name as col_1_0_ from person person0_

и зависит от функции приведения базы данных. Из-за этого вы не можете передать там составной тип (https://hibernate.atlassian.net/browse/HHH-9459)

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