Reputation: 22637
i have a bidirectional, one to many, and many to one relationship. say, a Company has many Persons, and a Persons has one company, so, in company,
@OneToMany(mappedBy = "company", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Collection<Person> persons;
and in Person,
@ManyToOne
@JoinColumn(name="COMPANY_ID")
private Company company;
now, say i have a @PrePersist / @PreUpdate method on Company, where when it is updated, i want to set the same timestamp on all the People ... like,
@PrePersist
@PreUpdate
public void setLastModified() {
this.lastModified = System.currentTimeMillis();
if (persons != null) {
for (Person person : persons) {
person.setLastModified(this.lastModified);
}
}
}
when i debug this, i see that the persons field in Company is always empty. when i look at the type of the persons collection, it's a java.util.Vector. not sure if that's relevant. i expected to see some auto-loading JPA collection type.
what am i doing wrong?
Upvotes: 10
Views: 8803
Reputation: 347
This is caused by a known bug in Hibernate, see https://hibernate.atlassian.net/browse/HHH-9979.
Unfortunately I am not aware of any workarounds.
Upvotes: 0
Reputation: 7337
In my case I got this fixed by realizing that I did not need a (Bidirectional) OneToMany - ManyToOne relationship.
For example, in a Unidirectional OneToMany relationship, just write something like:
// Company Class:
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<Person> persons = new HashSet<Person>();
// Person Class:
// - Remove the 3 lines
Check this example: https://github.com/thombergs/code-examples/tree/master/spring-data/spring-data-rest-associations/src/main/java/com/example/demo
If this does not fix your issue, check if you are using Lombok in your Person or Company classes.
If that is the case, add these two annotations in the Company class (vice-versa for the Person class):
@Data
@Entity
@EqualsAndHashCode(exclude = { "persons"}) // This,
@ToString(exclude = { "persons"}) // and this
public class Company implements Serializable {
// ...
private Set<Person> persons = ...
/ ...
Upvotes: 2
Reputation: 18379
You must set both sides of your relationship. When you create a new Person and set its Company you must also add the Person to the Company's persons (employees?).
Also, you should not change another object in one object's prePersist/Update, you should use its own prePersist/Update event.
Upvotes: 2
Reputation: 9935
if you would like to getpersonList
in Company
, use FetchType.EAGER
.
In JPA,
@--ToOne => Default : FetchType.EAGER
@--ToMany => Default : FetchType.LAZY
@JoinColumn(name="COMPANY_ID", fetch = FetchType.EAGER)
private Company company;
Upvotes: 0
Reputation: 1384
Add fetch = FetchType.Eager to @ManyToOne annotation. You added it on the other side of relationship.
Upvotes: 1