我有 2 个表:USER 和 ADDRESS。 USER 有第一个、最后一个,并且计数为 @Transient 以显示用户拥有的地址计数。我有一个 Spring JPA Data 方法,它使用 @Query (select user.*, COUNT(address.id) from ... group by user.id) 来获取用户信息和地址 COUNT。我已经确认我的查询很好,但我无法将结果中的 COUNT 映射到用户类中的计数变量。我错过了什么?
用户.java:
@Transient
private int count;
private String first;
private String last;
UserRepository.java
@Query(value = "SELECT "
+ " user.*, COUNT(address.id) AS COUNT "
+ "FROM "
+ " user "
+ " INNER JOIN "
+ " address ON user.id = address.user_id "
+ "GROUP BY user.ID "
+ "ORDER BY user.last ASC;", nativeQuery = true)
List<User> findUserWithCount();
最佳答案
“@Transient”注释不应该按照您尝试的方式工作。获取用户所有地址的正确方法是使用 @OneToMany 注解映射 User 实体中的 Address 实体,然后进行查询以获取该用户的地址,最后获取 User 实体上获取的地址的 .size() 。
为了更好地解释这一点,我将举一个例子,让我们从映射开始(某些部分的代码不包括在内):
@Entity
@Table(name = "User")
public class User {
// All user attributes
@OneToMany
public List<Address> addresses;
// All getters and setters, including addresses get and set.
}
@Entity
@Table(name = "Address")
public class Address {
// All user attributes getters/setters
}
现在我们已经映射了两个实体,您应该能够通过调用 getAddresses().size() 方法从用户获取地址计数,但是当使用 @OneToMany 注释时,映射的集合是延迟加载的,这意味着您在使用 Java 之前,需要从数据库中获取数据。要执行此提取,您可以使用经过一些修改的查询:
首先,您不需要使用 native 查询,因为您的实体现在已正确映射。其次,您需要使用 JPQL 语法重新编写查询,第三,您需要获取 Address 集合。下面给出的示例可能适用于您的情况:
@Query(value = "SELECT u FROM User u
LEFT JOIN FETCH u.addresses")
List<User> findUserWithCount();
请注意,并不是说你将无法对带有“last”字段的数据进行排序,因为它有一个 @Transient 注释,这意味着该字段不会持久化在数据库上,这将使其无法在 JPQL 查询中使用。
如果一切都正确完成,您现在应该能够通过调用 getAddresses.size() 方法从用户获取地址计数。
PS:我强烈建议您学习一些 Hibernate 入门教程,使用正确的 Hibernate 规范映射可以轻松完成您尝试获取用户地址计数的方式。
无论如何,我希望你能回答这个问题,祝你好运。
关于java - Spring JPA DATA 与 @Query 返回一个额外的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33270329/