Spring Boot JPA - OneToMany relationship causes infinite loop

前端 未结 5 1268
走了就别回头了
走了就别回头了 2021-01-12 06:34

I have a two objects with simple @OneToMany relationship which looks as follows:

parent:

@Entity
public class ParentAccount {

  @Id
  @GeneratedValu         


        
相关标签:
5条回答
  • 2021-01-12 06:50

    I recently had this issue due to a poorly defined Jackson2HttpMessageConverter.

    I had done something like the following.

    @Bean
    RestTemplate restTemplate(@Qualifier("halJacksonHttpMessageConverter")
                                      TypeConstrainedMappingJackson2HttpMessageConverter halConverter) {
        final RestTemplate template = new RestTemplateBuilder().build();
        halConverter.setSupportedMediaTypes(List.of(/* some media types */)); 
        final List<HttpMessageConverter<?>> converters = template.getMessageConverters();
        converters.add(halConverter);
        template.setMessageConverters(converters);
        return template;
    }
    

    This caused a problem because the media types did not include all the defaults. Changing it to the following fixed the issue for me.

    halConverter.setSupportedMediaTypes(
        new ImmutableList.Builder<MediaType>()
            .addAll(halConverter.getSupportedMediaTypes())
            .add(/* my custom media type */)
            .build()
    );
    
    0 讨论(0)
  • 2021-01-12 06:51

    Problem solved. I was using a custom @toString method in the LinkedAccount which was referencing the ParentAccount. I had no idea that this could cause any problem and therefor I did not include the toString in my question.

    Apparently, this was causing an infinite loop of lazy loading and removing this reference fixed the problem.

    0 讨论(0)
  • 2021-01-12 07:05

    As the first answer suggests:

    Do not use Lombok's @Data annotation on @Entity classes.

    Reason: @Data generates hashcode(), equals() and toString() methods that use the generated getters. Using the getter means of course fetching new data even if the property was marked with FetchType=LAZY.

    Somewhere along the way hibernate tries to log the data with toString() and it crashes.

    0 讨论(0)
  • 2021-01-12 07:09

    Something like this does not work?

    @Entity
    public class Account {
    
        @Id
        @GeneratedValue
        private long id;
        private String name;
    
        @ManyToOne(cascade={CascadeType.ALL})
        @JoinColumn(name="manager_id")
        private Account manager;
    
        @OneToMany((fetch = FetchType.EAGER, mappedBy="manager")
        private Set<Account> linkedAccounts = new HashSet<Account>();
    
    }
    
    0 讨论(0)
  • 2021-01-12 07:13

    As user1819111 told, @Data from Lombok is not compatible with @Entity and FetchType=LAZY. I had used Lombok.Data (@Data) and I was getting this error.

    As I don't want do create all get/set, I just put the Lombok @Setter and @Getter in your class and all will work fine.

    @Setter
    @Getter
    @Entity
    @Table(name = "file")
    @SequenceGenerator(name = "File_Sequence", allocationSize=1, sequenceName = "file_id_seq")
    public class MyClass{
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "File_Sequence")
        @Column(name = "id")
        private Long id;
    
        @Column(name = "name")
        private String name;
    
        @OneToMany(mappedBy = "file", cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
        private Set<Base2FileDetail> details = new HashSet<>();
    }
    
    0 讨论(0)
提交回复
热议问题