在Hibernate/JPA中返回具有完整联接的ResultSet [英] Return ResultSet with intact joins in Hibernate / JPA

查看:73
本文介绍了在Hibernate/JPA中返回具有完整联接的ResultSet的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have 2 entities: EntityA and EntityB. They are related with a One To Many relation.

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语言中,这将是:

I have a query that joins EntityA with a LEFT JOIN to Entity B. And a 'ON' clause. In normal SQL lingo this would be:

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

因此,我从加入的结果集中获得了许多急需的信息.我只希望记录与某些属性匹配时才加入.总之,如果EntityB与join子句匹配,我就需要EntityA和附加的EntityB.

So I'm having much needed information from my joined resultset. I only want records joined if they match certain properties. I need EntityA, allways, and an attached EntityB if EntityB matched the join clause.

该项目由Hibernate/JPA设置.我不知道如何获取所需的信息.这时我有:

The project is set up with Hibernate / JPA. I can't figure out how to retreive the information needed. At this moment I have:

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()时,我都会得到所有它们.

So here I am.. Stuck with my List of EntityAs. whenever I call getEntityBs() on a EntityA, I'm getting all of them.. And this makes sense.. But How can I retrieve the joined set?

我坚持使用JPA和Hibernate,因为这种选择不是我做出的.

I'm stuck with JPA and Hibernate, as this choice is not made by me.

提前谢谢!

推荐答案

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

What you need here is a custom projection or DTO. Filtering the entity collection might cause a delete because entities always reflect the current DBMS state and are synchronized at the end of the transaction.

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

You can write a JPQL query, just like the SQL one, that does what you want.

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

但这不会帮助您将结果具体化为丰富的对象.如果Object []即元组足以满足您的用例,则可以使用这种查询并完成操作,但是如果要映射到丰富的对象,我建议您看一下

But this won't help you with the materialization of the results into rich objects. If an Object[] i.e. the tuples are good enough for your use case, then use this kind of query and be done, but if you want to map to rich objects, I can recommend that you take a look at Blaze-Persistence Entity-Views.

Blaze-Persitence是JPA之上的查询构建器,它支持JPA模型之上的许多高级DBMS功能.我在其顶部创建了实体视图,以方便在JPA模型和自定义接口定义的模型之间进行映射,例如类固醇上的Spring Data Projections.这个想法是您以自己喜欢的方式定义目标结构,并通过JPQL表达式将属性(获取器)映射到实体模型.由于属性名称用作默认映射,因此大多数情况下不需要显式映射,因为80%的用例都是将DTO作为实体模型的子集.

Blaze-Persitence is a query builder on top of JPA which supports many of the advanced DBMS features on top of the JPA model. I created Entity Views on top of it to allow easy mapping between JPA models and custom interface defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure the way you like and map attributes(getters) via JPQL expressions to the entity model. Since the attribute name is used as default mapping, you mostly don't need explicit mappings as 80% of the use cases is to have DTOs that are a subset of the entity model.

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

A mapping for your model could look as simple as the following

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

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

查询是将实体视图应用于查询的问题,最简单的方法就是按ID查询.

Querying is a matter of applying the entity view to a query, the simplest being just a query by id.

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

Spring Data集成使您可以像使用Spring Data Projections一样使用它:

The Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

这篇关于在Hibernate/JPA中返回具有完整联接的ResultSet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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