Property with @Id and @GeneratedValue(strategy=IDENTITY) brokes @NaturalIdCache

Description

The following test case demonstrates the issue.

EntityWithNaturalKey.java

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import org.hibernate.annotations.NaturalId; import org.hibernate.annotations.NaturalIdCache; import javax.persistence.Cacheable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import static javax.persistence.GenerationType.IDENTITY; @Entity @Cacheable @NaturalIdCache public class EntityWithNaturalKey { @Id @GeneratedValue(strategy = IDENTITY) private long id; @NaturalId(mutable = false) private String name; protected EntityWithNaturalKey() { } public EntityWithNaturalKey(String name) { this.name = name; } public long getId() { return id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }

NaturalIdCacheTest.java

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 import org.hibernate.Session; import org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.test.jpa.AbstractJPATest; import org.hibernate.testing.TestForIssue; import org.junit.Assert; import org.junit.Test; public class NaturalIdCacheTest extends AbstractJPATest { @Override public String[] getMappings() { return NO_MAPPINGS; } @Override public void configure(Configuration cfg) { super.configure(cfg); cfg.addAnnotatedClass(EntityWithNaturalKey.class); cfg.setProperty(Environment.USE_SECOND_LEVEL_CACHE, "true"); cfg.setProperty(Environment.USE_QUERY_CACHE, "true"); cfg.setProperty(Environment.GENERATE_STATISTICS, "true"); cfg.setProperty(Environment.CACHE_REGION_FACTORY, SingletonEhCacheRegionFactory.class.getName()); } @Test @TestForIssue(jiraKey = "???") public void testPutIntoNaturalIdCache_newlyCreatedIdentity() throws Exception { // Bug description: // Creating new entity with auto generated identity // puts new item with value = null into natural id // cache region, and mainly because of this it will // never be (re-)populated later, causing natural // id queries performing again and again. Session s = openSession(); s.beginTransaction(); EntityWithNaturalKey e = new EntityWithNaturalKey("test"); s.persist(e); s.getTransaction().commit(); s.close(); // Assert.assertEquals(0, sessionFactory().getStatistics().getNaturalIdQueryExecutionCount()); // it would be perfect but not necessary s = openSession(); s.beginTransaction(); e = (EntityWithNaturalKey) s.bySimpleNaturalId(EntityWithNaturalKey.class).load("test"); Assert.assertNotNull(e); s.getTransaction().commit(); s.close(); long queryCount = sessionFactory().getStatistics().getNaturalIdQueryExecutionCount(); // entity must be cached, no more queries bust be issued // since we didn't modify anything. s = openSession(); s.beginTransaction(); e = (EntityWithNaturalKey) s.bySimpleNaturalId(EntityWithNaturalKey.class).load("test"); Assert.assertNotNull(e); s.getTransaction().commit(); s.close(); Assert.assertEquals(queryCount, sessionFactory().getStatistics().getNaturalIdQueryExecutionCount()); } }

Environment

Any.

Status

Assignee

Unassigned

Reporter

Andrey Anisimov

Fix versions

None

Labels

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Affects versions

4.1.11
4.2.0.Final

Priority

Critical