title: Hibernate duplicate records when @Version is of type Integer but not when using primitive type int
body: <p>Given a JPA Entity, I've noticed an interesting issue in my code : </p>
  
  <ul>
  <li>when the <code>@Version</code> field is of type <code>Integer</code>, the records are duplicated</li>
  <li>when the <code>@Version</code> field is of primitive type <code>int</code>, the records are stored properly</li>
  </ul>
  
  <p>I reproduced the issue on a Parent/Child hierarchy with bidirectional relation (in order to reduce verbosity, I used Lombok) using Spring Data on Hibernate 4.3.11.Final with an in-memory HSQLDB 2.5.0 database (but the issue also occurs using Hibernate 5.4.10.Final and Oracle 12 database).</p>
  
  <p>The Child class:</p>
  
  <pre><code>@Entity
  @SequenceGenerator(name = "s1", allocationSize = 1, sequenceName = "S1db")
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  @EqualsAndHashCode
  @ToString(exclude = "parent")
  class Child {
      @Id
      @Column
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "s1")
      private Long id;
  
      @Column
      private String name;
  
      @Version
      @Column
      private Integer version;
  
      @ManyToOne
      @JoinColumn
      private Parent parent;
  }
  </code></pre>
  
  <p>The Parent class:</p>
  
  <pre><code>@Entity
  @Getter
  @Setter
  @NoArgsConstructor
  @SequenceGenerator(name = "s2", allocationSize = 1, sequenceName = "s2db")
  @ToString
  class Parent {
      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "s2")
      @Column
      private Long id;
  
      @Column(nullable = false)
      private String name;
  
      @OneToMany(targetEntity = Child.class,
              mappedBy = "parent",
              cascade = CascadeType.ALL,
              orphanRemoval = true,
              fetch = FetchType.LAZY
      )
      @OnDelete(action = OnDeleteAction.CASCADE)
      private List&lt;Child&gt; children = new ArrayList&lt;&gt;();
  }
  </code></pre>
  
  <p>The Repositories and Spring Configuration :</p>
  
  <pre><code>@Repository
  @javax.transaction.Transactional
  interface ChildRepository extends JpaRepository&lt;Child, Long&gt; {}
  
  @javax.transaction.Transactional
  @Repository
  interface ParentRepository extends JpaRepository&lt;Parent, Long&gt; {}
  
  @Configuration
  @EnableJpaRepositories(basePackageClasses = ParentRepository.class)
  @EntityScan(basePackageClasses = Parent.class)
  class ConfigClass {
      @Bean
      public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
          JpaTransactionManager txManager = new JpaTransactionManager();
          txManager.setEntityManagerFactory(entityManagerFactory);
          return txManager;
      }
  
      @Bean
      public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
          final DriverManagerDataSource dataSource = new DriverManagerDataSource();
          dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
          dataSource.setUrl("jdbc:hsqldb:mem:spring;sql.syntax_ora=true");
          dataSource.setUsername("sa");
          dataSource.setPassword("");
  
          final Properties properties = new Properties();
          properties.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
          properties.setProperty("hibernate.hbm2ddl.auto", "create");
          properties.setProperty("hibernate.show_sql", "true");
          properties.setProperty("hibernate.format_sql", "true");
          properties.setProperty("hibernate.use_sql_comments", "true");
          properties.setProperty("properties.hibernate.jdbc.batch_size", "10");
  
          final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
          em.setDataSource(dataSource);
          em.setPackagesToScan(Parent.class.getPackage().getName());
  
          final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
          em.setJpaVendorAdapter(vendorAdapter);
          em.setJpaProperties(properties);
  
          return em;
      }
  }
  </code></pre>
  
  <p>And finaly the test class:</p>
  
  <pre><code>@RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration(classes=ConfigClass.class)
  @Transactional
  public class ParentRepositoryTest {
      @Autowired
      private ParentRepository parentRepository;
      @Autowired
      private ChildRepository childRepository;
  
      @Test
      public void test() {
          // cleanup database
          childRepository.deleteAll();
          parentRepository.deleteAll();
  
          // Given a parent without child
          Parent p = new Parent();
          p.setName("Alice");
          p = parentRepository.saveAndFlush(p);
  
          // When I add 3 children
          for (int i=0; i&lt;3; i++) {
              Child c = new Child();
              c.setParent(p);
              c.setName("child " + i);
              c.setVersion(0); // &lt;===== this is the main issue
              // When Child.version is an int =&gt; will persist 3 elements
              // When Child.version is an Integer =&gt; will persist 6 elements
              p.getChildren().add(c);
          }
          for (Child c : p.getChildren()) {
              childRepository.save(c);
          }
  
          // Then the database contains 3 children
          Assertions.assertThat(childRepository.findAll()).hasSize(3); // Ouch! will persist 6 children
      }
  }
  </code></pre>
  
  <p>The conclusion is that :</p>
  
  <ul>
  <li>When <code>Child.version</code> is of primitive type <code>int</code>, the test pass.</li>
  <li>When <code>Child.version</code> is of type <code>Integer</code>, the test fails.</li>
  </ul>
  
  <p>While solving the issue is easy (I just need to set the type to <code>int</code>), I'm wondering why this makes a difference. </p>
  
  <p>Can someone explain me why the <code>@Version</code> field type makes a difference ?</p>