title: JPA. JoinTable and two JoinColumns
body: <p>I need to create table PORTATION_MODEL_SET. And I need to create two keys from table portation and one key from table phone_model</p>
  
  <p><img src="https://i.stack.imgur.com/iyjzH.jpg" alt="enter image description here"></p>
  
  <p>I have code:</p>
  
  <pre><code>@Entity
  @Table(name="PORTATION")
  @SecondaryTable(name="PORTATION")
  @Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
  public class JDBCPortation implements Portation {
  
      @Id
      @GeneratedValue(strategy=GenerationType.AUTO)
      private Integer id;
  
      @ManyToOne(targetEntity=JDBCContentMetaData.class, fetch=FetchType.LAZY)
      @JoinColumn(name="fk_content_id",nullable=false)
      private JDBCContentMetaData content;
  
  
      @ManyToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY,targetEntity=JDBCPhoneModel.class)
      @JoinTable(
              name="PORTATION_MODEL_SET",
              joinColumns={
                      @JoinColumn(table="PORTATION", name="fk_portation_id", referencedColumnName="id"),
                      @JoinColumn(table="PORTATION", name="fk_content_id", referencedColumnName="fk_content_id", nullable=true)
                      },
              inverseJoinColumns=@JoinColumn(table="PHONE_MODEL",name="fk_phone_model_id", referencedColumnName="id"))
      private List&lt;PhoneModel&gt; phoneModel;
  //more code.....
      }
  </code></pre>
  
  <p>and this:</p>
  
  <pre><code>@Entity
  @Table(name="PHONE_MODEL")
  @Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
  public class JDBCPhoneModel implements PhoneModel {
  
      @Id @GeneratedValue(strategy=GenerationType.AUTO)
      private Integer id;
  
      @Column(name="wurfl_id",length=255,nullable=false)
      private String idWurfl;
  
      @Column(name="name",length=100,nullable=false)
      private String modelName;
  }
  </code></pre>
  
  <p>And this:</p>
  
  <pre><code>@Entity
  @Table(name="CONTENT_META_DATA")
  public class JDBCContentMetaData implements ContentMetaData {
  
      @Id @GeneratedValue(strategy=GenerationType.AUTO)
      private Integer id;
  
      @OneToMany(mappedBy="content",cascade={CascadeType.PERSIST,CascadeType.MERGE},targetEntity=JDBCPortation.class,fetch=FetchType.LAZY)
      private List&lt;Portation&gt; portations;
  }
  </code></pre>
  
  <p>And I do this:</p>
  
  <pre><code>    JDBCPhoneModel phoneModel = new  JDBCPhoneModel();
      phoneModel.setIdWurfl("nokia_c50");
      phoneModel.setModelName("c50"); 
  
      JDBCContentMetaData content = JDBCContentMetaData.getNewInstance();
      content.getMetaData().setName("goodaaar!");
      content.getMetaData().setTitle("goood win!");
      content.setType(portationType.getContentType());
      basicRepository.saveForce(content);
  
      System.out.println("content_id:"+content.getId());
      JDBCPortation portation = JDBCPortation.getInstance(content);
      portation.setBinPath("/var/www/abra.jpg");
      portation.setPortitionType(portationType);
      //EXCEPTION IN SAVE FORCE
      basicRepository.saveForce(portation);
  
      portation.addPhoneModel(phoneModel);
      basicRepository.updateForce(portation);
  </code></pre>
  
  <p>but </p>
  
  <blockquote>
    <p>@JoinColumn(name="fk_content_id",
    referencedColumnName="fk_content_id", nullable=true)</p>
  </blockquote>
  
  <p>generate error:</p>
  
  <pre><code>org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
      at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:476)
      at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
      at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
      at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
      at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
      at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
      at ru.icb.cms.repository.db.jpa.repository.BasicRepository$$EnhancerByCGLIB$$e5fc35ad.saveForce(&lt;generated&gt;)
      at ru.icb.cms.repository.db.domain.RepositoryObjectTest.testCreateContent(RepositoryObjectTest.java:62)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
      at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
  </code></pre>
  
  <p>P.S. it works for:</p>
  
  <pre><code>@ManyToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY,targetEntity=JDBCPhoneModel.class)
  @JoinTable(
          name="PORTATION_MODEL_SET",
          joinColumns={
                  @JoinColumn(table="PORTATION",name="fk_portation_id", referencedColumnName="id")
                  },
          inverseJoinColumns=@JoinColumn(table="PHONE_MODEL",name="fk_phone_model_id", referencedColumnName="id"))
  private List&lt;PhoneModel&gt; phoneModel;
  </code></pre>