[英]Hibernate causes infinite loop with @ManyToMany bidirectional relation
I have two entities in my project with have a many-to-many relation between them. 我的项目中有两个实体,它们之间具有多对多关系。 The relation is represented using a helper mapping table in postgres which contains the relevant ID for each entity, pretty standard. 该关系使用postgres中的帮助程序映射表表示,该表包含每个实体的相关ID(相当标准)。
Let's call the table bucket_object_mapping
and it has two columns: bucket_id
, object_id
. 我们将其称为表bucket_object_mapping
,它具有两列: bucket_id
, object_id
。
The bucket class: 桶类:
@Entity
@Table(name = "bucket")
public class Bucket {
// Some fields omitted here
@ManyToMany(cascade = {}, fetch = FetchType.LAZY)
@JoinTable(
name = "bucket_object_mapping",
joinColumns = @JoinColumn(name = "bucket_id"),
inverseJoinColumns = @JoinColumn(name = "object_id")
)
private List<Model> models;
}
In the Model
class I have no mapping to the Bucket
class (no need for that) 在Model
类中,我没有映射到Bucket
类(不需Bucket
)
When I run this simple query: 当我运行此简单查询时:
SELECT bucket FROM Bucket bucket WHERE bucket.customerId=:customerId
The data is returned fine at first, but then an infinite loop of queries to the Model
table starts to run and I'm not sure why. 数据一开始会很好地返回,但是随后对Model
表的无限查询循环开始运行,我不确定为什么。 Looks like it's happening when I return the result list through a SpringMVC controller. 当我通过SpringMVC控制器返回结果列表时,这似乎正在发生。 I do convert the Bucket
to a DTO but not the Model
(It's just that the Model
entity does not have any reference to the Bucket
so there's not supposed to be a circular reference problem). 我确实将Bucket
转换为DTO,但没有将Model
(只是Model
实体没有对Bucket
任何引用,因此不应该存在循环引用问题)。
Controller code: 控制器代码:
@RequestMapping(value = "", method = RequestMethod.GET)
@ResponseBody
public List<BucketDTO> getAllByCustomer(@RequestParam(value = "customerid") final Long customerId) {
return bucketService.getAllBucketsForCustomer(customerId);
}
The code in the service: 服务中的代码:
@Transactional
public List<BucketDTO> getAllBucketsForCustomer(final Long customerId) {
List<Bucket> buckets = bucketDao.getBucketsForCustomer(customerId);
List<BucketDTO> result = bucketDtoConverter.toDtoList(buckets);
return result
}
Turns out the problem was originated in the Model
. 原来问题出在Model
。 While Model
does not have any reference to Bucket
it does have a reference to another object with a @OneToMany
annotation (and the referenced object references Model
with @ManyToOne
). 尽管Model
没有对Bucket
任何引用,但它确实具有对带有@OneToMany
批注的对象的引用(并且所引用的对象使用@ManyToOne
引用了Model
)。
I converted everything (Bucket, Model and the 3rd object) to DTOs and now it works. 我将所有内容(Bucket,Model和第3个对象)都转换为DTO,现在可以使用了。 The reason for it to work is because the infinite loop was caused when the jackson lib tried to serialize the result . 之所以起作用,是因为无限循环是在杰克逊库试图序列化结果时引起的 。 Because there was a bidirectional reference from the Model
object to another object it got stuck in an infinite loop trying to serialize those. 因为存在从Model
对象到另一个对象的双向引用,所以它陷入了一个无限循环中,试图对其进行序列化。 By converting to DTO I made sure that only Model
holds a reference to the other object so it solves the issue. 通过转换为DTO,我确保只有Model
拥有对另一个对象的引用,从而可以解决此问题。
You can follow the chat that led to the answer here 您可以在此处关注导致答案的聊天
I thnik you should delete relation from Model (if you have) or add MappedBy. 我想您应该从模型中删除关系(如果有的话)或添加MappedBy。 When you have relation on Model.class
and no @MappedBy
so you create first record on table bucket_object_mapping
for Bucket
and second record for Model
当您在Model.class
上具有关系而没有@MappedBy
,您在表bucket_object_mapping
为Bucket
创建第二条记录,并在Model
上创建第二条记录
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.