简体   繁体   English

Hibernate使用@ManyToMany双向关系导致无限循环

[英]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_idobject_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_mappingBucket创建第二条记录,并在Model上创建第二条记录

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM