Reputation: 347
I have the following Situation:
OrganisationEntity.java
@Entity
@Table(name = "organisation")
public class OrganisationEntity {
// ...
private PersonEntity contactPerson;
// ...
@OneToOne
@JoinColumn(name = "contact_person_id", referencedColumnName = "id", nullable = false)
public PersonEntity getContactPerson() {
return contactPerson;
}
public void setContactPerson(PersonEntity contactPerson) {
this.contactPerson = contactPerson;
}
// ...
}
ContactPerson.java
@Entity
@Table(name = "person")
public class PersonEntity {
private int id;
// ...
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
// ...
}
On the database the table Organisation has a non-nullable foreign key to Person. The entity mapping is uni-directional New when I want the persist a new pair of records (one organisation and one person) with merge
on the OrganisationEntity
I get the following error:
17:10:19.827 WARN [http-nio-8080-exec-2] [org.hibernate.action.internal.UnresolvedEntityInsertActions] [144] HHH000437: Attempting to save one or more entities that have a non-nullable association with an unsaved transient entity. The unsaved transient entity must be saved in an operation prior to saving these dependent entities.
Unsaved transient entity: ([ch.freiwilligenarbeit_sempach.entity.PersonEntity#0])
Dependent entities: ([[ch.freiwilligenarbeit_sempach.entity.OrganisationEntity#]])
Non-nullable association(s): ([ch.freiwilligenarbeit_sempach.entity.OrganisationEntity.contactPerson])
This makes perfect sense to me, since it tries to insert the organisation with no reference to the person whatsoever. So I would usually define a cascade behaviour, so that hibernate inserts the person first, sets the reference ond the organisation and then persists the organisation. I tried the following on the organisation entity:
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "contact_person_id", referencedColumnName = "id", nullable = false)
public PersonEntity getContactPerson() {
return contactPerson;
}
and
@OneToOne
@JoinColumn(name = "contact_person_id", referencedColumnName = "id", nullable = false)
@Cascade(org.hibernate.annotations.CascadeType.ALL)
public PersonEntity getContactPerson() {
return contactPerson;
}
But neither of the seem to work. I still get the same error. But I think this should actually work.
Any help is highly appreciated! Thanks in advance.
Upvotes: 1
Views: 1813
Reputation: 347
This did the trick.
@Cascade(org.hibernate.annotations.CascadeType.ALL)
Although I believe I stopped tomcat and cleaned redeployed the webapp i did not work yesterday. Today it worked as expected, so that the referenced entities (Person) were inserted before the referencing entity (Organisation).
Upvotes: 1
Reputation: 187
I don't understand completely, what do you want, but I suppose that you want to save a person entity with a person organization.
If you use different ids, you should add the @OneToOne
annotation with attribute mappedBy=contactPerson
In the PersonEntity class
@OneToOne(cascade = CascadeType.ALL, mappedBy = "contactPerson")
private OrganisationEntity orgEntity;
In the OrganisationEntity class
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "contact_person_id", nullable = false)
private PersonEntity contactPerson; // name which is pointed as mappedBy attribute
Then you can save this correct writing something like this
orgEntity.setContactPerson(contactPerson);
orgRepo.save(orgEntity);
p.s. I wrote using field injection, but it's not necessary.
Upvotes: 1