我正在将JPA 2.0与Hibernate 4.1.0.Final一起使用。我有几个类,Groups和GroupMembers。每个GroupMember都绑定到一个用户对象
@Entity @Table(name = "group") public class Group { @Id @NotNull @GeneratedValue(generator = "uuid-strategy") @Column(name = "ID") private String id; … @OneToMany(mappedBy = "group") private Set<GroupMember> members; @Entity @Table(name = "sb_msg_group_member") public class GroupMember { … @ManyToOne @JoinColumn(name = "USER_ID", nullable = false, updatable = true) private User user;
是否有可能编写给定User对象的java.util.Set的JPA标准查询,该查询将返回其成员与该Set完全匹配的组?我尝试了以下…
final CriteriaBuilder builder = m_entityManager.getCriteriaBuilder(); CriteriaQuery<Group> criteria = builder.createQuery(Group.class); final Root<Group> groupRoot = criteria.from(Group.class); final Set<GroupMember> groupMembers = new HashSet<GroupMember>(); for (final User user : users) { final GroupMember groupMember = new GroupMember(); groupMember.setUser(user); groupMembers.add(groupMember); } // for criteria.where(builder.equal(groupRoot.get(Group_.members), groupMembers)); final TypedQuery<Group> results = m_entityManager.createQuery(criteria);
但是它失败了,但…
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:988) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:974) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:919) at com.mysql.jdbc.PreparedStatement.checkAllParametersSet(PreparedStatement.java:2611) at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2586) at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2510) at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2259) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:56) at org.hibernate.loader.Loader.getResultSet(Loader.java:2040) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1837) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1816) at org.hibernate.loader.Loader.doQuery(Loader.java:900) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342) at org.hibernate.loader.Loader.doList(Loader.java:2526) at org.hibernate.loader.Loader.doList(Loader.java:2512) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2342) at org.hibernate.loader.Loader.list(Loader.java:2337) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:495) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:357) at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1275) at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101) at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:287) at org.hibernate.ejb.criteria.CriteriaQueryCompiler$3.getSingleResult(CriteriaQueryCompiler.java:258) at org.mainco.subco.messaging.repo.MessageDaoImpl.findGroupByMembers(MessageDaoImpl.java:144) at org.mainco.subco.messaging.repo.MessageDaoIT.testFindGroupByMembers(MessageDaoIT.java:83)
每个用户都将需要不同的根,因为每个根都与其他用户不同(未经测试):
final CriteriaBuilder builder = m_entityManager.getCriteriaBuilder(); CriteriaQuery<Group> criteria = builder.createQuery(Group.class); final List<Predicate> predicates = new ArrayList<Predicate>(); final Root<Group> group = criteria.from(Group.class); for (final User user : users) { final Root<GroupMember> memberRoot = group.join(Group_.members); final Predicate p = builder.equal(memberRoot.get(GroupMember_.user), user); predicates.add(p); } // for predicates.add(builder.equals(builder.count(group.get(Group_.members)),users.size())) criteria.where(builder.and(predicates.toArray(new Predicate[predicates.size()]))); final TypedQuery<Group> results = m_entityManager.createQuery(criteria);