JPA:如何为集合中的项目编写order by子句?

时间:2013-12-09 23:06:14

标签: hibernate jpa sql-order-by jpa-2.0

我正在使用JPA 2.0和Hibernate 4.1.0.Final。我在我的Hibernate实体中有这个......

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "user_address", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns =     @JoinColumn(name = "address_id"))
private Set<Address> addresses;

Address实体具有以下字段:

@Column(name = "email")
private String email;

如果用户可能根本没有链接到任何地址对象,我如何编写一个order by子句来查询User集合中的第一个电子邮件地址的用户对象的查询?我试过了

final CriteriaBuilder builder = m_entityManager.getCriteriaBuilder();
final CriteriaQuery<User> criteria = builder.createQuery(User.class);
final Root<User> user = criteria.from(User.class);
...
Expression orderByExpr = orderByRoot.get(orderByCol).get("addresses").get("email");
criteria.orderBy(orderByExpr);

但是得到错误......

java.lang.IllegalArgumentException: Unable to resolve attribute [email] against path
    at org.hibernate.ejb.criteria.path.AbstractPathImpl.unknownAttribute(AbstractPathImpl.java:116)
    at org.hibernate.ejb.criteria.path.AbstractPathImpl.locateAttribute(AbstractPathImpl.java:221)
    at org.hibernate.ejb.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:192)
    at org.mainco.subco.user.repo.UserDaoImpl.addOrderByCol(UserDaoImpl.java:446)
    at org.mainco.subco.user.repo.UserDaoImpl.buildFindUsersQuery(UserDaoImpl.java:342)
    at org.mainco.subco.user.repo.UserDaoImpl.findUsers(UserDaoImpl.java:153)
    at org.mainco.subco.user.repo.UserDao2IT.testFindOrderByEmail(UserDao2IT.java:558)

编辑:以下是Andrei I推荐的粗略代码。导致我在评论中列出错误。

final CriteriaBuilder builder = m_entityManager.getCriteriaBuilder();
final CriteriaQuery<User> criteria = builder.createQuery(User.class);
final Root<User> user = criteria.from(User.class);
...
final Root<User> user = criteria.from(User.class);
 Join<User, Address> addr = user.join("addresses", JoinType.LEFT);
 orderByExpr = addr.get("email"); 
 criteria.orderBy(builder.asc(orderByExpr));
…            
return criteria.where(builder.and(…))
            .select(user);

1 个答案:

答案 0 :(得分:0)

尝试以下方法:

final CriteriaQuery<User> query = builder.createQuery(User.class);
final Root<User> user = query.from(User.class);
query.select(user);//this one was missed.

SetJoin<User, Address> addr = user.joinSet("addresses", JoinType.LEFT);

query.orderBy( builder.asc(addr.get("email")) );

PS:因为addresses字段是一个集合,所以它没有被排序,这意味着不清楚列表中的哪一个将被考虑。同样在SQL中,您需要一些定义“first”元素的标准。