JPA @NamedQuery select @OneToMany object 类型

JPA @NamedQuery select by @OneToMany object type

假设我们有以下情况:A parent 有一个 children 的列表,而每个 children 是 "number" 或 "alphabet" 类型,并且我想 select parent

我有以下最小示例,我已经解决了第一种情况,但不知道第二种情况,因为我假设我必须按 object 类型进行过滤,但我不确定这是否是仅通过 SQL 是否可行(我不想在 Java 中进行过滤以尽早减少相关实体的数量)。

Parent.java

import java.io.Serializable;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;

@Entity
@NamedQueries({
    @NamedQuery(name = "findWithNumberChildrenContainingNumber42", query = "SELECT nc.parent from NumberChild nc WHERE nc.number = 42"),
    @NamedQuery(name = "findWithoutNumberChildren", query = "?")
})
public class Parent implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(mappedBy = "parent")
    private List<Child> children;

    // ...
}

Child.java

import java.io.Serializable;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;

@MappedSuperclass
abstract class Child implements Serializable {

    @ManyToOne
    private Parent parent;

    // ...
}

数量Child.java

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class NumberChild extends Child {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private Integer number;

    // ...  
}

字母表Child.java

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class AlphabetChild extends Child {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String alphabet;

    // ...
}

原来之前的查询比必要的更复杂,所以这是我刚刚测试过的。

SELECT p FROM Parent p WHERE p NOT IN (SELECT nc.parent FROM NumberChild nc)

好吧,在我的测试中名称不同,但 Hibernate 的日志显示它确实生成了更有效的查询。