diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java index 0aa9d1dc43..72f0d787b1 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java @@ -1701,6 +1701,22 @@ public class StatefulPersistenceContext implements PersistenceContext { @Override public void loadedStateUpdatedNotification(EntityEntry entityEntry) { + final EntityPersister persister = entityEntry.getPersister(); + if ( ! persister.hasNaturalIdentifier() ) { + // nothing to do + return; + } + + // extract the natural id values + final int[] naturalIdPropertyIndexes = persister.getNaturalIdentifierProperties(); + final Object[] naturalIdValues = new Object[ naturalIdPropertyIndexes.length ]; + int i = 0; + for ( int naturalIdPropertyIndex : naturalIdPropertyIndexes ) { + naturalIdValues[i++] = entityEntry.getLoadedState()[ naturalIdPropertyIndex ]; + } + + // re-cache + cacheNaturalIdResolution( persister, entityEntry.getId(), naturalIdValues ); } private class NaturalId { diff --git a/hibernate-core/src/matrix/java/org/hibernate/test/jpa/naturalid/Group.java b/hibernate-core/src/matrix/java/org/hibernate/test/jpa/naturalid/Group.java new file mode 100644 index 0000000000..88c143f057 --- /dev/null +++ b/hibernate-core/src/matrix/java/org/hibernate/test/jpa/naturalid/Group.java @@ -0,0 +1,67 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.jpa.naturalid; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.NaturalIdMutability; +import org.hibernate.annotations.NaturalId; + +/** + * @author Steve Ebersole + */ +@Entity +@Table(name = "T_GROUP") +public class Group { + private Integer id; + private String name; + + public Group() { + } + + public Group(Integer id, String name) { + this.id = id; + this.name = name; + } + + @Id + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @NaturalId(mutability = NaturalIdMutability.MUTABLE) + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/hibernate-core/src/matrix/java/org/hibernate/test/jpa/naturalid/MutableNaturalIdTest.java b/hibernate-core/src/matrix/java/org/hibernate/test/jpa/naturalid/MutableNaturalIdTest.java new file mode 100644 index 0000000000..46a5aff501 --- /dev/null +++ b/hibernate-core/src/matrix/java/org/hibernate/test/jpa/naturalid/MutableNaturalIdTest.java @@ -0,0 +1,72 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.jpa.naturalid; + +import org.hibernate.Session; + +import org.junit.Test; + +import org.hibernate.test.jpa.AbstractJPATest; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * @author Steve Ebersole + */ +public class MutableNaturalIdTest extends AbstractJPATest { + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Group.class }; + } + + @Test + public void testSimpleNaturalIdLoadAccessCacheWithUpdate() { + Session s = openSession(); + s.beginTransaction(); + Group g = new Group( 1, "admin" ); + s.persist( g ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + g = (Group) s.bySimpleNaturalId( Group.class ).load( "admin" ); + assertNotNull( g ); + Group g2 = (Group) s.bySimpleNaturalId( Group.class ).getReference( "admin" ); + assertTrue( g == g2 ); + g.setName( "admins" ); + s.flush(); + g2 = (Group) s.bySimpleNaturalId( Group.class ).getReference( "admins" ); + assertTrue( g == g2 ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + s.createQuery( "delete Group" ).executeUpdate(); + s.getTransaction().commit(); + s.close(); + } +}