从Spring Data Jpa查询返回自定义对象

val*_*0ne 6 java spring spring-data spring-data-jpa spring-boot

我在jpa信息库类中有一个自定义查询:

package it.univaq.we.internshipTutor.repository;
import ...

public interface ProfessorRepository extends JpaRepository<Professor, Long> {

    List<Professor> findAll();

    ...

    @Query(value =  "SELECT professor.id, professor.department_id, " +
                    "professor.first_name, professor.last_name, " +
                    "professor.email, COUNT(professor_id) as count " +
                    "FROM professor LEFT JOIN student_internship ON professor.id = professor_id " +
                    "GROUP BY professor_id ORDER BY count DESC LIMIT ?1", nativeQuery = true)
    List<ProfessorInternshipCount> mostRequestedProfessors(int limit);
}
Run Code Online (Sandbox Code Playgroud)

该查询返回最需要的10位实习导师/教授;结果由教授的信息和一个整数值(计数)组成。

教授模特班:

package it.univaq.we.internshipTutor.model;

import ...

@Entity
@Table(name = "professor")
public class Professor {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;

    @Transient
    private UUID uuid;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "department_id", nullable = false)
    @NotNull(message = "this field is mandatory")
    private Department department;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "professor")
    private List<StudentInternship> studentInternships;

    @Column(name = "first_name", nullable = false, length = 255)
    @NotEmpty
    private String firstName;

    @Column(name = "last_name", nullable = false, length = 255)
    @NotEmpty
    private String lastName;

    @Column(name = "email", nullable = false, length = 255)
    @Email
    @NotEmpty
    private String email;

    ...getters and setters...
}
Run Code Online (Sandbox Code Playgroud)

ProfessorInternshipCount模型(用于封装查询结果):

package it.univaq.we.internshipTutor.model;

public class ProfessorInternshipCount {
    private Professor professor;
    private Integer count;

    public ProfessorInternshipCount(Professor professor, int count) {
        this.professor = professor;
        this.count = count;
    }

    ...getters and setters...
}
Run Code Online (Sandbox Code Playgroud)

现在,我很难将查询返回的内容与我创建的模型绑定在一起。更准确地说,我得到以下异常:

org.springframework.core.convert.ConverterNotFoundException: 
    No converter found capable of converting from type 
    [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] 
    to type 
    [it.univaq.we.internshipTutor.model.ProfessorInternshipCount]
...
Run Code Online (Sandbox Code Playgroud)

难道我做错了什么?有做我想做的更好的方法吗?

Md.*_*rim 6

您可以使用投影轻松实现。这里有波纹管列:

private String firstName;
private String lastName;
private Long id;
Run Code Online (Sandbox Code Playgroud)

使用查询中的getter创建一个Interface。您的投影将如下所示:

public interface ITestProjection {
    Long getId();
    Integer getCount();
    String getFirstName();
    String getLastName();
}
Run Code Online (Sandbox Code Playgroud)

您的查询将如下所示:

@Query(value = "SELECT professor.id, professor.department_id, " +
                    "professor.first_name, professor.last_name, " +
                    "professor.email, COUNT(professor_id) as count " +
                    "FROM professor LEFT JOIN student_internship ON professor.id = professor_id " +
                    "GROUP BY professor_id ORDER BY count DESC LIMIT =?1", nativeQuery = true)
    ArrayList<ITestProjection> findDataWithCount(Integer limit);
Run Code Online (Sandbox Code Playgroud)

希望这能解决您的问题。

有关更多详细信息,请访问此线程

谢谢 :)

  • 当名字是first_name时,getFirstName()对我不起作用,但当它是firstName时,它起作用。为什么? (3认同)