JPA recursive hierarchy read - StackOverflowError with FetchType.EAGER but LazyInitializationException with FetchType.LAZY
09:04 01 Nov 2025

I'm working with these entities:

UserEntity:

@Entity
@Table (name = "users", uniqueConstraints = @UniqueConstraint(columnNames={"name"}))
public class UserEntity {

    @Id
    @GeneratedValue (strategy = GenerationType.SEQUENCE, generator = "user_id_seq")
    private Long id;

    @Column( name = "name")
    private String name;

    private int level;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
    private Set berryInventory;

BerryInventoryEntity:

@Entity
@Table (name = "berry_inventory")
public class BerryInventoryEntity {

    @Id
    @GeneratedValue (strategy = GenerationType.SEQUENCE, generator = "inventory_id_seq")
    private Long id;

    @ManyToOne (optional = false)
    @JoinColumn (name = "user_id")
    private UserEntity user;

    @ManyToOne (optional = false)
    @JoinColumn (name = "berry_id")
    private BerryEntity berry;

    private int quantity;
}

I'm testing the repository of BerryInventory and I ran into a problem. I created an instance of BerryInventoryEntity and saved it using the repository:

BerryInventoryEntity berryInventory = BerryInventoryEntity.builder()
        .berry(berry)
        .user(user)
        .quantity(1)
        .build();

berryInventoryRepository.save(berryInventory);

Then I used this query to retrieve the BerryInventoryEntity I just saved:

@Query("SELECT b FROM BerryInventoryEntity b WHERE b.user = :user")
Iterable findInventoryOfUser(UserEntity user);

Like this:

Iterable berryInventoryCreated = berryInventoryRepository.findInventoryOfUser(userCreated);

But then U get two different errors depending on the FetchType in the @OneToMany relationship indicated in UserEntity.

If the FetchType is "LAZY" the UserEntity comes with an instance of BerryInventoryEntity that throws the exception:

Method threw 'org.hibernate.LazyInitializationException' exception. Cannot evaluate com.dpr.berry.domain.entities.UserEntity.toString()

But if I change it to "EAGER" then a StackOverFlowError is thrown because UserEntity contains a list of BerryInventoryEntity that also contains UserEntity and so on.

Can I retrieve a BerryInventoryEntity that its UserEntity doesn't also come with a BerryInventoryEntity? What is the correct way of fixing this issue?

java spring-boot jpa spring-data-jpa