2011-06-18 210 views
4

OpenJPA有任何方式通过CriteriaBuilder获取嵌套对象属性吗?OpenJPA criteriaBuilder嵌套对象属性获取

这是一个小案例。

@Entity 
public class X { 
     private Object Y; 

     // getters, setters... 
} 

@Entity 
public class Y { 
     private String Z; 

     // getters, setters... 
} 

因此,在使用时CriteriaBuilder,我们使用的是X为根,即:

@PersistenceContext 
private EntityManager entityManager; 

//..... 

Root<X> rootObj = criteriaBuilder.from(X.class); 
CriteriaQuery<X> select; 

String param1 = X.getY().getZ(); 

// initializing predicate, default value is TRUE 
Predicate predicate1 = criteriaBuilder.isNull(null); 

// construct search predicate which fails miserably due to IllegalArgumentExecption 
if (X != null) { 
predicate1 = criteriaBuilder.and(predicate1, criteriaBuilder.equal(rootObj.<String> get("Y.Z"), param1));} 

现在,我的悲伤是这样的 - >get("Y.Z")

CriteriaBuilder不知道反思取ž (但它可以并且将解决Y)。有没有办法直接从get()获得Z?除了使用JPQL之外,我还可以想到另一种方法 - 我不喜欢这种方法:我想我可以将Z作为@Transient属性在X中暴露(为了防止OpenJPA将其作为列保留),但是听起来像是一个非常不好的想法:我本质上是手动展开一个对象图,并在实体bean内部引入不需要的垃圾,而不是计算平坦化一个复杂图形所需的时间或这种错误倾向(它可能会出错很多方法)。

有没有办法让这项工作?任何想法都表示赞赏。

回答

7

嘿,这个解决方案令人惊讶地简单 - 它看起来非常难看,但它的工作原理。

predicate1 = criteriaBuilder.and(predicate1, criteriaBuilder.equal(rootObj.get("Y").<String> get("Z"), param1));} 

我真的不知道是否有更优雅的解决方案。

+2

如果您使用元模型:'predicate1 = criteriaBuilder.and(predicate1,criteriaBuilder.equal(rootObj.get(X_.Y).get(Y_.Z),param1));}' – gertas

+0

但是,不要使用元模型类,我个人发现这种链接的语法非常出乎意料,特别是链中最后一个getter的类型声明。可以说,它可以使用反射罩下的反射来更清晰地定义(并且容易使用),但是 - 就像这样,这种方式将不得不这样做。 – quantum