【发布时间】:2019-04-26 18:10:27
【问题描述】:
我正在处理 spring 数据并使用 Spring Boot 2.1.0.RELEASE 并使用 JPQL 查询关联/嵌入实体字段以获取关联实体类过滤器的 @OneToMany 关系,但它检索所有嵌入对象也使用fetch = FetchType.EAGER,但不过滤关联对象并加载所有对象。下面是实体和 repo 类。
第一个实体类
@Entity
@Table(name = "USER")
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String username;
@OneToMany(mappedBy = "user", targetEntity = AuthorityEntity.class, fetch = FetchType.LAZY, cascade=CascadeType.ALL)
private List<AuthorityEntity> authorities;
//Setter getter
}
第二个实体类
@Entity
@Table(name = "AUTHORITY")
public class AuthorityEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String authorityType;
private String textType;
@JsonBackReference
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private UserEntity user;
//Setter getter
}
存储库接口
@Repository
public interface UserRepo extends JpaRepository<UserEntity, Long> {
UserEntity findByUsernameAndAuthoritiesAuthorityType(String username, String authority);
}
我也尝试了 HQL @Query("select u from UserEntity u JOIN FETCH AuthorityEntity a on u.id = a.user where u.username = ?1 and a.authorityType = ?2"),但它也获取所有子对象而不是过滤子对象。
让我知道我错在哪里,是否需要任何配置?
【问题讨论】:
-
where 子句不用于过滤实体中返回的内容。它用于选择应返回哪些实体。如果我执行一个查询来查找所有名称中包含 w 的用户,我将返回一个用户列表,而 Nawal,您将成为该列表的一部分,因为您的名称中有 w。然后,一旦我找到你,如果我问你“把你名字中的字母给我”,你不会只说“w”。你会说“N,a,w,a,l”。这里也一样。
-
如果您只想选择特定的 AuthorityEntity 实例,那么您应该查询 AuthorityEntity 实例,即将它们放在查询的 select 子句中。这不会改变这样一个事实,即如果用户 u 有 3 个权限,那么它就有 3 个权限,并且询问它的权限将始终返回它的 3 个权限。
-
@JBNizet 如果它检索所有子对象,那么我必须过滤关联的对象,这会使我的代码变脏。根据 Spring Data JPA,可以开发一种自定义方法 findByUsernameAndAuthoritiesAuthorityType(String username, String authority); 来执行此类查询,但它表现不佳,并且在支持的一个为 UserEntity 和另一个执行两个查询选择所有权威实体。我可以截取任何代码以对关联对象执行过滤吗?
-
我在之前的 cmets 中已经告诉过你需要做什么。再读一遍。
-
如果我理解正确,我必须进行另一个查询来选择 UserEntity 以外的 AuthorityEntity,如果是这样,那么我在这里没有使用 Spring Data JPQL 功能并编写两个查询。我只想为性能执行一个查询的原因。
标签: hibernate spring-boot spring-data-jpa spring-data hibernate-mapping