[英]Return custom object from Spring Data Jpa query
I've a custom query inside a jpa repository class: 我在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);
}
The query returns the 10 most requested internship tutors/professors; 该查询返回10个最需要的实习辅导员/教授; the result is composed by the information of the Professor and an integer value (the count).
结果由教授的信息和整数值(计数)组成。
Professor model class: 教授模特课:
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...
}
ProfessorInternshipCount model (created to incapsulate the result of the query): 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...
}
Now, I've difficulties in binding what the query returns with the model I've created. 现在,我很难将查询返回的内容与我创建的模型绑定。 More precisely I get the following exception:
更准确地说,我得到以下例外:
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]
...
Am I doing something wrong? 难道我做错了什么? Is there a better way of doing what I'am trying to do?
有没有更好的方法来做我想做的事情?
You can easily achive this using projection. 您可以使用投影轻松实现此目的。 Here you have the bellow columns :
在这里你有以下列:
private String firstName;
private String lastName;
private Long id;
Create an Interface with getter from your query. 使用查询中的getter创建一个接口。 Your projection will like this:
您的预测将是这样的:
public interface ITestProjection {
Long getId();
Integer getCount();
String getFirstName();
String getLastName();
}
Your Query will like this : 您的查询将是这样的:
@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);
Hope this will solve your problem. 希望这能解决你的问题。
For more details visit this thread . 有关详细信息,请访问此主题 。
Thanks :) 谢谢 :)
You can do this by either following ways. 您可以通过以下方式执行此操作。
Go through the article to get more detail. 阅读文章以获取更多详细信息。
http://javasampleapproach.com/spring-framework/spring-data/query-alter-domain-model-spring-jpa-projection-springboot-mysql-database http://javasampleapproach.com/spring-framework/spring-data/query-alter-domain-model-spring-jpa-projection-springboot-mysql-database
For example, let's that we have: 例如,让我们拥有:
User - entity object with many fields. 用户 - 具有许多字段的实体对象。
UserBean - just object where our data will be converted. UserBean - 只是我们的数据将被转换的对象。
Bad practice: 不好的做法:
@Repository
public class ReportingRepository {
@PersistenceContext
private EntityManager em;
public List<UserBean> findQuery() {
Query query = em.createNativeQuery("select ... from Table INNER JOIN ...");
List<UserBean> items = (List<UserBean>) query.getResultList();
return items;
}
}
but it will return values in arrays, so it will be more beautiful if we write the following code, that is better practice: 但它会返回数组中的值,所以如果我们编写以下代码会更漂亮,这是更好的做法:
query.unwrap(SQLQuery.class)
.addScalar("instance name", StringType.INSTANCE)
.addScalar("second instance name", IntegerType.INSTANCE)
.setResultTransformer(Transformers.aliasToBean(UserBean.class));
List<UserBean> items = query.getResultList();
So finally everything is converted to UserBean class. 所以最后一切都转换为UserBean类。 Note that in addScalar method you should pass instance variable name (in your question you have count variable )
请注意 ,在addScalar方法中,您应该传递实例变量名称(在您的问题中,您有计数变量)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.