Search code examples
javahibernatejpamany-to-onebidirectional

Hibernate: Bidirectional ManyToOne Mapping - inverse relation not working


I have a problem creating a bidirectional mapping of two domain classes.

I have my UserAccount.java which has many AccountTransactions. In the AccountTransaction domain object there's a column user_account_id with a foreign key.

I have set up the mapping the following way:

UserAccount.java

// Other properties 

@ManyToOne(optional = false)
@JoinColumn(name = "user_account_id")
@NotNull
private UserAccount userAccount;

// Getters and setters...

AccountTransaction.java

@OneToMany(cascade=CascadeType.ALL, mappedBy="userAccount")
public List<AccountTransaction> accountTransactions;

The scenario is that I would like to get a list of all userAccounts with their corresponding accountTransactions as a JSON Array, but accountTransactions object is always null.

I have also tried it over a modified Query in the repository:

@Query("SELECT account FROM UserAccount account JOIN FETCH account.accountTransactions WHERE account.user = :systemUser AND account.adminAccount = TRUE")
List<UserAccount> findAllAdminAccountWithTransactions(@Param("systemUser") User systemUser);

When I retrieve the values over this query, it first returns everything correctly in the repository. But then it throws an exception:

c.d.c.w.rest.errors.ExceptionTranslator  : An unexpected error occurred: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.david.coinlender.domain.UserAccount["accountTransactions"]->org.hibernate.collection.internal.PersistentBag[0]->com.david.coinlender.domain.AccountTransaction["userAccount"]

I seem to have an infinite loop somewhere. Can someone please point me to the solution?


Solution

  • Since this is a bidirectional relation jackson will try to serialize each part of the relation from the other part so yeah you will have infinite recursion, to avoid this you need to stop the cycle by either stopping serializing of one side of the relation using @JsonIgnore

     @JsonIgnore
     @ManyToOne(optional = false)
     @JoinColumn(name = "user_account_id")
     @NotNull
     private UserAccount userAccount;
    

    or you could go for another solutions if you care to serialize both sides, check this post for solution to keep serializing both side without infinite recursion