【问题标题】:JPA: How do I write an order by clause for an item in a set?JPA:如何为集合中的项目编写 order by 子句?
【发布时间】:2013-12-09 23:06:14
【问题描述】:

我正在使用 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 子句以按此集中的第一个电子邮件地址排序?我试过了

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);

【问题讨论】:

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


【解决方案1】:

尝试以下方法:

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 中,您需要一些标准来定义“第一个”元素。

【讨论】:

  • 您好,我尝试了您的建议,但导致错误“java.lang.IllegalStateException: No explicit selection and an implicit one cold not be determined”。
  • 这是另一个问题/问题,因为您忘记选择根目录。我更新了我的答案来解决这个问题。
  • 是的,我已经这样做了。我编辑了我的答案,向您展示我是如何按您提供的行插入订单的。如果我将它们注释掉,一切正常(除了排序),但如果我包含你的行,我会得到我列出的异常。
  • 是的,我输入了你的台词,我得到了那个例外。
  • 有趣。我更正了我使用joinSet() 而不是join() 的答案。
猜你喜欢
  • 1970-01-01
  • 2013-08-30
  • 2013-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
  • 2021-01-27
  • 2020-12-24
相关资源
最近更新 更多