java - JPA2 Criteria Query 以选择表 A 中的记录,其引用未在表 B 中找到

标签 java spring postgresql jpa-2.0

我有以下结构如下表

Table A {
    id <-- Primary key
    someColumn 
}

Table B {
    id <-- Primary key
    someColumn 
    idOfA <-- Foreign key mapping to Table A
}

实体类如下所示

@Entity
@Table(name = "A")
public class A implements Serializable {
    private static final long serialVersionUID = -78448557049178402L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    .......
    .......
    @OneToMany(mappedBy = "a")
    private List<B> bs = new ArrayList<>();
}

@Entity
@Table(name = "B")
public class B implements Serializable {
    private static final long serialVersionUID = -659500557015441771L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    .......
    .......
    @OneToOne
    @JoinColumn(name = "a_id", nullable = false)
    private A a;
 }

使用 JPA2,我想从表 A 中选择在表 B 中没有引用的记录。

预期的 native postgres 查询是

select * from A a 
    where a.id not in 
        (select b.idOfA from B b);

到目前为止,我能做到的是

public List<A> getANotInB() {
    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();


    // Select From Table B
    CriteriaQuery<B> criteriaQueryB = criteriaBuilder
            .createQuery(B.class);
    Root<B> rootB = criteriaQueryB.from(B.class);
    criteriaQueryB.select(rootB);

    // Select records from Table A
    CriteriaQuery<A> criteriaQueryA = criteriaBuilder.createQuery(A.class);
    Root<A> rootA = criteriaQueryA.from(A.class);
    criteriaQueryA.select(A);

    // Create predicate   
    Predicate predicate = rootAttemptA.in(criteriaQueryB.getSelection());
    criteriaQueryA.where(criteriaBuilder.not(predicate));

    // Create query

    TypedQuery<A> query = entityManager.createQuery(criteriaQueryA);
    List<A> as= query.getResultList();
    System.out.println(as);
    return as;
}

我知道上面的代码不正确,我有很多基础知识。 请帮忙

注意:我要使用JPA2 Criteria Query

最佳答案

试试这个

    CriteriaBuilder cb = entityManager.getCriteriaBuilder();

    // Select distinct aid from B
    CriteriaQuery<B> bQuery = cb.createQuery(B.class);
    Root<B> bRoot = bQuery.from(B.class);
    bQuery.select(bRoot.get("a").get("id")).distinct(true);

    // Select * from A where aid not in ()
    CriteriaQuery<A> aQuery = cb.createQuery(A.class);
    Root<A> aRoot = aQuery.from(A.class);
    aQuery.select(aRoot).where(cb.not(aRoot.get("id").in(bQuery)));

    TypedQuery<A> query = entityManager.createQuery(aQuery);
    List<A> result = query.getResultList();

基本上,您将构建查询的一部分并将它们粘合在一起。

更多信息在这里:

JPA Criteria

关于java - JPA2 Criteria Query 以选择表 A 中的记录,其引用未在表 B 中找到,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50284500/

相关文章:

java - 创建枚举与创建 Java 类有什么区别?

java - 没有 spring mvc 的 spring 安全

java - "Could not find acceptable representation"使用 spring-boot-starter-web

javascript - 如何在更少的 SQL 查询中执行复杂的 API 授权?

java - 我的涉及字符位置的 do-while 循环有问题

java - 计算 map 中值的出现次数

Postgresql 服务器正在本地计算机上运行,​​但 psql 无法连接

php - 使用 PHP PDO 设置 PostgreSQL 模式的最佳替代方案

java - 在 Java 中使用 selenium 等待元素加载时出现问题

java - IntelliJ "Could not autowire."检查,Spring JPA 存储库的 "[…] more than one bean"