java findall,使用Java泛型为JPA查找带有WHERE子句的findAll()查询

So, After a 10+ year break I'm coming back to Java and trying out stuff with JPA and Java generics. I've created a generics based findAll(other) JPA query that basically does

SELECT * FROM source WHERE other_id = other.id;

This is where I'm up to. It works, but I'm wondering if there's a better, cleaner way to do it. Using ManagedType was hard, and there's not much complete documentation or simple examples around.

I've decided to keep my code as generic as possible (no pun intended) so I use JPA2.

This is the root of all Entity Classes. I probably don't need it, but it stops me from having basic mistakes.

import java.io.Serializable;

public abstract class DomainObject implements Serializable {

private static final long serialVersionUID = 1L;

public abstract void setId(Long id);

public abstract Long getId();

}

This is the abstract DAO class. I extend this for the implementation classes as I need to be more specific doing other activities - mostly making sure lazy sets are loaded.

public abstract class GenericDAOImpl implements GenericDAO {

private Class type;

@PersistenceContext

protected EntityManager entityManager;

public GenericDAOImpl(Class type) {

super();

this.type = type;

}

... save and delete classes go here

@Override

public List findAll(T2 where) {

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(type);

Root rootQuery = criteriaQuery.from(type);

if (where != null) {

EntityType entity = entityManager.getMetamodel().entity(type);

SingularAttribute super T, ?> attribute = null;

for (SingularAttribute super T, ?> singleAttribute: entity.getSingularAttributes()) {

// loop through all attributes that match this class

if (singleAttribute.getJavaType().equals(where.getClass())) {

// winner!

attribute = singleAttribute;

break;

}

}

// where t.object = object.getID()

criteriaQuery.where(criteriaBuilder.equal(rootQuery.get(attribute), where));

}

criteriaQuery.select(rootQuery);

TypedQuery query = entityManager.createQuery(criteriaQuery);

// need this to make sure we have a clean list?

// entityManager.clear();

return query.getResultList();

}

Any suggestions? If anything, I want this out there so other people can make use of it.

解决方案

Hat tip to Adam Bien if you don't want to use createQuery with a String and want type safety:

@PersistenceContext

EntityManager em;

public List allEntries() {

CriteriaBuilder cb = em.getCriteriaBuilder();

CriteriaQuery cq = cb.createQuery(ConfigurationEntry.class);

Root rootEntry = cq.from(ConfigurationEntry.class);

CriteriaQuery all = cq.select(rootEntry);

TypedQuery allQuery = em.createQuery(all);

return allQuery.getResultList();

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值