通过嵌入式ID的JPA Criteria API连接 [英] JPA Criteria api join through embedded ID

查看:81
本文介绍了通过嵌入式ID的JPA Criteria API连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下实体:

@Entity
@Table(name = "place_revision")
public class PoiRevision {
    @OneToMany(mappedBy = "pk.revision", cascade = {CascadeType.ALL})
    private Collection<PoiRevisionCategory> categoryMapping;
    // ...
}

@Entity
@Table(name = "place_revision__category")
@AssociationOverrides({
    @AssociationOverride(name = "pk.revision",
        joinColumns = @JoinColumn(name = "place_revision_id")),
    @AssociationOverride(name = "pk.category",
        joinColumns = @JoinColumn(name = "category_id"))
})
public class PoiRevisionCategory {
    @EmbeddedId
    private PoiRevisionCategoryId pk = new PoiRevisionCategoryId();
    // ...
}

@Embeddable
public class PoiRevisionCategoryId implements Serializable {
    @ManyToOne
    private PoiRevision revision;
    @ManyToOne
    private Category category;
    // ...
}

@Entity
@Table(name = "category")
public class Category {
    @ManyToMany(targetEntity = Section.class, cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)
    @JoinTable(
        name = "category__section",
        joinColumns = @JoinColumn(name = "category_id"),
        inverseJoinColumns = @JoinColumn(name = "section_id")
    )
    private Collection<Section> sections;
    // ...
}

并要选择<$ c具有类别且具有部分的$ c> PoiRevisions 。
我正在使用Spring-data 规范在数据库中查询这些实体。

And want to select PoiRevisions that have Categories that have some Sections. I'm using Spring-data Specification to query the database for these entities.

我的意图是这样写的:

Specification<PoiRevision> spec = new Specification<PoiRevision>() {
    @Override
    public Predicate toPredicate(Root<PoiRevision> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
        List<Predicate> conditions = new ArrayList<>(CONDITION_COUNT);

        CollectionJoin<PoiRevision, PoiRevisionCategory> mapping = root.join(PoiRevision_.categoryMapping);
        // BROKEN here as we cannot use nested path for joins
        Join<PoiRevisionCategory, Category> categories = mapping.join("pk.category"); 
        conditions.add(categories.get("sections").in(sections));

        // ...

        return cb.and(conditions.toArray(new Predicate[] {}));
    }
};

但是我们不能将嵌套路径用于此类连接,因为JPA提供程序(在我的情况下为Hibernate)仅看起来用于 PoiRevisionCategory 类的直接属性。而且我们不能将嵌入的Id连接到我们的结果集中,因为它不是一个可管理的实体。

But we cannot use nested path for such joins as JPA provider (Hibernate, in my case) looks only for direct properties of PoiRevisionCategory class. And we cannot "join" embedded Id to our result set because it's not a manageable entity.

我真的很纠结于这个问题,当这个问题看起来并不复杂

I'm really stuck with this issue which seems to be far from complicated when translated into SQL yet it has some complexity on the ORM-side.

任何想法都值得赞赏。

推荐答案

完全切换到元模型API之后,它变得更加清晰,我实际上能够加入嵌入式实体,就像我尝试使用字符串api失败一样。

After switching completely to metamodel API it became clearer and I was actually able to join embedded entity just like I tried and failed with string api.

所以正确的方法就是像通常那样加入

So the correct way is just to join like one would normally do

Join<PoiRevisionCategory, PoiRevisionCategoryId> pk = mapping.join(PoiRevisionCategory_.pk);
Join<PoiRevisionCategoryId, Category> cats = pk.join(PoiRevisionCategoryId_.category);
CollectionJoin<Category, Section> sec = cats.join(Category_.sections);
conditions.add(sec.get(Section_.id).in(sections));

这样做确实很好!

太好了。

这篇关于通过嵌入式ID的JPA Criteria API连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆