jpa - 如何指定具有 "MEMBER IN"的 JPA 标准 API 以及映射父类(super class)中的多对多关系?

标签 jpa eclipselink criteria criteria-api

我想查询 ConcreteEntity,其中 AUser 用户 IS MEMBER of ConcreteEntity.createdBy

@Entity
public class AUser implements Serializable {
    @Id
    @GeneratedValue
    private Long id;
    private String property;

@MappedSuperclass
public class AbstractEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue
    private Long id;
    @ManyToMany
    private Set<AUser> createdBy = new HashSet<>();

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
ppublc class ConcreteEntity extends AbstractEntity {
    private String property1;

EntityManager em = ...; //set to null or else
AUser user = ...; //set to null or else
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<ConcreteEntity> criteria = cb.createQuery(ConcreteEntity.class);
Root<ConcreteEntity> concreteRoot = criteria.from(ConcreteEntity.class);
criteria.select(concreteRoot);
SetAttribute<AbstractEntity, AUser> setAttribute = ConcreteEntity_.createdBy;
PluralAttribute<ConcreteEntity, Set<AUser>, AUser> pluralAttribute = setAttribute;
    //richtercloud/jpa/criteria/api/metamodel/member/of/NewMain.java:[40,77] error: incompatible types: SetAttribute<AbstractEntity,AUser> cannot be converted to PluralAttribute<ConcreteEntity,Set<AUser>,AUser>
Expression<Set<AUser>> createdByExpression = concreteRoot.get(pluralAttribute);
criteria.where(cb.isNotMember(user, createdByExpression));
TypedQuery<ConcreteEntity> query = em.createQuery(criteria);
List<ConcreteEntity> result = query.getResultList();

我没有得到从 SetAttributePluralAttribute 的转换。我知道我不应该用无法编译的代码发布问题,但是尽管我想说我对泛型有相当的了解,但我在这里不明白。

我正在使用 Eclipselink 2.5.2 和 JPA 2.1。

最佳答案

查看 Path.get 方法:

<Y> Path<Y> get(SingularAttribute<? super X, Y> attribute);

<E, C extends Collection<E>> Expression<C> get(PluralAttribute<X, C, E> collection);

第二个应该是:

<E, C extends Collection<E>> Expression<C> get(PluralAttribute<? super X, C, E> collection);

所以,恕我直言,这不是你的错,API 出了问题。

需要一个解决方法。只需删除编译时类型(无论如何,它都会在运行时删除)。

你必须做:

Expression<Set<AUser>> createdByExpression = ((Root<AbstractEntity>) (Object) root).get(AbstractEntity_.createdBy);

Expression<Set<AUser>> createdByExpression = root.get((SetAttribute<ConcreteEntity, AUser>) (Object) AbstractEntity_.createdBy);

否则

Expression<Set<AUser>> createdByExpression = root.get("createdBy");

关于jpa - 如何指定具有 "MEMBER IN"的 JPA 标准 API 以及映射父类(super class)中的多对多关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44604886/

相关文章:

java - Criteria API - 具有参数表达式的优点

grails - gorm标准可以受实现域类约束吗?

java - spring hibernate jpa中的多对一关系

hibernate - 具有多个数据库供应商支持的 Java/Maven/JPA/Hibernate 构建的最佳方法?

java - JPQL : Access inherited Attributes in a Query

java - 使用 JPA 从子对象级联到父对象

grails - Grails-条件构建器-createCriteria

java - 如何加快 JPA 中的列表访问速度

java - 使用 JPA 时如何将 Web 应用程序的数据库从 RDB 更改为 Hadoop?

java - 如何在 wildfly 中激活 JDBC 日志