2

I'm a little confused with bidirectional OneToOne relationship, which may not be optional on both ends. I'm using JPA2 with Hibernate:

@Entity
@Table(name = "city")
public class City {

    @Id
    @GeneratedValue
    @Column
    public Long _UID;

    @OneToOne(mappedBy="city", optional=false, orphanRemoval = true, cascade=CascadeType.ALL)
    public Mayor mayor;
}

@Entity
@Table(name = "mayor")
public class Mayor {

    @Id
    @GeneratedValue
    @Column
    public Long _UID;

    @OneToOne(optional=false, cascade=CascadeType.ALL)
    public City city;
}

And if I try this transaction:

Mayor m = new Mayor("Ed", "Lee");
City c = new City("San Francisco", 100000);
m.setCity(c);
c.setMayor(m);

EntityTransaction et = this.getEm().get().getTransaction();
et.begin();

this.getEm().get().persist(c);
this.getEm().get().flush();

et.commit();

I get following exception:

javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: test.persistence.entity.Mayor.city

If I inspect City instance before it get persisted, it has a Mayor instance on a right place and this Mayor instance has a relationship set back to the City instance.

With optional=false only on the City side all is ok.

4

1 回答 1

1

This is because you have a circular dependency on your mapping with cascadeAll on both side.

What happens there is that you are saving your city which save your mayor which then save your city which is not persisted yet (as you are trying to save it in the first place) and therefore hibernate does not know how to make reference to the city in DB.

You should try to fine tune the cascading of your city field in the mayor class to remove the cascade type persist.

[Edit] it seems also that the responsible of the relationship is the mayor (as the mappedby is in the city class). I think, as you are trying to persist the city, that the city should be responsible of the relationship (and therefore the mappedBy attribute should be in the mayor class)

于 2013-02-26T11:25:52.120 回答