使用输入参数初始化JPA @Query

时间:2019-04-03 17:15:43

标签: spring hibernate spring-boot spring-data-jpa

我想使用提供的参数通过@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 个答案:

答案 0 :(得分:1)

修复代码中的明显错误(无默认构造函数,类型参数中的基元)后,在应用程序启动期间会抛出前三种方法:

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);  
}

以上方法是一种解决方法,这导致参数以sql形式发送到db(例如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