Как определить API критериев JPA с "MEMBER IN" и отношением "многие ко многим" в сопоставленном суперклассе?

Я хотел бы запросить ConcreteEntity где AUser userIS MEMBER из 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();

Я не понимаю переход от 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");
Другие вопросы по тегам