title: spring-data-jpa @OneToMany fails with lazy init
body: <p>I am trying to create a Parent-Child relationship using Spring-data-jpa, hibernate, spring-data, H2 (for tesitng), and eventually Postgress (production).  </p>
  
  <p>Here are the tables defined in h2.sql:</p>
  
  <pre><code>CREATE TABLE IF NOT EXISTS Menu (
    menuId bigint(11) NOT NULL AUTO_INCREMENT,
    displayText varchar (100)  DEFAULT NOT NULL,
    displayOrder int default NULL
    );
  
  
  CREATE TABLE IF NOT EXISTS MenuItem (
    menuItemId bigint(11) NOT NULL AUTO_INCREMENT,
    displayText varchar (100)  DEFAULT NOT NULL,
    path varchar (50)  NULL,
    toolTip varchar (500)  DEFAULT NOT NULL,
    displayOrder int default NULL,
    callType varchar (50)  DEFAULT NOT NULL
    );
  </code></pre>
  
  <p>I have two simple entities:</p>
  
  <pre><code>@Entity
  public class Menu {
  
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private long menuId;
  
      @OneToMany(fetch = FetchType.LAZY, mappedBy = "menu")
      private List&lt;MenuItem&gt; menuItems = new ArrayList&lt;MenuItem&gt;();
  
      private String displayText;
      private int displayOrder;
  </code></pre>
  
  <p>and </p>
  
  <pre><code>@Entity
  public class MenuItem {
  
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private long menuItemId;
  
      private String displayText;
      private String path;
      private String toolTip;
      private int displayOrder;
  
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "menuId", nullable = false)
      private Menu menu;
  
      @Enumerated(EnumType.STRING)
      @Column(name = "callType", nullable = false)
      private HttpType callType;
  </code></pre>
  
  <p>I have an application:</p>
  
  <pre><code>@Configuration
  @ComponentScan
  @EnableJpaRepositories
  @EnableTransactionManagement
  @EnableAutoConfiguration
  public class Application {
  
      public static void main(String[] args) {
          ApplicationContext MyApplication = SpringApplication.run( Application.class, args );
      }
  }
  </code></pre>
  
  <p>And a Configuration class:</p>
  
  <pre><code>@Configuration
  public class MyConfiguration {
  @Bean
      public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
          LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
          lef.setDataSource( dataSource );
          lef.setJpaVendorAdapter( jpaVendorAdapter );
          lef.setPackagesToScan( "com.xxx.yyy" );
          return lef;
      }
  
      @Bean
      public JpaVendorAdapter jpaVendorAdapter() {
          HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
          hibernateJpaVendorAdapter.setShowSql( true );
          hibernateJpaVendorAdapter.setGenerateDdl( true );
          hibernateJpaVendorAdapter.setDatabase( Database.H2 );
          return hibernateJpaVendorAdapter;
      }
  
      @Bean
      public PlatformTransactionManager transactionManager() {
          return new JpaTransactionManager();
      }
  
      @Bean
      public DataSource dataSource() {
  
          return new EmbeddedDatabaseBuilder().setType( EmbeddedDatabaseType.H2 ).setName( "product" )
                  .addScript( "classpath:h2.sql" ).build();
      }
  }
  </code></pre>
  
  <p>I have a test:</p>
  
  <pre><code>@SpringApplicationConfiguration
  @Transactional
  class MenuRepositoryTest extends Specification {
  
      @Shared
      ConfigurableApplicationContext context
  
      @Shared
      private MenuRepository menuRepository
  
      void setupSpec() {
          Future future = Executors.newSingleThreadExecutor().submit(
                  new Callable() {
                      @Override
                      public ConfigurableApplicationContext call() throws Exception {
                          return (ConfigurableApplicationContext) SpringApplication.run(Application.class)
                      }
                  })
          context = future.get(60, TimeUnit.SECONDS)
          menuRepository = context.getBean(MenuRepository.class)
      }
  
      void cleanupSpec() {
          if (context != null) {
              context.close()
          }
      }
   @Transactional
      def "test creating a single menu with a single menuItem"() {
  
          def menu = new Menu()
          menu.setDisplayOrder(0)
          menu.setDisplayText("test")
          menuRepository.save(menu)
  
          def menuItem = new MenuItem()
          menuItem.setToolTip("tooltip 1")
          menuItem.setPath("/1")
          menuItem.setCallType(HttpType.GET)
          menuItem.setDisplayText("tooltip")
          menu.addMenuItem(menuItem)
  
          when:
          def menus = menuRepository.findAll()
          menus[0].getMenuItems()
  
          then:
          menus[0].getMenuItems().size() == 1
  
      }
  }
  </code></pre>
  
  <p>Here is my gradle showing dependencies:</p>
  
  <pre><code>apply plugin: 'java'
  apply plugin: 'groovy'
  apply plugin: 'idea'
  apply plugin: 'spring-boot'
  apply plugin: 'jacoco'
  apply plugin: 'war'
  apply plugin: 'maven'
  
  
  buildscript {
      repositories {
          maven { url "http://repo.spring.io/libs-snapshot" }
          mavenLocal()
      }
      dependencies {
          classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.0.RC4")
      }
  }
  repositories {
      mavenCentral()
      maven { url "http://repo.spring.io/libs-snapshot" }
      maven { url 'http://repo.spring.io/milestone' }
  }
  
  dependencies {
      compile("org.springframework.boot:spring-boot-starter-web:1.0.0.RELEASE")
      compile("org.springframework.boot:spring-boot-starter-data-jpa:1.0.1.RELEASE")
      compile("org.springframework.boot:spring-boot:1.0.1.RELEASE")
      compile("org.springframework:spring-orm:4.0.0.RC1")
      compile("org.hibernate:hibernate-entitymanager:4.2.1.Final")
      compile("org.springframework:spring-tx")
      compile("com.h2database:h2:1.3.172")
      compile("joda-time:joda-time:2.3")
      compile("org.thymeleaf:thymeleaf-spring4")
      compile("org.codehaus.groovy.modules.http-builder:http-builder:0.7.1")
      compile('org.codehaus.groovy:groovy-all:2.2.1')
      compile('org.jadira.usertype:usertype.jodatime:2.0.1')
  
      testCompile('org.spockframework:spock-core:0.7-groovy-2.0') {
          exclude group: 'org.codehaus.groovy', module: 'groovy-all'
      }
      testCompile('org.codehaus.groovy.modules.http-builder:http-builder:0.7+')
      testCompile("junit:junit")
  }
  
  jacocoTestReport {
      group = "Reporting"
      description = "Generate Jacoco coverage reports after running tests."
  }
  
  sourceSets {
  
      main {
  
          java {
              srcDirs = []
          }
          groovy {
              srcDirs = ['src/main/groovy', 'src/main/java']
          }
          resources {
              srcDirs = ['src/main/resources']
          }
  
          output.resourcesDir = "build/classes/main"
      }
  
      test {
          java {
              srcDirs = []
          }
          groovy {
              srcDirs = ['src/test/groovy', 'src/test/java']
          }
          resources {
              srcDirs = ['src/test/resources']
          }
  
          output.resourcesDir = "build/classes/test"
      }
  }
  
  task wrapper(type: Wrapper) {
      gradleVersion = '1.11'
  }
  </code></pre>
  
  <p><strong>Answer</strong>: </p>
  
  <p>Change build.gradle to use different spock</p>
  
  <pre><code>buildscript {
      repositories {
          maven { url "http://repo.spring.io/libs-milestone" }
          mavenLocal()
      }
      dependencies {
          classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.1.RELEASE")
      }
  }
  repositories {
      mavenCentral()
      maven { url "http://repo.spring.io/libs-milestone" }
      maven { url "https://repository.jboss.org/nexus/content/repositories/releases" }
      maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
      maven { url "http://repo.spring.io/snapshot" }
      maven { url 'http://repo.spring.io/milestone' }
  }
  dependencies {
  compile("org.springframework.boot:spring-boot-starter-web:1.0..RELEASE")
      compile("org.springframework.boot:spring-boot:1.0.1.RELEASE")
      compile("org.springframework.boot:spring-boot-starter-data-jpa:1.0.1.RELEASE")
      testCompile('org.spockframework:spock-core:1.0-groovy-2.0-SNAPSHOT') {
          exclude group: 'org.codehaus.groovy', module: 'groovy-all'
      }
  
      testCompile('org.spockframework:spock-spring:1.0-groovy-2.0-SNAPSHOT') {
          exclude group: 'org.spockframework', module: 'spock-core'
          exclude group: 'org.spockframework', module: 'spring-beans'
          exclude group: 'org.spockframework', module: 'spring-test'
          exclude group: 'org.codehaus.groovy', module: 'groovy-all'
      }
      testCompile('org.springframework:spring-test:4.0.3.RELEASE')
  ...}
  </code></pre>
  
  <p>Change the test to not use SetupSpec or @Shared:</p>
  
  <pre><code>@ContextConfiguration(classes = MyApplication, loader = SpringApplicationContextLoader)
  @Transactional
  class MenuRepositoryTest extends Specification {
  
      @Autowired
      private MenuRepository menuRepository
  
      def "test creating a single menu with a single menuItem"() {
  
          def menu = new Menu()
          menu.setDisplayOrder(0)
          menu.setDisplayText("test")
          menuRepository.save(menu)
  
          def menuItem = new MenuItem()
          menuItem.setToolTip("tooltip 1")
          menuItem.setPath("/1")
          menuItem.setCallType(HttpType.GET)
          menuItem.setDisplayText("tooltip")
          menu.addMenuItem(menuItem)
  
          when:
          def menus = menuRepository.findAll()
          menus[0].getMenuItems()
  
          then:
          menus[0].getMenuItems().size() == 1
  
      }
  }
  </code></pre>