首页 > 解决方案 > 我是否必须为连接查询创建单独的 @Entity 类才能提取结果?JpaRepository

问题描述

我想使用 Spring Boot JPA 存储库从两个 @Entity 表中提取数据(并将其显示在 .html thymeleaf 中)。

挑战:我真的不想有一个单独的 @Entity 类(因此是一个单独的表)来表示连接的结果。甚至可能吗?我是 Spring 新手,不确定最佳实践是什么。

班级客户

@Data
@Entity
@Table(name="client", uniqueConstraints={@UniqueConstraint(columnNames={"client_id"})})
public class Client {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "client_seq")
    @SequenceGenerator(name = "client_seq", initialValue = 50)
    @Column(name="client_id", nullable = false, unique = true, length = 9)
    private long client_id;
    @Column(name="NAME", nullable = false,  length = 20)
    private String name;
    @Column(name="SURNAME", nullable = false,  length = 20)
    private String surname;
    @Column(name="CITY", nullable = false,  length = 20)
    private String city;
    @Column(name="COUNTRY", nullable = false,  length = 20)
    private String country;
    @Column(name="BIO", nullable = false,  length = 200)
    private String bio;

    @OneToMany(mappedBy = "client")
    private Set<Request> requests;

    public Client() {
    }

    public Client(String name, String surname, String city, String country, String bio) {
        this.name = name;
        this.surname = surname;
        this.city = city;
        this.country = country;
        this.bio = bio;
    }

课程要求

@Entity
@Data
@Table(name="request",uniqueConstraints = {@UniqueConstraint(columnNames = "request_id")})
public class Request {

    public enum Status
    {
        PENDING, BACKED, DONE;
    }

    @Id
    @Column(name = "request_id", unique = true, nullable = false, length = 9)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long requestId;

    @ManyToOne
    @JoinColumn(name="client", referencedColumnName = "client_id")
    private Client client;

    @Column(name="request_short", nullable = false,  length = 100)
    private String requestShort;

    @Column(name = "request_long", nullable = false,  length = 250)
    private String requestLong;

    @Column(name = "request_date", nullable = false)
    private LocalDate requestDate;

    @Column(name = "status")
    private Status status;

    public Request(String requestShort, String requestLong, LocalDate requestDate, Status status) {
        this.requestShort = requestShort;
        this.requestLong = requestLong;
        this.requestDate = requestDate;
        this.status = status;
    }

}

用于收集结果但不存储结果的 DEMO 类

@Data
@Component
public class ClientRequest {

    private long client_id;
    private long requestId;

    public ClientRequest(){};

    public ClientRequest(long client_id, long requestId) {
        this.client_id = client_id;
        this.requestId = requestId;
}

最后是我的存储库:

@Repository
public interface ClientRepository extends JpaRepository<Client, Long> {

    List<Client> findByName(String name);    // **works**

    @Query("SELECT a FROM Client a WHERE client_id > ?1")
    List<Client> findByUser_id(Long user_id);             // **works**

    @Query("SELECT a.client_id, b.request_id FROM Client a JOIN a.Request b WHERE a.client_id > ?1")
    List<ClientRequest> findPendingRequestsWithUserData(Long user_id);     // fails

  }

相关错误信息:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webController': Unsatisfied dependency expressed through field 'clientRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.dev.repository.ClientRepository.findPendingRequestsWithUserData(java.lang.Long)!

标签: javaspringspring-bootjpaspring-data-jpa

解决方案


尝试这个。这应该有效。

@Query("SELECT new com.path.to.ClientRequest(a.client_id, b.request_id) FROM Client a JOIN a.requests b WHERE a.client_id > ?1")
List<ClientRequest> findPendingRequestsWithUserData(Long user_id); 

您需要使用new类的完整路径创建新对象。这就是缺少的。


推荐阅读