我有这样的实体结构
@MappedSuperclass
public abstract class Base {
UUID id;
}
@MappedSuperclass
public abstract class Parent<C extends Child> extends Base {
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<C> children;
}
@MappedSuperclass
public abstract class Child<P extends Parent> extends Base {
@JoinColumn(name = "parent_id", referencedColumnName = "id")
@ManyToOne(optional = false)
private P parent;
}
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "ap")
public class AP extends Parent<AC> {}
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "ac")
public class AC extends Child<AP> {}
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "bp")
public class BP extends Parent<BC> {}
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "bc")
public class BC extends Child<BP> {}
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "cp")
public class CP extends Parent<CC> {}
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "cc")
public class CC extends Child<CP> {
String value;
}
我做标准查询
CriteriaQuery<Long> cq = getEntityManager().getCriteriaBuilder().createQuery(Long.class);
Root<CP> rt = cq.from(CP.class);
Path child = rt.join("children");
final CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
cq.select(criteriaBuilder.count(rt));
cq.where(criteriaBuilder.equal(child.get("value"), "exists"));
TypedQuery<Long> q = getEntityManager().createQuery(cq);
Long res = q.getSingleResult()
并在where子句中获取错误:
java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [value] on this ManagedType [Base]
经过一段时间的调试后,我发现实体管理器元模型中的父元类将属性子元素保存为AC列表。 AC显然不包含字段“值”。
知道如何修复此错误吗?
答案 0 :(得分:0)
我认为没有简单的解决办法。除非您愿意将value
移至AC
并使CC
延长AC<CP>
。或类似的东西。
此行为是因为类型擦除。
children
的实际泛型类型在运行时不可用,因为编译器根据上限List<AC>
将列表转换为泛型类型AC
。
另见great answer这对我说的很好。
在查询之后,可以检查并将列表/项目转换为实际类型,但在CriteriaQuery
内是否可以确定是否可行。