title: Spring data JPA and hibernate detached entity passed to persist on ManyToMany relationship
body: <p>I am trying to persist an object that has a many-to-many relationship with other objects already persisted.</p>
  
  <p>Here is my persisted object (they are already persisted in the db, which is a MySql):-</p>
  
  <p><strong>Product</strong></p>
  
  <pre><code>@Entity
  @Table(name="PRODUCT")
  public class Product {
      private int productId;
      private String productName;
      private Set&lt;Reservation&gt; reservations = new HashSet&lt;Reservation&gt;(0);
  
      @Id @GeneratedValue(strategy=GenerationType.AUTO)
      public int getProductId() {
          return productId;
      }
  
      public void setProductId(int productId) {
          this.productId = productId;
      }
  
  @Column(nullable = false)
      public String getProduct() {
          return product;
      }
      public void setProduct(String product) {
          this.product = product;
      }
  
      @ManyToMany(fetch = FetchType.LAZY, mappedBy = "products")
      public Set&lt;Reservation&gt; getReservations() {
          return reservations;
      }
      public void setReservations(Set&lt;Reservation&gt; reservations) {
          this.reservations = reservations;
      }
  }
  </code></pre>
  
  <p>Here is my no persisted object, which I am trying to create</p>
  
  <pre><code>@Entity
  @Table(name = "RESERVATION")
  public class Reservation {
  
      private int reservationId;
  
      private Set&lt;Product&gt; products = new HashSet&lt;Product&gt;(0);
  
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      public int getReservationId() {
          return reservationId;
      }
  
      public void setReservationId(int reservationId) {
          this.reservationId = reservationId;
      }
  
      @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
      @JoinTable(name = "product_reservation", joinColumns = { @JoinColumn(name = "reservationId", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "productId", 
              nullable = false, updatable = false) })
      public Set&lt;Product&gt; getProducts() {
          return products;
      }
  
      public void setProducts(Set&lt;Product&gt; products) {
          this.products = products;
      }
  }
  </code></pre>
  
  <p>This is my <code>ReservationService</code> class, which receives an array of products names, look the products using the name and put them into the reservation object.</p>
  
  <pre><code>@Service
  public class ReservationServiceImpl implements ReservationService {
  
      @Autowired
      private ProductDAO productDAO;
      @Autowired
      private ReservationDAO reservationDAO;
  
      @Transactional
      public void createReservation(String[] productNames) {
  
              Set&lt;Product&gt; products = new HashSet&lt;Product&gt;();
              for (String productName : productNames) {
                  Product pi = productDAO.findByProductName(productName);
                  products.add(pi);
              }
              Reservation reservation = new Reservation();
              reservation.setProducts(products);
              reservationDAO.save(reservation);   ---&gt; Here I am getting detached entity passed to persist
      }
  }
  </code></pre>
  
  <p>Here is my <code>ProductDAO</code> interface:</p>
  
  <pre><code>public interface ProductDAO extends JpaRepository&lt;Product, Integer&gt; {
  
      public Product findByProductName(String productName);
  }
  </code></pre>
  
  <p>This is my spring config file:</p>
  
  <pre><code>@Configuration
  @PropertySource(value = { "classpath:base.properties" })
  @EnableTransactionManagement
  @EnableJpaRepositories(basePackages = "com.reservation.dao")
  public class RepositoryConfig {
  
      @Autowired
      private Environment env;
  
      @Bean
      public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
          return new PropertySourcesPlaceholderConfigurer();
      }
  
      @Bean
      public PlatformTransactionManager transactionManager() {
          EntityManagerFactory factory = entityManagerFactory().getObject();
          return new JpaTransactionManager(factory);
      }
  
      @Bean
      public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
          HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
          vendorAdapter.setGenerateDdl(Boolean.valueOf(env
                  .getProperty("hibernate.generate.ddl")));
          vendorAdapter.setShowSql(Boolean.valueOf(env
                  .getProperty("hibernate.show_sql")));
  
          Properties jpaProperties = new Properties();
          jpaProperties.put("hibernate.hbm2ddl.auto",
                  env.getProperty("hibernate.hbm2ddl.auto"));
          jpaProperties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
  
          LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
          factory.setDataSource(dataSource());
          factory.setJpaVendorAdapter(vendorAdapter);
          factory.setPackagesToScan("com.reservation.service.domain");
          factory.setJpaProperties(jpaProperties);
          factory.afterPropertiesSet();
          factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
          return factory;
      }
  
      @Bean
      public HibernateExceptionTranslator hibernateExceptionTranslator() {
          return new HibernateExceptionTranslator();
      }
  
      @Bean
      public DataSource dataSource() {
          BasicDataSource dataSource = new BasicDataSource();
          dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
          dataSource.setUrl(env.getProperty("jdbc.url"));
          dataSource.setUsername(env.getProperty("jdbc.username"));
          dataSource.setPassword(env.getProperty("jdbc.password"));
          return dataSource;
      }
  }
  </code></pre>
  
  <p>Here is the full stack trace:</p>
  
  <blockquote>
    <p>SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/web] threw exception [Request processing failed; 
        nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.reservation.service.domain.Product; 
        nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.reservation.service.domain.Product] with root cause
        org.hibernate.PersistentObjectException: detached entity passed to persist: com.reservation.service.domain.Product
            at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:141)</p>
  </blockquote>