Issue Type: Bug Bug
Affects Versions: 4.2.0.Final, 4.1.11
Assignee: Unassigned
Components: caching (L2)
Created: 08/Apr/13 9:17 AM
Description:

The following test case demonstrates the issue.

EntityWithNaturalKey.java
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
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.
Project: Hibernate ORM
Priority: Critical Critical
Reporter: Andrew Anisimov
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira