JustDanyul
JustDanyul

Reputation: 14054

Chicken or egg type hibernate mapping problem

I got a class with a one-to-one relation. Basically, in "class A" I have a one-to-one relation to "class B". This relation uses a primary key join column. Now my issue is as follows, if I try and create a instance of A, I cant save it because I haven't added a instance of B to it yet. But, I cant create a instance of B because I need the id of A first.

A easy solution would be to make the ID in B the automatically generated one, so I could then create a instance of B before creating a instance of A. However, I'm sure there is a better way of doing this? :)

I can see in the database that hibernate created a additional index on the id column of A, which im guessing is a foreign key constraint. And I can see the the documentation that the XML version of the one-to-one mapping have a attribute to specify if the relation is constrained or not, however, the @OneToOne annotation doesnt seem to have this option? :S

Upvotes: 2

Views: 471

Answers (1)

Andrey
Andrey

Reputation: 6796

It seems you have two relationships between A and B tables (you have: A has a_id, b_id; B has b_id, a_id). To model one to one you need only one relationship. Determine which table is 'main' and then drop column from 'secondary' table (should be: A has a_id, b_id; B has b_id). After that hibernate (and any other schema client) will be able to insert to B first, then to A with reference to B table.

For example for egg and chicken. There are multiple relations between eggs and chickens (one chicken can laid many eggs; one egg can produce one chicken). So for the one to one relationship egg-produces-chicken, it is reasonable to have parent_egg_id column in chicken table, so an egg can be created first and then a chicken with reference to that egg.

Hibernate mapping could look like the following:

In Chicken class:

@OneToOne
@JoinColumn(name = "parent_egg_id")
public Egg getParentEgg() {
    return parentEgg;
}

In Egg class:

@OneToOne(mappedBy = "parentEgg")
public Chicken getChildChicken() {
    return childChicken;
}

Update:

The same thing as constrained in xml, optional property in OneToOne interface will do. It is defaulted to true, so the relationship is nullable by default.

    /** 
     * (Optional) Whether the association is optional. If set 
     * to false then a non-null relationship must always exist.
     */
    boolean optional() default true;

According to your comments rows to A are inserted first. I would consider having dependency from B to A, not from A to B. In this case to create item in A then in B, two insert statements are required (with relation from A to B - additional update A statement is required.).

Upvotes: 2

Related Questions