javahibernatespring-data-jpaone-to-onecascading

Bidirectional @OneToOne cascade issue JPA/Hibernate/Spring-Data


I have the entities bellow:

@Entity
public class User implements Serializable {

   private String username;

   @OneToOne( optional = false, mappedBy = "user", orphanRemoval = true, fetch = FetchType.LAZY, cascade = CascadeType.ALL )
   private BankAccount bankAccount;
   //.....
}

And:

@Entity
public class BankAccount implements Serializable {

    @OneToOne( optional = false, fetch = FetchType.LAZY )
    @JoinColumn( name = "user", unique = true, referencedColumnName = "username" )
    private User user;
    //...
}

For me, I hope I'm right, User entity is the parent so I can cascade its operations to BankAccount. But when I try this :

User user = new User();
user.setBankAccount(new BanckAccount());
userRepository.save(user);

I have this exception :

org.hibernate.PropertyValueException: not-null property references a null or transient value : org.company.models.User.bankAccount

The save cascading is not propagated and I have to save bankAccount before setting it to the user. Am I missing something, should I review my association? Thanks


Solution

  • Your mappedBy should be in child entity, which you want to be saved first. So here mapped by should be in BankAccount. Also You should use @JoinColumn in parent entity, so the foreign key of child can be stored in parent table. For example:

    @Entity
    public class User implements Serializable {
    
       private String username;
    
       @OneToOne( optional = false, orphanRemoval = true, fetch = FetchType.LAZY, cascade = CascadeType.ALL )
       @JoinColumn(name = "bank_account_id")
       private BankAccount bankAccount;
       //.....
    }
    

    And in BankAccount:

    @Entity
    public class BankAccount implements Serializable {
    
        @OneToOne( optional = false, fetch = FetchType.LAZY, mappedBy = "bankAccount")
        private User user;
        //...
    }
    

    See the similar example here.