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

“多袋取出例外:连接三个深度表时无法同时取出多个包”

漆雕和雅
2023-03-14

无效数据访问设备别名:org.hibernate.loader.多个包取出异常:无法同时获取多个包: [订单项, 订单项选项];

上面是我加入下面三个表时遇到的一个例外。

OrderItemOption.java

@Entity
public class OrderItemOption {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "item_option_id")
  private Long id;

  @Column(name = "item_id", nullable = false)
  private Long itemId;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(
      name = "item_id",
      referencedColumnName = "item_id",
      insertable = false,
      updatable = false
  )
  private OrderItem orderItem;
}

订单项.java

@Entity
public class OrderItem {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "item_id")
  private Long id;

  @Column(name = "order_id", nullable = false)
  private Long orderId;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(
      name = "order_id",
      referencedColumnName = "order_id",
      insertable = false,
      updatable = false,
      nullable = false
  )
  private Order order;

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "orderItem")
  @OrderBy("item_option_id ASC")
  private List<OrderItemOption> options;
}

订单.java

@Entity
public class Order {
  @Id
  @Column(name = "order_id", nullable = false)
  private Long id;

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "order")
  @OrderBy("item_id ASC")
  private List<OrderItem> items;
}

这是我一次性加入它们的QueryDSL代码。

final QOrder order = QOrder.order;
final QOrderItem item = QOrderItem.orderItem;
final QOrderItemOption option = QOrderItemOption.orderItemOption;

from(order)
.leftJoin(order.items, item).fetchJoin()
.leftJoin(item.options, option).fetchJoin()
.where(
    order.id.eq(orderId)
        .and(item.id.in(itemIds))
        .and(option.id.in(optionIds))
)
.fetchOne())

我想做的是获得包含过滤关系的order对象,这样我就可以通过Order对象访问过滤的子对象。并且关系的类型应该是列表,而不是集合。

例如,order.getItems().get(0).getOptions.get(O)

我怎样才能实现这个目标?

共有2个答案

柯耀
2023-03-14

如果您确实无法使用Set代替List:

父.class

@OneToMany(
    mappedBy = "parent",
    orphanRemoval = true,
    cascade = { CascadeType.PERSIST, CascadeType.MERGE }
)
@OrderColumn(name = "position")
private List<Child> childs = new ArrayList<>();

子类.class

@ManyToOne(fetch = FetchType.LAZY)
private Parent parent;

并在儿童表中创建一个名为“位置”的列

ALTER TABLE child ADD COLUMN position integer NOT NULL default 0

如果您不能使用表中的其他列,则需要按顺序查询列表。或者使用子ID和自定义getter。

@OrderColumn(name=“id_child”,updatetable=false,insertable=false)

public List<Child> getChilds() {
    childs.removeAll(Collections.singleton(null));
    return childs;
}
帅博远
2023-03-14

为了避免上述例外,有两种可能性:

  1. 列表更改为Set
  2. 使用列表,但不要取出两个袋子。这意味着不要对两个集合都使用fetchJoin()

过滤:

使用将不筛选的where条件集合。集合将包含所有关联对象。加入JPA是为了在根对象Order上创建条件。它与SQL中的不同。

可以使用JPA 2.1JOIN ON功能过滤相关集合。这允许ON子句中的附加条件

参见示例QueryDSL Left Join with additional conditions in ON

 类似资料:
  • 问题内容: 我们有一个项目,需要延迟加载实体的集合,但是在某些情况下,我们需要热切地加载它们。我们已经为实体添加了注释。在我们的存储库方法中,我们添加了一个“ javax.persistence.loadgraph”提示来热切加载上述注释中定义的4个属性。当我们调用该查询时,Hibernate抛出。 有趣的是,当我重新定义所有这些集合时,Hibernate 确实不 使用MultipleBagFet

  • 问题内容: 以下是我的代码在这里,我使用多个列表从数据库中获取数据。从hql查询中获取数据时显示异常。 Pojo课 hmb.xml文件 HQL查询 我正在尝试以下查询从数据库中获取数据,但这显示了 如何解决此问题 问题答案: 这是一个非常常见的问题,所以我决定将答案变成一篇文章。 Hibernate不允许获取一个以上的包,因为这会生成Cartesian。 现在,您会发现很多答案,博客文章,视频或其

  • 我有以下实体 注册程序 教练 官方 基本上,我有与(Trainer-Register steredProgram,官方注册程序)有多对一关系的实体。现在我有一个服务已经满足了我的要求,通过id获取注册程序,我应该只包含所有的和与isDeletedfalse。请参阅下面的服务: 服务 现在,我尝试使用< code>@Query和< code>@EntityGraph,这样我就可以只使用一个查询就获得

  • 问题内容: Hibernate在创建SessionFactory时抛出此异常: org.hibernate.loader.MultipleBagFetchException:无法同时获取多个包 这是我的测试用例: Parent.java Child.java 这个问题怎么样?我能做什么? 编辑 好的,我的问题是另一个“父”实体在我的父内部,我的真实行为是这样的: Parent.java Anoth

  • 这是在收到以db为单位的帖子列表后发送带有每个帖子链接数据的POST请求的代码。 在使用每个链接请求帖子后,从回复中提取playerCount并将其更新到每个帖子。 我在这段代码中使用Resttemplate,但有一个问题需要花费太长时间。 所以我想把这个代码改为一次发送一个请求,并在所有请求完成后更新每个帖子。 我怎样才能把这个代码转换成我想要的? 我将使用此代码作为计划任务。

  • 问题内容: 在创建时抛出此异常: 无法同时获取多个包 这是我的测试用例: Parent.java 这个问题怎么样?我能做什么? 编辑 好的,我的问题是另一个“父”实体在我的父内部,我的真实行为是这样的: Parent.java AnotherParent.java Hibernate不喜欢带有的两个集合FetchType.EAGER,但这似乎是一个错误,我没有做不寻常的事情… FetchType.