title: JPA - correct way to insert to a join table (with extra columns)
body: <p>I managed to insert crew for my movie - now I want to do it the right way. Entities (abbreviated):</p>
  
  <pre><code>@Entity
  @Table(name = "movies")
  public class Movie implements Serializable {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private int idmovie;
      // bi-directional many-to-one association to MoviesHasCrew
      @OneToMany(mappedBy = "movy", cascade = CascadeType.PERSIST)
      private List&lt;MoviesHasCrew&gt; moviesHasCrews;
  }
  
  @Entity
  @Table(name = "movies_has_crew")
  public class MoviesHasCrew implements Serializable {
      @EmbeddedId
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private MoviesHasCrewPK id;
      // bi-directional many-to-one association to Crew
      @ManyToOne
      @JoinColumn(name = "crew_idcrew", columnDefinition = "idcrew")
      @MapsId("crewIdcrew")
      private Crew crew;
      // bi-directional many-to-one association to Movy
      @ManyToOne
      @JoinColumn(name = "movies_idmovie")
      @MapsId("moviesIdmovie")
      private Movie movy;
      // bi-directional many-to-one association to Role
      @ManyToOne
      @JoinColumn(name = "roles_idrole")
      @MapsId("rolesIdrole")
      private Role role;
  }
  
  @Entity
  @Table(name = "crew")
  public class Crew implements Serializable {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private int idcrew;
      // bi-directional many-to-one association to MoviesHasCrew
      @OneToMany(mappedBy = "crew", cascade = CascadeType.PERSIST)
      private List&lt;MoviesHasCrew&gt; moviesHasCrews;
  }
  </code></pre>
  
  <p>Sorry for 'movy' and 'crews' that's the tools (and qualifies for a bug report)</p>
  
  <p>Controller and form:</p>
  
  <pre><code>@ManagedBean
  @ViewScoped
  public class MovieController implements Serializable {
      @EJB
      private MovieService service;
      private Crew crewMember;
      private Movie movie;
  
      public String addCrewMember() {
          if (movie.getIdmovie() == 0) {
              movie = (Movie) FacesContext.getCurrentInstance()
                  .getExternalContext()
                  .getSessionMap().get("movie");
          }
          service.addCrew(movie, crewMember);
          return null;
      }
  }
  
  &lt;h:form id="movie_add_crew_form" rendered="#{sessionScope.movie != null}"&gt;
  &lt;h:panelGrid columns="2"&gt;
      &lt;h:selectOneListbox id="crewMember" redisplay="true" size="8"
          value="#{movieController.crewMember}"
          converter="#{movieController$CrewConverter}"&gt;
          &lt;f:selectItems value="#{movieController.allCrew}" var="entry"
              itemValue="#{entry}" itemLabel="#{entry.name}" /&gt;
          &lt;f:ajax event="blur" render="crewMemberMessage" /&gt;
      &lt;/h:selectOneListbox&gt;
      &lt;h:message id="crewMemberMessage" for="crewMember" /&gt;
  &lt;/h:panelGrid&gt;
  &lt;h:commandButton value="Add" action="#{movieController.addCrewMember}"&gt;
      &lt;f:ajax execute="@form" render="@form :movie_crew" /&gt;
  &lt;/h:commandButton&gt;&lt;/h:form&gt;
  </code></pre>
  
  <p>And finally the service:</p>
  
  <pre><code>@Stateless
  public class MovieService {
  
      @PersistenceContext
      private EntityManager em;
  
      public void addCrew(Movie m, Crew w) {
          MoviesHasCrew moviesHasCrew = new MoviesHasCrew();
          moviesHasCrew.setCrew(w);
          moviesHasCrew.setMovy(m);
          moviesHasCrew.setRole(Role.DEFAUT_ROLE);
          em.persist(moviesHasCrew);
          m.addMoviesHasCrew(moviesHasCrew); // (1)
          em.merge(m); // noop
      }
  }
  </code></pre>
  
  <p><strong>Question 1</strong>: I want to have the Crew and Movie entities' fields <code>moviesHasCrews</code> updated on persisting the <code>MoviesHasCrew</code>  entity (ie drop <code>m.addMoviesHasCrew(moviesHasCrew); em.merge(m);</code>) but my cascade annotations do not seem to do it. Should I do it the other way round ? That is add to <code>moviesHasCrews</code> in movies and merge/perist Movie and have the <code>MoviesHasCrew</code> updated - this I <a href="http://giannigar.wordpress.com/2009/09/04/mapping-a-many-to-many-join-table-with-extra-column-using-jpa/" rel="nofollow noreferrer">read</a> needs hibernate but I work with generic JPA - is it still not doable in vanilla JPA ?</p>
  
  <p><strong>Question 2</strong>: a rundown of how this should be done would be appreciated (for instance should I add <code>fetch=Lazy</code> (in <code>Movie</code> and <code>Crew</code>) <code>@Transient</code> to the <code>moviesHasCrews</code> fields ?). Is <code>@MapsId("moviesIdmovie")</code> etc needed in the join table entity ?  Is this the most minimal/elegant way of doing it ?</p>
  
  <p>The schema:</p>
  
  <p><img src="https://i.stack.imgur.com/z3ulp.png" alt="enter image description here"></p>
  
  <p>References:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/14752695/jpa-simple-many-to-many-with-eclipselink">JPA simple many-to-many with eclipselink</a></li>
  <li><a href="http://giannigar.wordpress.com/2009/09/04/mapping-a-many-to-many-join-table-with-extra-column-using-jpa/" rel="nofollow noreferrer">Mapping a many-to-many join table with extra column using JPA</a></li>
  </ul>