1

I have a problem when i try to save the user object to database using Spring Boot 2.1.6.RELEASE and Spring Data JPA.

  1. user object and detail object have a bidirectional one-to-one relation.
  2. The id of detail have a foreign key to id of user(the id of user is autoincrement).
  3. user information is map from json format to a object with @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);
...

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> {
}
...

Error:

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

What can i do?

Thanks

  • Possible duplicate https://stackoverflow.com/a/17379331/7736617 – Arnaud Claudel Jul 19 '19 at 16:45
  • Read the error message. The ID of UserDetail is supposed to come from its user field. And the error message tells you that the use field is null. What do you conclude? I conclude that it's null, but shouldn't be. And that you should thus initialize the UserDetails' user field. – JB Nizet Jul 19 '19 at 16:45
  • @JBNizet yes but Spring-Data is supposed to do it automatically with the annotations, or not? – 4wiz4rdisneverl4te Jul 19 '19 at 17:53
  • @JBNizet not necessarily, he probably wants to create all the entities at once. – Arnaud Claudel Jul 19 '19 at 18:11
  • @Arnaud and how would that prevent to initialize a field of an object? – JB Nizet Jul 19 '19 at 19:47
  • @Lucas no. It's your responsibility to populate the objects you want to save before saving them. – JB Nizet Jul 19 '19 at 19:48
  • @JBNizet The deserialization does it, it creates a User + a UserDetail, both without any id – Arnaud Claudel Jul 19 '19 at 19:49
  • 1
    It creates a User which has a UserDetails. But the association is bidirectional, and owning side of the association is UserDetails.user, and UserDetails.user is null. It must not be null, as the error message clearly says. – JB Nizet Jul 19 '19 at 19:56
  • @JBNizet I'll dig it later but I don't think that we should be forced to initialize it. – Arnaud Claudel Jul 19 '19 at 20:11

1 Answers1

1

By following this post I am able to save both the entities.

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

Think of this as setting a relationship between the two java classes without using the persistence provider.These properties need to be set manually by the developer so that it can access the relation from the direction he wants.

This code needs to be added to the user entity which binds the userdetail appropriately

    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.


user06062019
  • 681
  • 4
  • 9