【问题标题】:org.hibernate.id.IdentifierGenerationException: "attempted to assign id from null one-to-one property"org.hibernate.id.IdentifierGenerationException:“尝试从空的一对一属性分配 id”
【发布时间】:2019-11-28 16:04:49
【问题描述】:

当我尝试使用 Spring Boot 2.1.6.RELEASE 和 Spring Data JPA 将用户对象保存到数据库时遇到问题。

  1. 用户对象和详细信息对象具有双向的一对一关系。
  2. detail 的 id 与用户的 id 有一个外键(用户的 id 是自增的)。
  3. 用户信息是从json格式映射到带有@RequestBody的对象。

json:

{"name" : "Jhon",
    "detail":
    {
        "city" : "NY"
    }
}

userController.java:

...
@PostMapping(value="/user")
public Boolean agregarSolicitiud(@RequestBody User user) throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
    userRepository.save(user);
...

用户.java:

...
@Entity
public class User {

    @Id
    @Column(updatable=false, nullable=false, unique=true)
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @Column
    private String name;

    @OneToOne(mappedBy =     "solicitud",optional=false,cascade=CascadeType.ALL)
    private UserDetail userDetail;
}

UserDetail.java:

...
@Entity
public class UserDetail {

    @Id
    @Column
    private Long id;

    @Column
    private String city;

    @MapsId
    @OneToOne(optional = false,cascade = CascadeType.ALL)
    @JoinColumn(name = "id", nullable = false)
    private User user;
}

userRepository.java

...
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
...

错误:

 org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [proyect.model.Detail.user]

我能做什么?

谢谢

【问题讨论】:

  • 阅读错误信息。 UserDetail 的 ID 应该来自其用户字段。并且错误消息告诉您使用字段为空。你得出什么结论?我的结论是它是空的,但不应该是。并且您应该因此初始化 UserDetails 的用户字段。
  • @JBNizet 是的,但是 Spring-Data 是否应该使用注释自动执行此操作?
  • @JBNizet 不一定,他可能想一次创建所有实体。
  • 它创建了一个具有 UserDetails 的用户。但是关联是双向的,关联的拥有方是UserDetails.user,UserDetails.user为null。正如错误消息中明确指出的那样,它不能为空。

标签: java spring-boot spring-data-jpa


【解决方案1】:

通过关注这篇文章,我可以保存这两个实体。

https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/

可以把这看作是在不使用持久化提供程序的情况下设置两个 java 类之间的关系。这些属性需要由开发人员手动设置,以便它可以从他想要的方向访问关系。

此代码需要添加到适当绑定 userdetail 的用户实体中

    public void setUserDetail(UserDetail userDetail) {
      if (userDetail == null) {
            if (this.userDetail != null) {
                this.userDetail.setUser(null);
            }
        } else {
            userDetail.setUser(this);
        }
        this.userDetail = userDetail;
    }
````
This code sets the user to the userDetails which is causing the issue.

As mentioned in the comments the deserializer is not able to bind the objects properly.The above code will binds the userDetails.user.


【讨论】:

    猜你喜欢
    • 2021-01-16
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多