Tiago Pimenta
Tiago Pimenta

Reputation: 746

One-to-One ids must be manually assigned

I wonder how to make Hibernate cascade ids when saving one-to-one entities.

@Entity
@Table(name = "foo")
class Foo {
    @Id
    @Column(name = "foo_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "foo_seq")
    private Integer fooId;

    // ...

    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "foo")
    private Bar bar;

    // ...

    public void setBar(Bar bar) {
        this.bar = bat;
        if (bar != null) {
            bar.setFoo(this);
            bar.setFooId(getFooId());
        }
    }

}

@Entity
@Table(name = "bar")
class Bar {

    @Id
    @Column(name = "foo_id")
    // this is the foo's id, the foreign key is the primary key of this table
    private Integer fooId;

    @OneToOne(fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn
    private Foo foo;

    // ...

}

Well, when I save a instance of Foo without Bar, then set an instance of Bar and save it again it works, but if I try to save it all once it says ids for this class must be manually assigned before calling save.

Foo foo = new Foo();
// foo.set...
repository.save(foo); // I do not want to save twice, I want to remove it
Bar bar = new Bar();
// bar.set...
foo.setBar(bar);
repository.save(foo);

How can I fix this issue? I do not need it to be bidirectional, but this must be possible to get a Bar from a Foo, like discussion in this thread, but this time the id is the same from Foo table.

Upvotes: 0

Views: 756

Answers (1)

Prerak Tiwari
Prerak Tiwari

Reputation: 3466

The reason its behaving like this is because Hibernate is generating the value of fooId at the time it is saving the Entity and not before that. So even if you are assigning the fooId in setBar() method its actually assigning NULL to the Bar.fooId and since you haven't defined and Generation Strategy on Bar.fooId you are getting that error. Modify Bar class as given below and then try again and that error should go away:

 @Id
    @Column(name = "foo_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer fooId;

Upvotes: 1

Related Questions