Yuk*_*ida 5 hibernate jpa entitygraph
当我有以下实体时。
@Entity
class Article {
@OneToMany
Set<Comment> comments;
}
@Entity
class Comment {
@ManyToOne
User author;
}
Run Code Online (Sandbox Code Playgroud)
并使用 EntityGraph 和静态元模型创建一些视图规范类,如下所示。
class ArticleViewSpec {
/**
* fetch comments and each of comment's author.
*/
public static final Function<EntityManager, EntityGraph<Article>> DETAIL = em -> {
EntityGraph<Article> graph = em.createEntityGraph(Article.class);
Subgraph<Comment> sgComment = graph.addSubgraph(Article_.comments);
sgComment.addAttributeNodes(Comment_.author);
return graph;
};
}
Run Code Online (Sandbox Code Playgroud)
但是上面的类不能被编译,因为预期的类型不是
Subgraph<Comment> sgComment = graph.addSubgraph(Article_.comments);
Run Code Online (Sandbox Code Playgroud)
但
Subgraph<Set<Comment>> sgComment = graph.addSubgraph(Article_.comments);
Run Code Online (Sandbox Code Playgroud)
当我们有扩展的属性时会出现这个问题javax.persistence.metamodel.PluralAttribute。(例如 SetAttribute、ListAttribute)
这种行为显然来自 api 规范。
javax.persistence.EntityGraph#addSubgraph(javax.persistence.metamodel.Attribute<T,X>)
但是,在这些情况下,如何使用 JPA 静态 MetaModel 以可编程方式和类型安全地创建 EntityGraph 呢?
/**
* fetch comments and each of comment's author.
*/
public static final Function<EntityManager, EntityGraph<Article>> DETAIL = em -> {
EntityGraph<Article> graph = em.createEntityGraph(Article.class);
Subgraph<Comment> sgComment =
graph.addSubgraph(Article_.comments.getName(), Comment.class);
sgComment.addAttributeNodes(Comment_.author);
return graph;
};
Run Code Online (Sandbox Code Playgroud)
我遇到了同样的问题,经过一些研究后,我非常确定这是 JPA API中的一个缺陷。
EclipseLink 中的实现似乎做了正确的事情:
public <T> Subgraph<T> addSubgraph(Attribute<X, T> attribute) {
Class type = attribute.getJavaType();
if (attribute.isCollection()) {
type = ((PluralAttribute) attribute).getBindableJavaType();
}
return addSubgraph(attribute.getName(), type);
}
Run Code Online (Sandbox Code Playgroud)
PluralAttribute请注意,当给定a 时,实现如何违反接口的声明:T对于Attributea Collection<something>,该方法实际上并不返回Subgraph<Collection<something>>声明的 a ,而是返回一个实例Subgraph<something>。
在我看来,API 在这方面实际上已经被破坏了,而且似乎没有人关心,因为可能没有多少人使用EntityGraphs和静态元模型,尽管这将是一件好事。
有人应该在某个地方创建一个问题来修复 API 的该部分。
我当前对问题的“修复”是一种EntityGraphBuilder接受SingularAttribute<E,X>并PluralAttribute<E,?,X>允许类型安全创建EntityGraphs 的自定义。基本上,我只是让EntityGraphElements 代表树中的属性或节点,然后通过类型安全的泛型方法将它们插入在一起。这还有一个好处,就是可以将不同的原因EntityGraph和SubGraph接口合并到一个通用 API 下,以便EntityGraph可以创建和使用表示,以及在其他实体图中作为子图重新使用。
我的解决方案可能也适用于 JPA API,它基本上只是将
<T> Subgraph<T> addSubgraph(Attribute<X, T> attribute)
Run Code Online (Sandbox Code Playgroud)
分为两种方法:
<F> EntityGraphElement<F> fetch(SingularAttribute<? super T, F> attr);
Run Code Online (Sandbox Code Playgroud)
和
<F> EntityGraphElement<F> fetch(PluralAttribute<? super T, ?, F> attr);
Run Code Online (Sandbox Code Playgroud)
更新:
使用一些泛型 Voodoo,一种方法就足够了:
<F, A extends Attribute<? super T, ?> & Bindable<F>> EntityGraphElement<F> fetch(A attribute);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
948 次 |
| 最近记录: |