org.springframework.dao.InvalidDataAccessApiUsageException:org.hibernate.loader.MultipleBagFetchException:无法同时获取多个行李:[Order.items,OrderItem.options];
以上是我加入三个表时遇到的例外情况。
order item option.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;
}
order item.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;
}
order.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对象,以便我可以通过订单对象访问过滤后的子项。并且关系的类型应该是List,而不是Set。
例如,order.getItems()。get(0).getOptions.get(0)
我怎样才能实现这一目标?
为避免上述异常,有两种可能性:
List
改为Set
要么List
但不要拿两个袋子。这意味着不要在两个集合中使用fetchJoin()
。过滤:
使用条件集合的地方不会被过滤。集合将包含所有关联的对象。加入JPA是为了在根对象上创建条件 - Order。它与SQL中的不同。
可以使用JPA 2.1 JOIN ON
功能过滤关联的集合。这允许ON
条款中的附加条件
如果你真的不能使用Set而不是List:
Parent.class
@OneToMany(
mappedBy = "parent",
orphanRemoval = true,
cascade = { CascadeType.PERSIST, CascadeType.MERGE }
)
@OrderColumn(name = "position")
private List<Child> childs = new ArrayList<>();
Child.class
@ManyToOne(fetch = FetchType.LAZY)
private Parent parent;
并在Child的表中创建一个名为“position”的列
ALTER TABLE child ADD COLUMN position integer NOT NULL default 0
如果您不能在表中使用其他列,则需要按顺序查询列表。或者使用孩子的id和自定义的getter。
@OrderColumn(name = "id_child", updatable = false, insertable = false)
public List<Child> getChilds() {
childs.removeAll(Collections.singleton(null));
return childs;
}