我试图用 JPA 实体实现代沟模式。这是我们选择的解决方案( <-- 是继承)
BaseEntity <-- EntityGenerated <-- Entity
EntityGenerated 类型是抽象的,并使用@MappedSuperclass 进行映射,所有字段均使用正确的映射注释生成,关系指向具体的子类,而不是 Generated 的。
Entity 是一个具体类型,仅在类不存在时生成,最初只有使用@Entity 注释的类声明。@Table 等其他映射属性在生成的 orm.xml 中。
现在,当我们生成 jpa 静态元模型(使用 hibernate 或 openjpa 元模型生成器)时,生成的类如下所示:
public class BaseEntity_ {
public static volatile SingularAttribute<PersistentDomainObject,Long> id;
public static volatile SingularAttribute<PersistentDomainObject,Long> timeStamp;
}
public class UserGenerated_ extends BaseEntity_ {
public static volatile SetAttribute<UserGenerated,Group> groups;
}
public class User_ extends UserGenerated_ {
}
如果我想在 jpa 条件查询中使用 User_,我将执行以下操作:
CriteriaQuery<User> query = criteriaBuilder.createQuery(User.class);
Root<User> root = query.from(User.class);
query.where(root.get(User_.groups).in(paramGroups));
但它不会编译.... User_.groups 是 SetAttribute 类型,get 方法的 jpa 路径 api 是:
<E, C extends java.util.Collection<E>> Expression<C> get(PluralAttribute<X, C, E> collection);
(相比之下,奇异属性的get方法是
<Y> Path<Y> get(SingularAttribute<? super X, Y> attribute)
女巫工作更好)
所以,现在,问题是:
为什么元模型生成器生成 MappedSuperclass 的类,因为没有办法直接查询它?,应该在每个子类中定义超类的属性和关系(其中 X 是子类类型)
为什么 jpa 标准 Path api 没有将复数属性的 get 方法定义为
get(PluralAttribute<? super X, C, E> collection)
?
如何在不放弃条件查询的情况下在 JPA 实体上实现代沟模式?
谢谢