我正试图在我的应用程序中从JPA JPQL查询转向Criteria Query。
主要原因是我厌倦了重构字符串并修复了由 Not typesafe JPQL&#39> 引起的大量运行时jpa异常。
我在网上搜索其他支持typeafe和ide重构机制的JPA解决方案。标准查询似乎很有希望。
有人认为在标准查询中困扰我:
在方法参数中使用字符串。 它可以以某种方式替换为类型安全的Java对象/变量,也许是java反射?
以下是示例代码:
public List<BankAccount> findWithBalance(int amount) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<BankAccount> cq = cb.createQuery(BankAccount.class);
Root<BankAccount> from = cq.from(BankAccount.class);
ParameterExpression<Integer> balance = cb.parameter(Integer.class);
cq.select(from);
Predicate predicate = cb.gt(from.<Integer> get("balance"), balance);
cq.where(predicate);
cq.orderBy(cb.asc(from.get("ownerName")));
TypedQuery<BankAccount> query = em.createQuery(cq);
query.setParameter(balance, amount);
return query.getResultList();
}
正如您所看到的那样,有字符串:
如果我要更改此参数的名称,我在IDE或编译时都不会收到错误。我将不得不在运行时测试它,这对像我这样的大型项目来说并不好。
我用:
请帮忙。
答案 0 :(得分:2)
Metamodel生成器似乎也是一个很好的解决方案:
示例实体:
@Entity
public class Order {
@Id
@GeneratedValue
Integer id;
@ManyToOne
Customer customer;
@OneToMany
Set<Item> items;
BigDecimal totalCost;
// standard setter/getter methods
}
生成元模型(在编写/编写Order类时由eclipse IDE自动完成。原始类中的每个更改:Order
- 即使没有保存文件也会在Order_
类中自动更新):
@StaticMetamodel(Order.class)
public class Order_ {
public static volatile SingularAttribute<Order, Integer> id;
public static volatile SingularAttribute<Order, Customer> customer;
public static volatile SetAttribute<Order, Item> items;
public static volatile SingularAttribute<Order, BigDecimal> totalCost;
}
由于我们可以构建类型安全的SQL查询,如下所示:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
SetJoin<Order, Item> itemNode = cq.from(Order.class).join(Order_.items);
cq.where( cb.equal(itemNode.get(Item_.id), 5 ) ).distinct(true);