| As mentioned in HHH-8487 Closed flush to the database is always done before accessing an entity via native SQL or HQL query when FlushModeType.AUTO is enabled. So the @Version annotated property is always incremented when an update / merge with fetch with SQL of an entity occurs. But when doing an update to an entity and access it with entityManager.find( ) the version is not incremented. So this behavior is inconsistent according to fetching over SQL. Should a flush to the database not also be done when calling entityManager.find( )? Consider the testcase below as example:
public class JPAUnitTestCase { Logger LOG = Logger.getLogger(JPAUnitTestCase.class); private EntityManagerFactory entityManagerFactory; private EntityManager entityManager; @Before public void init() { entityManagerFactory = Persistence.createEntityManagerFactory("templatePU"); entityManager = entityManagerFactory.createEntityManager(); // entityManager.setFlushMode(FlushModeType.COMMIT); entityManager.setFlushMode(FlushModeType.AUTO); } @After public void destroy() { entityManager.close(); entityManagerFactory.close(); } @Test public void hhh123Test() throws Exception { entityManager.getTransaction().begin(); TableB b = new TableB(); b.setName("name b"); b.setDescription("Bsome description"); entityManager.persist(b); TableA a = new TableA(); a.setName("name a"); a.setDescription("some description"); entityManager.persist(a); { a.setDescription("some new description 1"); entityManager.merge(a); TableA aFetch = entityManager.find(TableA.class, a.getId()); //version is not incremented, no flush assertThat(aFetch.getVersion(), is(0L)); } { // flush is executed and version is incremented Query query = entityManager.createQuery("select entity from table_a entity where id = :id").setParameter("id", a.getId()); TableA aFetch = (TableA) query.getSingleResult(); assertThat(aFetch.getVersion(), is(1L)); } { a.setDescription("some new description 2"); entityManager.merge(a); TableA aFetch = entityManager.find(TableA.class, a.getId()); //version is not incremented, no flush assertThat(aFetch.getVersion(), is(1L)); //do native query List resultList = entityManager.createNativeQuery("select * from table_b", TableB.class).getResultList(); // flush is executed and version of TableA is incremented TableB bFetch = (TableB) resultList.get(0); assertThat(bFetch.getVersion(), is(0L)); aFetch = entityManager.find(TableA.class, a.getId()); assertThat(aFetch.getVersion(), is(2L)); } LOG.info("Do commit"); entityManager.getTransaction().commit(); } @Entity(name = "table_a") public static class TableA { @Version @Column private Long version; @Id @GeneratedValue @Column(name = "oId", updatable = false, nullable = false) private Long id; @Column(nullable = true) private String name; @Column(nullable = true) private String description; public Long getVersion() { return version; } public void setVersion(Long version) { this.version = version; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public String toString() { return String.format("TableA{version=%d, id=%d, name='%s', description='%s'}", version, id, name, description); } } @Entity(name = "table_b") public static class TableB { @Version @Column private Long version; @Id @GeneratedValue @Column(name = "oId", updatable = false, nullable = false) private Long id; @Column(nullable = true) private String name; @Column(nullable = true) private String description; public Long getVersion() { return version; } public void setVersion(Long version) { this.version = version; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public String toString() { return String.format("TableB {version=%d, id=%d, name='%s', description='%s'} ", version, id, name, description); } } }
|