Return 在 Hibernate/JPA 中具有完整连接的结果集

Return ResultSet with intact joins in Hibernate / JPA

我有 2 个实体:EntityA 和 EntityB。它们与一对多关系相关。

public class EntityA {

    @Identifier
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="ID", updatable = false, nullable = false)
    private long id;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name="ENTITY_A_ID", referencedColumnName="ID", nullable=true)
    private List<EntityB> entityBs;

   /* GETTERS SETTERS ... */
}
public class EntityB {

    @Identifier
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="ID", updatable = false, nullable = false)
    private long id;


    @Column(name="SOME_PROPERTY")
    private String someProperty;

    @ManyToOne
    @JoinColumn(name="ENTITY_A_ID")
    private EntityA entityA;
    /* GETTERS SETTERS ... */

}

我有一个查询,它通过 LEFT JOIN 将 EntityA 连接到实体 B。还有一个 'ON' 子句。 在正常的 SQL 术语中,这将是:

select * from EntityA eA left join EntityB eB
    on (eA.ID = eB.ENTITY_A_ID and eB.SOME_PROPERTY = "blabla" )
    where ...

所以我从加入的结果集中获得了很多需要的信息。我只希望记录与某些属性匹配时加入。如果 EntityB 与连接子句匹配,我需要 EntityA、allways 和附加的 EntityB。

该项目是使用 Hibernate/JPA 设置的。我不知道如何检索所需的信息。此时我有:

public class EntityADAO {

    public List<EntityA> findMethod() {

        CriteriaBuilder builder = entityManager.getCriteriaBuilder();

        CriteriaQuery<EntityA> query = builder.createQuery(EntityA.class);

        Root<EntityA> entityARoot = query.from(EntityA.class);
        Join<EntityA, EntityB> entityBJoin = entityARoot.join("entityB", JoinType.INNER);
        entityBJoin.on(new Predicate [] {builder.equal(entityBJoin.get("someProperty"), "fixed_val_for_now"});

       /* where clause left out for readability */

        TypedQuery<EntityA> q = entityManager.createQuery(query);

        return q.getResultList();

        }

    } 

所以我在这里.. 卡在我的 EntityAs 列表中。每当我在 EntityA 上调用 getEntityBs() 时,我都会得到所有这些......这是有道理的......但是我如何检索连接的集合?

我被 JPA 和 Hibernate 困住了,因为这个选择不是我做的。

提前致谢!

这里您需要的是自定义投影或 DTO。过滤实体集合可能会导致删除,因为实体始终反映当前 DBMS 状态并在事务结束时同步。

您可以编写一个 JPQL 查询,就像 SQL 查询一样,它可以满足您的需求。

SELECT a.id, b.id 
FROM EntityA a 
LEFT JOIN EntityB b ON a.id = b.entityA.id AND b.someProperty = 'blabla'

但这不会帮助您将结果具体化为丰富的对象。如果 Object[] 即元组对你的用例来说足够好,那么使用这种查询就可以了,但如果你想映射到丰富的对象,我建议你看一下 Blaze-Persistence Entity-Views .

Blaze-Persitence 是基于 JPA 的查询构建器,它支持基于 JPA 模型的许多高级 DBMS 功能。我在它之上创建了实体视图,以允许在 JPA 模型和自定义接口定义的模型之间轻松映射,类似于 Spring 类固醇数据投影。这个想法是您按照自己喜欢的方式定义目标结构,并通过 JPQL 表达式将属性(getter)映射到实体模型。由于属性名称用作默认映射,因此您大多不需要显式映射,因为 80% 的用例都具有作为实体模型子集的 DTO。

您的模型的映射可能看起来像下面这样简单

@EntityView(EntityA.class)
public interface EntityAView {
    long getId();
    @Mapping("entityBs[someProperty = 'blabla']")
    List<EntityBView> getEntityBs();
}

@EntityView(EntityB.class)
public interface EntityBView {
    long getId();
}

查询就是将实体视图应用于查询,最简单的就是通过 id 进行查询。

EntityAView dto = entityViewManager.find(entityManager, EntityAView.class, id);

Spring 数据集成让您几乎可以像 Spring 数据投影一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features