【问题标题】:Spring Data JPQL doesn't filter associated entity of OneToMany relationshipSpring Data JPQL 不过滤 OneToMany 关系的关联实体
【发布时间】: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


【解决方案1】:

经过努力,我找到了 JPA Entity Graph 的解决方案

@NamedEntityGraph(name = "USER.AUTHORITY", attributeNodes = { @NamedAttributeNode("authorities") })
public class UserEntity 

@EntityGraph(value = "USER.AUTHORITY", type = EntityGraphType.LOAD)
UserEntity findByUsernameAndAuthoritiesAuthorityType(String username, AuthorityType authority); 

这对于 OneToMany 和过滤子对象非常有效,但在 ManyToMany 关系的情况下它也会失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 2021-05-22
    • 2014-01-18
    • 2019-02-09
    • 1970-01-01
    • 2014-07-30
    • 2023-03-21
    相关资源
    最近更新 更多