5

I have 2 entities between which I want to create a relation such that both share their primary keys. And when we commit one entity the other entity should also be committed with the same primary key which was generated for 1st entity.

My 1st entity is User

@Entity
@Table(name = "ENDUSER")
public class User extends LongIdBase implements IActivatable, IUser {

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = UserLoginRecord.class)
    @PrimaryKeyJoinColumn(name = "id")
    private UserLoginRecord userLoginRecord;

My second entity is UserLoginrecord

@Entity
@Table(name = "ENDUSER_TEMP")
public class UserLoginRecord {
    @Id
    @Column(name = "id")
    private Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "name")
    private String name;

I want that when I persist user, a new row for UserLoginRecord should also be created with the same primary as of User.

But while trying to persist, I am getting this error below.

ids for this class must be manually assigned before calling save():
Serafins
  • 1,237
  • 1
  • 17
  • 36
Shruti Rawat
  • 687
  • 6
  • 11
  • 24
  • please see link for a similar question - http://stackoverflow.com/questions/787698/jpa-hibernate-one-to-one-relationship – Atul Jul 11 '14 at 12:45

2 Answers2

10
  1. You get that error because whenever unless specifying an identifier generator, the "assigned" generator will be assumed. The assigned identifier expects you to set the ids manually, so I think you are interested in having the ids generated automatically.

    Try changing it to:

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
  2. The User should be the owner of the user/userLoginRecord association so:

    @Entity
    @Table(name = "ENDUSER")
    public class User extends LongIdBase implements IActivatable, IUser {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
        private Long id;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        @Column(name = "first_name")
        private String firstName;
    
        @Column(name = "last_name")
        private String lastName;
    
    }
    
  3. I think a user can have more UserLoginRecords which means a user will have a one-to-many association to UserLoginRecord and the UserLoginRecord will have a many-to-one association to a User.

  4. Assuming you have a one-to-one relationship between a User and a UserLoginRecord

    The UserLoginRecord looks like:

    @Entity
    @Table(name = "ENDUSER_TEMP")
    public class UserLoginRecord {
    
        @Id 
        @Column(name="userId", unique=true, nullable=false)
        private Long userId;
    
        @OneToOne(cascade = CascadeType.ALL)
        @JoinColumn(name="userId")
        @MapsId
        private User user;
    
  5. For a bidirectional one-to-one association the User may also contain:

        @OneToOne(mappedBy = "user")
        private UserLoginRecord userLoginRecord;
    

    If you go for a bidirectional association don't forget to set both sides prior to saving:

        user.setUserLoginRecord(userLoginRecord);
        userLoginRecord.setUser(user);
    

    Even if the userLoginRecord.user side is the owner of this association and the user.userLoginRecord is the "inverse" side.

Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
0

2021 JPA answer : Paragraph 4.2 here explains this clear and simple