【问题标题】:Two-side Joining in JPA Criteria BuildingJPA Criteria Building 中的两侧连接
【发布时间】:2020-03-04 07:00:25
【问题描述】:

我有三个实体,就像这样:-

@Entity
@Table(name = "product")
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    @Expose
    private long id;

    @ManyToOne
    @JoinColumn(name = "users_id")
    @Expose
    private User user;
}

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    @Expose
    private long id;
}


@Entity
@Table(name = "users_phone")
public class UserPhone {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    @Expose
    private int id;

    @ManyToOne
    @JoinColumn(name = "users_id")
    @Expose
    private User user;
}

现在,我想从基于连接三个表的产品表中获取结果。所以我制定了一个规范,以便我可以将它传递到存储库中。这是规范的代码。

    Specification<ProductPost> productSpecification = new Specification<ProductPost>() {
        @Override
        public Predicate toPredicate(Root<ProductPost> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
            List<Predicate> predicates = new ArrayList<>();
            criteriaQuery = criteriaBuilder.createQuery();

            if (userName.length() > 0) {
                predicates.add(criteriaBuilder.like(root.join("user").<String>get("fullName"), "%" + userName + "%"));
            }
            if (phoneNumber.length() > 0) {
                // Below line isn't working actually as  join("UserPhone") - 'user' table has no reference for 'userPhone'. But 'userPhone' has 'user'.
                predicates.add(criteriaBuilder.like(root.join("user").join("UserPhone").<String>get("phoneNumber"), "%" + postType + "%"));
            }

            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        }
    };

是的,如果我在 'user' 表中有 'userPhone' 引用,例如 product -&gt; user -&gt; userPhone 而不是 product -&gt; user, userPhone -&gt; user,这将很容易。但我的架构是这样的。现在我在加入 3 个表并获取结果时遇到了麻烦。

【问题讨论】:

    标签: java spring-boot jpa criteria-api dynamicquery


    【解决方案1】:

    如果cross-join 被占用而不是join 你可以试试这个解决方案

    if (phoneNumber.length() > 0) {
        Root<UserPhone> userPhone = query.from(UserPhone.class);
    
        predicates.add(criteriaBuilder.equal(
            root.join("user").get("id"), 
            userPhone.get("user").get("id")
        ));
    
        predicates.add(criteriaBuilder.like(
            userPhone.get("phoneNumber"), 
            "%" + postType + "%"
        ));
    }
    

    【讨论】:

      猜你喜欢
      • 2016-11-09
      • 2017-05-02
      • 1970-01-01
      • 1970-01-01
      • 2019-02-09
      • 1970-01-01
      • 2022-12-21
      • 2012-03-08
      • 2015-04-04
      相关资源
      最近更新 更多