The problem is that JPA does not maintain both sides of bidirectional relationships for you. This is much more apparent when you use a JPA provider that has a second level cache. The reason it is apparent is that when you set the owning side of a relationship - in this case call moviesHasCrew.setCrew(w) and then em.flush()- this causes the database FK to be updated. But if you immediately check your object model, you will see that the Crew member referenced does not have a corresponding moviesHasCrew instance in its collection. JPA doesn't manage your references and set them for you, so it is out of sync with what is in the database.
This should be expected in the same EntityManager. When a second level cache is involved though, every time you query for that Crew instance, it will return the cached copy that is now stale.
The only way to have the collection updated is cause the Crew instance to be reloaded from the database. This can be done by clearing the cache, or by forcing a refresh.
The better alternative is to maintain both sides of bidirectional relationship and keep them in sync with each other. In the code case you have, this means calling:
public void addCrew(Movie m, Crew w) {
MoviesHasCrew moviesHasCrew = new MoviesHasCrew();
moviesHasCrew.setCrew(w);
w.addMoviesHasCrew(moviesHasCrew);
moviesHasCrew.setMovy(m);
m.addMoviesHasCrew(moviesHasCrew); // (1)
moviesHasCrew.setRole(Role.DEFAUT_ROLE);
em.persist(moviesHasCrew);
em.merge(m); // noop unless it is detached
em.merge(w); // noop unless it is detached
}
The merge is required if they are detached instances, as the change to the collections needs to be put into the EntityManager so it can be merged into the cache.
If these merges are something you want to avoid, you can rely on the moviesHasCrew->Movies and moviesHasCrew->Crew relationships to handle it for you by setting the CascadeType.MERGE option on those relationship, and then use em.merge(moviesHasCrew); instead of the 3 em calls. Merging moviesHasCrew will cause it to be inserted into the database the same as persist would, but the merge will cascade over all referenced entities with relationships marked CascadeType.MERGE - so the referenced Crew and Movie will also get merged.