使用 JPA 语法时,具有复杂键类的 JpaRepository 验证失败并出现错误“方法查询验证失败”

Posted

技术标签:

【中文标题】使用 JPA 语法时,具有复杂键类的 JpaRepository 验证失败并出现错误“方法查询验证失败”【英文标题】:JpaRepository with complex key class is failing validation with error "Validation failed for query for method" when using JPA syntax 【发布时间】:2019-06-18 10:37:49 【问题描述】:

我正在尝试使用 JPA 的“开箱即用”好东西并将数据从 DB 获取到对象。当 JpaRepository 使用简单类作为键时,它工作得很好,但是对于键类有点复杂的测试用例,即使是最简单的查询,jpa 验证也会失败。

使用 native_query=true 可以解决问题,但是我不确定自己做错了什么以及缺少什么。

MyTestPK.java:

package com.mytest.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Embeddable;
import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Embeddable
public class MyTestPK implements Serializable 
    private String type;
    private String name;



MyTest.java:

package com.mytest.model;

import lombok.Data;

import javax.persistence.*;

@Entity
@Table(name = "my_test")

@Data
@IdClass(MyTestPK.class)
public class MyTest 
    @Id
    @Column(name = "my_test_type", nullable = false)
    private String type;

    @Id
    @Column(name = "my_test_name", nullable = false)
    private String name;

    @Column(name = "my_test_misc")
    private String misc;

MyTestRepository.java:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

@Repository
public interface MyTestRepository extends JpaRepository<MyTest, MyTestPK> 
    @Query(value="SELECT m FROM MyTest m")
    List<MyTest> getAllObjs();

收到以下错误: …… 调用 init 方法失败;嵌套异常是 java.lang.IllegalArgumentException: Validation failed for query for public abstract java.util.List com.mytest.dao.MyTestRepository.getAllObjs()! 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE] 在 org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]

【问题讨论】:

请添加完整的堆栈跟踪而不是仅仅添加一个 sn-p 并为其使用正确的代码格式。 【参考方案1】:

您可以使用@EmbeddedId,无需再次在实体类中定义列。

MyTestPK.java:

package com.mytest.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Embeddable;
import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Embeddable
public class MyTestPK implements Serializable 
    @Column(name = "my_test_type", nullable = false)
    private String type;
    @Column(name = "my_test_name", nullable = false)
    private String name;

MyTest.java:

package com.mytest.model;

import lombok.Data;

import javax.persistence.*;

@Entity
@Table(name = "my_test")
@Data
public class MyTest 
    @EmbeddedId
    private MyTestPK pk;

    @Column(name = "my_test_misc")
    private String misc;

【讨论】:

以上是关于使用 JPA 语法时,具有复杂键类的 JpaRepository 验证失败并出现错误“方法查询验证失败”的主要内容,如果未能解决你的问题,请参考以下文章

JPA - 不要扩展对其他类的引用

如何使用基于类的配置设置具有不同基础包、transactionManagerRef 的多个 Spring Data JPA?

JPA注解实现联合主键

jpa 2.0 对具有 2 个 ID 的类的注释,指向两个不同的表

使用 JPA 时实现 MVC

JPA Specification复杂查询及排序