简体   繁体   English

双向@OneToOne级联问题JPA / Hibernate / Spring-Data

[英]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 . 对我来说,我希望我是对的, User实体是父级,因此我可以将其操作级联到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. 保存级联不会传播,我必须先保存bankAccount然后再将其设置为用户。 Am I missing something, should I review my association? 我是否想念某些东西,应该复习我的协会吗? Thanks 谢谢

You specify mappedBy on the wrong side of the relation. 您在关系的错误一侧指定了appedBy。 It should be specified on the inverse (non-owning) side. 应在反(非所有权)侧指定。 As you want the user to save the account the user must be the owner. 您要用户保存帐户时,该用户必须是所有者。

Your mappedBy should be in child entity, which you want to be saved first. 您的mappedBy应该位于您要先保存的子实体中。 So here mapped by should be in BankAccount . 因此,此处所映射的应该在BankAccount Also You should use @JoinColumn in parent entity, so the foreign key of child can be stored in parent table. 另外,您应该在父实体中使用@JoinColumn ,以便子级的外键可以存储在父表中。 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 : 并在BankAccount

@Entity
public class BankAccount implements Serializable {

    @OneToOne( optional = false, fetch = FetchType.LAZY, mappedBy = "bankAccount")
    private User user;
    //...
}

See the similar example here. 请参见此处的类似示例

To complete this post, the cascade operation from child to parent works in this case @OneToOne(optional=false,mappedBy=...) . 为了完成这篇文章,在这种情况下,从子级到父级的级联操作为@OneToOne(optional=false,mappedBy=...) If we set optional=false in the child side, cascading seems to work (at least Cascade.PERSIST ). 如果我们在子端设置optional=false ,级联似乎可以工作(至少是Cascade.PERSIST )。

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

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