在Hibernate JPA中返回具有完整连接的ResultSet。

问题描述 投票:0回答:1

我有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到EntityB。还有一个'ON'子句。在正常的SQL行话中,这将是。

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

所以我从我的连接结果集中得到了很多需要的信息。我只想让记录在符合某些属性的情况下加入。我需要EntityA,总是这样,如果EntityB匹配了连接子句,我还需要一个附加的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();

        }

    } 

所以我在这里... 每当我在一个EntityA上调用getEntityBs()时,我就会得到所有的EntityAs。这是有道理的。但我如何才能检索到加入的集合?

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

先谢谢你

java hibernate jpa left-join jpa-criteria
1个回答
1
投票

你在这里需要的是一个自定义的投影或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-持久性实体-视图.

Blaze-Persitence是一个JPA之上的查询构建器,它支持JPA模型之上的许多高级DBMS功能。我在它上面创建了实体视图,以允许JPA模型和自定义接口定义的模型之间的轻松映射,就像Spring Data Projections一样。这个想法是,你以你喜欢的方式定义你的目标结构,并通过JPQL表达式将属性(getters)映射到实体模型。由于属性名被用作默认映射,你大多不需要显式映射,因为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 Data集成,你几乎可以像Spring Data Projections一样使用它。https:/persistence.blazebit.comdocumentationentity-viewmanualen_USindex.html#spring-data-features。

© www.soinside.com 2019 - 2024. All rights reserved.