0

我在使用 JPA2/Hibernate 4.2/MySQL 5.1/Java 6 时遇到问题

我有以下类 User,它有一个属性 ,Set<Role>其中 Role 是一个枚举。这是课程:

@Entity
public class User
{
  private static final long serialVersionUID = 1L;

  @ElementCollection(fetch=FetchType.EAGER)
  @Enumerated(value=EnumType.STRING)
  protected Set<Role> roles;

  // .. other stuff
}

public enum Role { ADMIN, OPERATOR, ... }

我已经尝试为此创建一个 CriteriaQuery 和一个 JPQL 查询,但由于某种原因,即使角色存在,它们每次都返回一个空列表。

这是我的条件查询代码:

CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<User> query = builder.createQuery(User.class);
Root<User> root = query.from(User.class);

query.where(builder.isMember( Role.ADMIN, root.<Set<Role>>get( "roles" ) ) );

List<User> result = getEntityManager().createQuery(query).getResultList();

这是我正在创建的 JPQL:

String jpql = "SELECT * FROM com.mypackage.user.User WHERE (:roles1 MEMBER OF roles))";
Query query = em.createQuery(jpql);
query.setParameter( "roles1", Role.ADMIN );
List result = em.getResultList();

users 表包含具有所有角色的单个用户,但这些都没有返回任何结果。对于我正在做的工作,我需要同时拥有 JPA 和 JPQL 版本。请帮忙!

4

1 回答 1

1

好的,对于那些有类似问题的人,我有一个解决方案,但它不是很好。感谢 JB Nizet 的指点,因为他们帮助诊断了问题。

问题是由于 JPA 和/或 Hibernate 在处理不是字符串的数据时的限制。在这里,我使用了一个枚举,它在 Role 对象和它在数据库中的字符串表示之间进行相等性测试,而不是将我传入的 Role 转换为它的 db 表示(正如你所期望的那样),然后做比较。

为了让 JPQL 版本继续运行,我做了:

String jpql = "SELECT * FROM com.mypackage.user.User WHERE (:roles1 MEMBER OF roles))";
Query query = em.createQuery(jpql);
query.setParameter( "roles1", Role.ADMIN.toString() );
List result = em.getResultList();

为了修复 JPA 版本,我做了:

CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<User> query = builder.createQuery(User.class);
Root<User> root = query.from(User.class);

query.where(builder.isMember( Role.ADMIN.toString(), root.<Set<String>>get( "roles" ) ) );

List<User> result = getEntityManager().createQuery(query).getResultList();

如果有人可以更正此代码并使其成为不必要的 toString (我没有排除我只是没有正确设置它的想法),如果你能把我说对,我将不胜感激。:)

于 2013-08-22T08:21:19.993 回答