gpt4 book ai didi

hibernate - JPA EntityGraph,使用静态元模型以编程方式创建 PluralAttribute 的子图

转载 作者:行者123 更新时间:2023-12-03 07:43:48 25 4
gpt4 key购买 nike

当我有以下实体时。

@Entity
class Article {
@OneToMany
Set<Comment> comments;
}

@Entity
class Comment {
@ManyToOne
User author;
}

并使用 EntityGraph 和静态元模型创建一些 View 规范类,如下所示。

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;
};
}

但是上面的类无法编译,因为预期类型不是

Subgraph<Comment> sgComment = graph.addSubgraph(Article_.comments);

但是

Subgraph<Set<Comment>> sgComment = graph.addSubgraph(Article_.comments);

当我们有扩展 javax.persistence.metamodel.PluralAttribute 的属性时,就会出现此问题。 (例如SetAttribute、ListAttribute)

这种行为显然来自 API 规范。 javax.persistence.EntityGraph#addSubgraph(javax.persistence.metamodel.Attribute<T,X>)

但是在这种情况下,如何使用 JPA 静态元模型以可编程且类型安全的方式创建 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;
};

最佳答案

我遇到了同样的问题,经过一些研究后,我非常确定这是 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);
}

请注意,当 PluralAttribute 时,实现如何违反接口(interface)的声明。给出:与 T Attribute的是 Collection<something> ,该方法实际上没有返回 Subgraph<Collection<something>>如声明的那样,但只是 Subgraph<something> 的一个实例相反。

在我看来,API 在这方面实际上已经被破坏了,而且似乎没有人关心,因为可能没有多少人使用 EntityGraph s 静态元模型,尽管这是一件好事。

有人应该在某个地方创建一个问题来修复 API 的该部分。

我当前对问题的“修复”是一种自定义 EntityGraphBuilder它接受 SingularAttribute<E,X>PluralAttribute<E,?,X>允许类型安全地创建 EntityGraph s。基本上,我只有我的EntityGraphElement s 表示属性或树中的节点,并通过类型安全的泛型方法将它们插入在一起。这还有一个好处就是可以出于任何原因合并不同的 EntityGraphSubGraph通用 API 下的接口(interface),因此 EntityGraph可以创建和使用表示,也可以将其重新用作其他实体图中的子图。

我的解决方案也可能适用于 JPA API,它基本上只是分割了

<T> Subgraph<T> addSubgraph(Attribute<X, T> attribute)

分为两种方法:

<F> EntityGraphElement<F> fetch(SingularAttribute<? super T, F> attr);

<F> EntityGraphElement<F> fetch(PluralAttribute<? super T, ?, F> attr);

更新:

使用一些泛型 Voodoo,一个方法就足够了:

<F, A extends Attribute<? super T, ?> & Bindable<F>> EntityGraphElement<F> fetch(A attribute);

关于hibernate - JPA EntityGraph,使用静态元模型以编程方式创建 PluralAttribute 的子图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45409305/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com