title: Error: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ForeignKey with Spring controller
body: <p>I have a simple two table application written in Spring MVC and which uses Hibernate. Everything works perfectly well but if I try to unit test one of the controllers, I get message:</p>
  
  <pre><code>Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ForeignKey;
  </code></pre>
  
  <p>The unit test method is below:</p>
  
  <pre><code>@RunWith(value=SpringJUnit4ClassRunner.class)
  @WebAppConfiguration
  @ContextConfiguration("file:C:/NetBeansProjects/Library/build/web/WEB-INF/library- servlet.xml")
  public class TestPersonController {
  
  @Autowired
  private PersonService personService;
  @Autowired
  private WebApplicationContext wac;
  
  private MockMvc mockMvc;
  
  @Before
  public void setup() {
      this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
  }
  
  @Test
  public void testGetProfile() {
      Person mockPerson = new Person();
      mockPerson.setPersonId(1);
      mockPerson.setName("Mr Brown");
      mockPerson.setAddress("Utopia Planitia on Mars");
      mockPerson.setTelephone("1234567890"); 
      mockPerson.setEmail("brown@brown.com");
  
      when(personService.get(1)).thenReturn(mockPerson);
      try {
          mockMvc.perform(get("/person/profile?personId=1"))
              .andExpect(status().isOk())
              .andExpect(view().name("view/profile"))
              .andExpect(forwardedUrl("/WEB-INF/jsp/view/profile.jsp"))
              .andExpect(model().attribute("person", hasSize(1)))
              .andExpect(model().attribute("person", hasItem(
                      allOf(
                              hasProperty("personId", is(1)),
                              hasProperty("name", is("Mr Brown")),
                              hasProperty("address", is("53 Onslow Gardens")),
                              hasProperty("telephone", is("1234567890")),
                              hasProperty("email", is("brown@brown.com"))
                      )
              )));
  
      }
      catch(Exception e) {
          Misc.printStackTrace(e);
      }
      verify(personService, times(1)).get(1);
      verifyNoMoreInteractions(personService);        
  }
  </code></pre>
  
  <p>}</p>
  
  <p>The two classes forming the model of the application are joined via a 1:M relationship. The first table Person has:</p>
  
  <pre><code>@Id
  @Column(name="PERSON_ID", unique=true, nullable=false)    
  @GeneratedValue(strategy=GenerationType.AUTO)
  private Integer personId;
  
  @Column(name="NAME", nullable=false, length=50)      
  private String name;
  
  @Column(name="ADDRESS", nullable=false, length=100)
  private String address;
  
  @Column(name="TELEPHONE", nullable=false, length=10)
  private String telephone;
  
  @Column(name="EMAIL", nullable=false, length=50)
  private String email;
  
  @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="person") 
  @JsonManagedReference
  private List&lt;Book&gt; books;
  </code></pre>
  
  <p>And the second table has:</p>
  
  <pre><code>@Id
  @Column(name="BOOK_ID", unique=true, nullable=false)
  @GeneratedValue(strategy=GenerationType.AUTO)
  private Integer bookId;
  
  @Column(name="AUTHOR", nullable=false, length=50)
  private String author;
  
  @Column(name="TITLE", nullable=false, length=50)
  private String title;
  
  @Column(name="DESCRIPTION", nullable=false, length=500)
  private String description;        
  @Column(name="ONLOAN", nullable=false)
  private boolean onLoan;
  
  
  @ManyToOne(fetch=FetchType.LAZY)
  @JoinColumn(name="person_id")
  @JsonBackReference
  private Person person;
  </code></pre>
  
  <p>These classes work correctly under all other circumstances except this new unit test of a method in the Person controller.</p>
  
  <p>I do not use the @ForeignKey annotation in my classes because there seems to be no need to and if I try, Java says it is unnecessary.</p>
  
  <p>Do I have a dependency issue or what?</p>
  
  <p>The unit test stacktrace follows:</p>
  
  <pre><code>Testsuite: library.person.TestPersonController
  Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.085 sec
  
  ------------- Standard Error -----------------
  log4j:WARN No appenders could be found for logger (org.springframework.test.context.junit4.SpringJUnit4ClassRunner).
  log4j:WARN Please initialize the log4j system properly.
  ------------- ---------------- ---------------
  Testcase: testGetProfile(library.person.TestPersonController):  Caused an ERROR
  Failed to load ApplicationContext
  java.lang.IllegalStateException: Failed to load ApplicationContext
      at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
      at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101)
      at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:155)
      at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:100)
      at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:319)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:212)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
      at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
      at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
  Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adminController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private library.service.PersonService library.controller.admin.AdminController.personService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private library.dao.PersonDAOImpl library.service.PersonService.personDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personDAOImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory library.dao.PersonDAOImpl.sessionFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in URL [file:C:/NetBeansProjects/Library/build/web/WEB-INF/library-servlet.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ForeignKey;
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
      at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
      at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
      at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:129)
      at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:60)
      at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
      at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:250)
      at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
      at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
  Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private library.service.PersonService library.controller.admin.AdminController.personService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private library.dao.PersonDAOImpl library.service.PersonService.personDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personDAOImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory library.dao.PersonDAOImpl.sessionFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in URL [file:C:/NetBeansProjects/Library/build/web/WEB-INF/library-servlet.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ForeignKey;
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
      at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
  Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private library.dao.PersonDAOImpl library.service.PersonService.personDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personDAOImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory library.dao.PersonDAOImpl.sessionFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in URL [file:C:/NetBeansProjects/Library/build/web/WEB-INF/library-servlet.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ForeignKey;
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1014)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:957)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
  Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private library.dao.PersonDAOImpl library.service.PersonService.personDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personDAOImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory library.dao.PersonDAOImpl.sessionFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in URL [file:C:/NetBeansProjects/Library/build/web/WEB-INF/library-servlet.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ForeignKey;
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
      at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
  Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personDAOImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory library.dao.PersonDAOImpl.sessionFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in URL [file:C:/NetBeansProjects/Library/build/web/WEB-INF/library-servlet.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ForeignKey;
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1014)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:957)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
  Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory library.dao.PersonDAOImpl.sessionFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in URL [file:C:/NetBeansProjects/Library/build/web/WEB-INF/library-servlet.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ForeignKey;
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
      at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
  Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in URL [file:C:/NetBeansProjects/Library/build/web/WEB-INF/library-servlet.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ForeignKey;
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1014)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:957)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
  Caused by: java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ForeignKey;
      at org.hibernate.cfg.AnnotationBinder.bindManyToOne(AnnotationBinder.java:2881)
      at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1795)
      at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:963)
      at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:796)
      at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3788)
      at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3742)
      at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1410)
      at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
      at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928)
      at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:343)
      at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:431)
      at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:416)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
  
  
  Test library.person.TestPersonController FAILED
  </code></pre>
  
  <p>Props file config:</p>
  
  <pre><code>&lt;!-- Spring Properties file for Library. --&gt;         
      &lt;bean id="propertiesFactory" class="org.springframework.beans.factory.config.PropertiesFactoryBean"&gt;
          &lt;property name="location"&gt;
             &lt;value&gt;/WEB-INF/library.properties&lt;/value&gt;
          &lt;/property&gt;
      &lt;/bean&gt;
  </code></pre>