Hi!
I have two entities like the following:
@Entity
public class Trip {
@OneToMany(mappedBy = "trip", fetch = FetchType.LAZY)
private Set<Job> jobs = new HashSet<Job>();
}
@Entity
public class Job {
@ManyToOne(fetch = FetchType.LAZY)
private Trip trip;
}
The problem is that the mappedBy relationship behaves differently in different circumstances. Here is an example
EntityManager em1 = unit.createEntityManager();
EntityManager em2 = unit.createEntityManager();
// One EM starts transaction and stores a trip
em1.getTransaction().begin();
Trip trip = new Trip();
em1.persist(trip);
Long tripId = trip.getId();
assertThat(tripId).isPositive();
em1.getTransaction().commit();
// Then em2 starts different transaction
em2.getTransaction().begin();
// Looking up for the trip through clean em (cache is empty)
Trip em2Trip = em2.find(Trip.class, tripId);
Job job = new Job();
job.setTrip(em2Trip);
em2.persist(job);
// The em2Trip should not be updated
assertThat(em2Trip.getJobs()).hasSize(1);
em2.getTransaction().commit();
em1.getTransaction().begin();
Trip em1Trip = em1.find(Trip.class, tripId);
// fails here
assertThat(em1Trip.getJobs()).hasSize(1);
em1.getTransaction().commit();
The code above shows that if an entity is already loaded in the entity manager's cache, the getter for the mappedBy relationship may return invalid results.
I have a proof it doesn't work under JBoss either. The following code behaves differently depending on which entity manager is being used. The result is unpredictable.
Trip trip = em.find(Trip.class, tripId);
if (trip.getJobs().size() == 0) ...
Does this mean that the mappedBy automatically makes application buggy as soon as it is introduced and used?
P.S. I am not trying to abuse hibernate. I only want to find out if someone faced such a problem and how did they cope with it