java - JPA 标准构建中的双方加入

标签 java spring-boot jpa criteria-api dynamicquery

我有三个实体,例如:-

@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()]));
        }
    };

是的,如果我在“用户”表中有“userPhone”引用,例如 - product -> user -> userPhone,那就很容易了而不是product -> user, userPhone -> user 。但我的架构是这样的。现在我在连接 3 个表并获取结果时遇到了麻烦。

最佳答案

如果使用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 + "%"
    ));
}

关于java - JPA 标准构建中的双方加入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60520602/

相关文章:

java - 用于显示和CRUD操作的实体类

java - 亚像素图形运动

java - Quartz 实例应该只运行特定的作业,而不是全部

c# - 如何在java中使用串口类[C#]

java - 如何使用 Spring Boot 让 Twilio 在通话中一一告诉 OTP

java - Spring 启动 : gracefully shutdown by controlling termination order involving MongoClient

java - 如何保持@ManyToMany 关系 - 重复条目或分离实体

java - JPA需要外键吗

java - Android: getPixel(x,y) 颜色值错误

java - 带有 Spring Kafka 的 Spring Boot Rest API