Hibernate 尝试从 null 一对一属性分配 id

Fee*_*eco 6 java hibernate

我有两个实体:

@Entity
@Table
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "user")
    private UserDetails userDetails;

}

@Entity
@Table(name="user_details")
public class UserDetails {

    @GenericGenerator(name = "generator", strategy = "foreign",
        parameters = @Parameter(name = "property", value = "user"))
    @Id
    @GeneratedValue(generator = "generator")
    @Column(unique = true, nullable = false)
    private Integer id;

    @OneToOne
    @PrimaryKeyJoinColumn
    private User user;

    public UserDetails(User user) {
        this.user = user;
        user.setUserDetails(this);
    }

}
Run Code Online (Sandbox Code Playgroud)

如果我使用 userDetails 创建用户,它会起作用。但随后它创建了一个 UserDetails 行,我不想要它。我必须从数据库中获取一个 User 并稍后添加一个 UserDetails :

userRepository.findOneById(id).map(user -> {
    UserDetails userDetails = user.getUserDetails();
    if (userDetails == null)
        userDetails = new UserDetails(user); 
     userDetails.setEmail(email);
     userRepository.save(user); //error here
});
Run Code Online (Sandbox Code Playgroud)

错误

org.springframework.orm.jpa.JpaSystemException: 试图从空一对一属性 [com.app.domain.UserDetails.user] 分配 id;嵌套异常是 org.hibernate.id.IdentifierGenerationException:试图从 null 一对一属性 [com.app.domain.UserDetails.user] 分配 id

Tre*_*vor 8

UserDetails在这种情况下,对象是 aUser和 the之间关系的拥有方UserDetails

受管实体之间的双向关系将基于关系拥有方持有的引用而持久化。

因此,当您说 时userRepository.save(user),您实际上是在尝试从关系的孩子方面进行挽救。

您需要创建一个UserDetailsRepository并从该新对象调用保存。

即这里的代码应该是这样的:

userRepository.findOneById(id).map(user -> {
    UserDetails userDetails = user.getUserDetails();
    if (userDetails == null)
        userDetails = new UserDetails(user); 
     userDetails.setEmail(email);
     userDetailsRepository.save(userDetails);
});
Run Code Online (Sandbox Code Playgroud)

  • 我想知道,为什么 UserDetails 在这种情况下是拥有方?通常它往往是用户(在本例中),如“mappedBy”所指定。 (13认同)