使用JPA加载父/子关系中的子实体

时间:2012-09-16 23:44:53

标签: jpa join parent-child fetch

我的域名有一个类别实体,它本身就具有双向关系。每个类别都可以有父母和孩子。

@Entity
public class Category implements DomainObject {

    private Long id;
    private Integer version;
    private String name;
    private Category parent;
    private Set<Category> children;

    @Override
    @Id
    @GeneratedValue
    public final Long getId() {
        return id;
    }

    @Version
    public Integer getVersion() {
        return version;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(unique=true, nullable=false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @ManyToOne
    public Category getParent() {
        return parent;
    }

    public void setParent(Category parent) {
        this.parent = parent;
    } 

    @OneToMany
    @JoinColumn(name = "parent_id")
    public Set<Category> getChildren() {
        return children;
    }

    public void setChildren(Set<Category> children) {
        this.children = children;
    }
}

我创建了以下查询来获取带有直接(1级)子项的“root”类别。

select distinct c from Category c left join fetch c.children where c.parent is null order by c.name

这实际上有效。我的问题是:为什么我需要getChildren()上的“JoinColumn”注释才能使这个工作,为什么我不能只做一个“foin fetch”查询,没有“distinct”?如果我删除“distinct”,我会得到一个乘法。对于父项的每个子项,将整个父项复制到结果集中。

有更好的方法吗?它感觉......有点糟糕。

1 个答案:

答案 0 :(得分:0)

在JPA中,您需要在加入OneToMany时设置不同,否则它将返回重复项。 这是必需的。

JPA规范需要这个,但它是一个奇怪的默认值,但与数据库连接中发生的事情有关。