当前位置: 首页 > 知识库问答 >
问题:

JPA选择关联并使用NamedEntityGraph

胡国兴
2023-03-14
select user.groups
from User user
where user.id = ?1
@Entity
@NamedEntityGraph(name = User.ENTITY_GRAPH,
    attributeNodes = {
        @NamedAttributeNode(User.Fields.permissions),
        @NamedAttributeNode(value = User.Fields.groups, subgraph = "user-groups-subgraph")
    },
    subgraphs = @NamedSubgraph(
        name = "user-groups-subgraph",
        attributeNodes = {
            @NamedAttributeNode(Group.Fields.permissions)
      }
    ))
public class User {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  
  @Enumerated(EnumType.STRING)
  @ElementCollection(targetClass = Permission.class)
  @CollectionTable(name = "USERS_PERMISSIONS", joinColumns = @JoinColumn(name = "uid"))
  private Set<Permission> permissions = EnumSet.of(Permission.ROLE_USER);
  
  @ManyToMany(fetch = LAZY)
  private Set<Group> groups = new HashSet<>();
}


@Entity
@NamedEntityGraph(name = Group.ENTITY_GRAPH,
    attributeNodes = {
        @NamedAttributeNode(value = Group.Fields.permissions)
    })
public class Group {

  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE)
  private Long id;
  
  @Enumerated(EnumType.STRING)
  @ElementCollection(targetClass = Permission.class)
  @CollectionTable(
      name = "GROUPS_PERMISSIONS",
      joinColumns = @JoinColumn(name = "gid")
  )
  @NonNull
  private Set<Permission> permissions = EnumSet.noneOf(Permission.class);
}
org.hibernate.QueryException:
  query specified join fetching, but the owner of the fetched association was not present in the select list
  [FromElement{explicit,collection join,fetch join,fetch non-lazy properties,classAlias=user,role=foo.bar.User.permissions,tableName={none},tableAlias=permission3_,origin=null,columns={,className=null}}]

我首先尝试了用户图,但是由于我们要获取组,所以我尝试了组图。同样的例外。

问题是,没有简单的方法向生成的查询添加fetch join,因为我不知道应该加入关联的哪些属性。我必须加载Entitygraph,遍历它和任何子图,并生成正确的join子句。

关于查询生成的更多细节:

// QueryDsl 4.3.x Expressions, where propType=Group.class, entityPath=User, assocProperty=groups
final Path<?> expression = Expressions.path(propType, entityPath, assocProperty);

// user.id = ?1
final BooleanExpression predicate = Expressions.predicate(Ops.EQ, idPath, Expressions.constant(rootId));

// QuerydslJpaPredicateExecutor#createQuery from Spring Data JPA
final JPQLQuery<P> query = createQuery(predicate).select(expression).from(path);

// Add Fetch Graph
((AbstractJPAQuery<?, ?>) query).setHint(GraphSemantic.FETCH.getJpaHintName(), entityManager.getEntityGraph(fetchGraph));
// em is EntityManager
List gs = em
                .createQuery("SELECT u.groups FROM User u WHERE u.id = ?1")
                .setParameter(1, user.getId())
                .setHint(GraphSemantic.FETCH.getJpaHintName(), em.getEntityGraph(Group.ENTITY_GRAPH))
                .getResultList();

queryException:查询指定了连接提取,但是提取的关联的所有者不在选择列表中

共有1个答案

丌官星渊
2023-03-14

因此,这个问题可以归结为一个整体图属性的解析问题:

select user.groups
from User user
where user.id = ?1

用实体图

EntityGraph<Group> eg = em.createEntityGraph(Group.class);
eg.addAttributeNodes(Group.Fields.permissions);

提供一个异常,该异常显示Hibernate试图获取user.permissions而不是group.permissions。这是错误报告。

 类似资料:
  • 问题内容: 我想更好地了解之间的区别 (1)传统的 多值关系/关联 和 (2) 可嵌入(和基本)类型 的JPA2 集合 我看到了语法上的差异,但想知道是否还会 影响性能 。在后台,数据库实现看起来非常相似。 凭直觉,我通常会使用for 组成方案 。但是即使那样感觉也很相似。 我在这里错过了本质吗?在某些方面,一个比另一个更有效吗? 谢谢你J 问题答案: 凭直觉,我通常将@ElementCollec

  • 所以我正在使用PHP和MySQL制作一个简单的电影数据库。我有两张桌子: 电影 电影类型

  • 问题内容: 我只需要从数据库中得到一个结果。如何使用JPA做到这一点? 我试过了 “从表t中选择t” 但是没有用 还有其他想法吗? 问题答案: 这样尝试 它应该工作 更新* 您也可以这样尝试

  • 我试图使用jpa组件来选择从标题中获取的id。我在文档中找到了一个使用本机select查询的示例: 我试图用${header.id}替换“1”常量: 这似乎不管用,我明白了: 也许还有别的方法可以让它发挥作用?

  • 有人知道如何使用Spring数据JPA获得一个列吗?我在我的Spring Boot项目中创建了一个存储库,如下所示,但总是得到

  • 问题内容: 我是来自python背景的Golang的新手,所以尝试了解新的和不同的概念。我正在尝试创建相关字段,然后从数据库中选择它们。 楷模: 创建表和行并从数据库中选择 打印: 两个问题: 为什么我需要选择creditCard作为单独的变量而不是使用点符号? 我在公司上遇到错误,并且没有点符号或相关工作。我该如何取回? 问题答案: 根据文件,你需要设置以进行自动预加载工作。因此,将检索用户的行