2017-06-17 107 views
1

我想查询的ConcreteEntity.createdByConcreteEntity其中AUser userIS MEMBER如何使用“MEMBER IN”指定JPA标准API并在映射的超类中指定多对多关系?

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

我没有从SetAttribute转换到PluralAttribute。我知道我不应该用无法编译的代码发布问题,但尽管我会说我对泛型有一个公正的理解,但我不明白。我在https://github.com/krichter722/jpa-criteria-api-metamodel-member-of提供了一个示例项目。

我正在使用Eclipselink 2.5.2和JPA 2.1。

回答

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"); 
+0

我验证的参考SSCCE(这种变化对分支'提出-API change' )。在2012年的jpa-spec列表上有一个关于这个问题的暗示](http://download.oracle.com/javaee-archive/jpa-spec.java.net/users/2012/11/0523.html)这简直被忽视 - 这就是为什么你需要问题跟踪器来跟踪问题,孩子。我问了新的清单[email protected]他们对这个问题的看法 - 但不能在这里发布链接,但是,因为 - 惊喜的电子邮件档案没有像猜测那样的直接链接... - 问题跟踪器。 –

+0

该问题已在官方问题跟踪器中报告,网址为https://github.com/javaee/jpa-spec/issues/108。 –

+0

我是你链接的bug报告的作者:)正如你所看到的,我在2015年4月28日创建了它(在旧的JIRA上),它也被忽略了。如果您没有花时间处理报表,则拥有问题跟踪器是没有用的... –

相关问题