使用规格的深度加入FETCH

问题描述 投票:0回答:1

我的实体A与实体B的关系为1-1。实体B与实体C相关1-1。

  • UserEntity
    • BadgeEntity
      • BadgeTypEntity

我想使用规格实现复杂的过滤搜索。此外,我将配置JOIN FETCH从UserEntity到BadgeEntity,从BadgeEntity到BadgeTypEntity,以在单个查询中检索带有“ BadgeType”的UserEntity。

没有规格,直接使用标准API,很容易解决在需要时配置所需提取的问题。

我首先尝试:https://github.com/tkaczmarzyk/specification-arg-resolver#enabling-spec-annotations-in-your-spring-app但似乎只能配置一个级别的提取(UserEntity-> BadgeEntity)

因此,我尝试提供一个“伪”规范,该规范只是向查询中添加了所需的JOIN FETCH,但是我认为这很难使它正常工作。

用户实体

public class UserEntity
{

   private String name;
   private String email;  

   @Fetch(FetchMode.JOIN)
   @OneToOne(fetch = FetchType.EAGER)
   @JoinColumn(name = "BADGE_ID")
   private BadgeEntity badge;

   ...
}

徽章实体

public class BadgeEntity
{

    @Fetch(FetchMode.JOIN)
    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "BADGE_TYPE_ID")
    private BadgeTypeEntity badgeType;
  ...
}

BadgeType实体

public class BadgeTypeEntity
{

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    @Column(name = "BADGE_TYPE_ID")
    private Integer badgeTypeId;

    @Column(name = "CODE")
    private String code;
}

EMAIL过滤器规范

public class UsersEmailSpec implements Specification<UserEntity>
{

    private String email;

    public UsersEmailSpec(String email)
    {
        this.email = email;
    }

    @Override
    public Predicate toPredicate(Root<UserEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder)
    {
        Predicate result = null;
        if(StringUtils.isNotEmpty(this.email))
        {
            result = criteriaBuilder.like(root.get(UserEntity_.email),this.email);
        }
        return result;
    }
}

[名称过滤器规格

public class UsersNameSpec implements Specification<UserEntity>
{

    private String name;

    public UsersNameSpec(String name)
    {
        this.name = name;
    }

    @Override
    public Predicate toPredicate(Root<UserEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder)
    {
        Predicate result = null;
        if(StringUtils.isNotEmpty(this.name))
        {
            result = criteriaBuilder.like(root.get(UserEntity_.name),this.name);
        }
        return result;
    }
}

用于配置FETCH JOIN的FAKE规范

Specification conjunctionSpec = new Specification() {
    @Override
    public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
        Fetch fetch = root.fetch(UserEntity_.badge, JoinType.INNER).fetch(BadgeEntity_.badgeType, JoinType.INNER);
            return null;
    }
};

有没有一种方法可以使用规格巧妙地解决此问题?

hibernate jpa spring-data-jpa dsl criteria-api
1个回答
0
投票

您可以实现多级实体子映射。

示例:

criteriaBuilder.like(root.get("badge").get("badgeType").get("email"),this.email); 
© www.soinside.com 2019 - 2024. All rights reserved.