我有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卡住了,因为这个选择不是我做的。
先谢谢你
你在这里需要的是一个自定义的投影或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。