具有两个以上 OneToMany 字段的 Hibernate 实体
Hibernate entity with more than two OneToMany fields
我有以下休眠实体:
@Entity
public class Customer {
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Address> addresses = new ArrayList<>();
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Contact> contacts = new ArrayList<>();
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Name> names = new ArrayList<>();
// Many more, including a primary key
}
启动应用程序,出现以下异常:
org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
如果我删除一个任意 OneToMany
关联,或者如果我向任意 OneToMany
关联添加一个 @Fetch(value = FetchMode.JOIN)
,一切正常。
这是休眠错误、休眠限制还是我的实体有问题? TIA!
这不是错误。这是因为 Hibernate 使用一个 select 和一个连接来获取所有数据。 Hibernate 可以连接三个或更多的表,但是连接的结果会有重复,例如 Address
列。 Hibernate 需要删除重复项——这是 Set
起作用的原因。
可能的解决方法:
- 使用
Set<Address>
而不是 List<Address>
。您应该对所有集合使用 Set
。
- 使用惰性抓取
fetch = FetchType.LAZY
- 使用
@Fetch(value = FetchMode.SUBSELECT)
补充阅读:
尝试使用:
@OneToMany
@LazyCollection(value=LazyCollectionOption.TRUE)
private Collection<Name> names = new ArrayList<>();
我有以下休眠实体:
@Entity
public class Customer {
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Address> addresses = new ArrayList<>();
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Contact> contacts = new ArrayList<>();
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Name> names = new ArrayList<>();
// Many more, including a primary key
}
启动应用程序,出现以下异常:
org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
如果我删除一个任意 OneToMany
关联,或者如果我向任意 OneToMany
关联添加一个 @Fetch(value = FetchMode.JOIN)
,一切正常。
这是休眠错误、休眠限制还是我的实体有问题? TIA!
这不是错误。这是因为 Hibernate 使用一个 select 和一个连接来获取所有数据。 Hibernate 可以连接三个或更多的表,但是连接的结果会有重复,例如 Address
列。 Hibernate 需要删除重复项——这是 Set
起作用的原因。
可能的解决方法:
- 使用
Set<Address>
而不是List<Address>
。您应该对所有集合使用Set
。 - 使用惰性抓取
fetch = FetchType.LAZY
- 使用
@Fetch(value = FetchMode.SUBSELECT)
补充阅读:
尝试使用:
@OneToMany
@LazyCollection(value=LazyCollectionOption.TRUE)
private Collection<Name> names = new ArrayList<>();