HHH-4781 : Read-only entities changed to modifiable on refresh
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18643 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
4ec26fa4cf
commit
b40cfb58db
|
@ -71,7 +71,13 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
|
||||
final EventSource source = event.getSession();
|
||||
|
||||
if ( source.getPersistenceContext().reassociateIfUninitializedProxy( event.getObject() ) ) return;
|
||||
boolean isTransient = ! source.contains( event.getObject() );
|
||||
if ( source.getPersistenceContext().reassociateIfUninitializedProxy( event.getObject() ) ) {
|
||||
if ( isTransient ) {
|
||||
source.setReadOnly( event.getObject(), source.isDefaultReadOnly() );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final Object object = source.getPersistenceContext().unproxyAndReassociate( event.getObject() );
|
||||
|
||||
|
@ -143,6 +149,9 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
String previousFetchProfile = source.getFetchProfile();
|
||||
source.setFetchProfile("refresh");
|
||||
Object result = persister.load( id, object, event.getLockOptions(), source );
|
||||
// Keep the same read-only/modifiable setting for the entity that it had before refreshing;
|
||||
// If it was transient, then set it to the default for the source.
|
||||
source.setReadOnly( result, ( e == null ? source.isDefaultReadOnly() : e.isReadOnly() ) );
|
||||
source.setFetchProfile(previousFetchProfile);
|
||||
|
||||
UnresolvableObjectException.throwIfNull( result, id, persister.getEntityName() );
|
||||
|
|
|
@ -840,6 +840,95 @@ public class ReadOnlyProxyTest extends FunctionalTestCase {
|
|||
s.close();
|
||||
}
|
||||
|
||||
public void testReadOnlyRefresh() {
|
||||
|
||||
Session s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
Transaction t = s.beginTransaction();
|
||||
DataPoint dp = new DataPoint();
|
||||
dp.setDescription( "original" );
|
||||
dp.setX( new BigDecimal(0.1d).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
s.save(dp);
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.load( DataPoint.class, dp.getId() );
|
||||
s.setReadOnly( dp, true );
|
||||
assertFalse( Hibernate.isInitialized( dp ) );
|
||||
s.refresh( dp );
|
||||
assertFalse( Hibernate.isInitialized( dp ) );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertTrue( Hibernate.isInitialized( dp ) );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
assertTrue( s.isReadOnly( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getImplementation() ) );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
assertTrue( s.isReadOnly( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getImplementation() ) );
|
||||
t.commit();
|
||||
|
||||
s.clear();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
}
|
||||
|
||||
public void testReadOnlyRefreshDetached() {
|
||||
|
||||
Session s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
Transaction t = s.beginTransaction();
|
||||
DataPoint dp = new DataPoint();
|
||||
dp.setDescription( "original" );
|
||||
dp.setX( new BigDecimal(0.1d).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
s.save(dp);
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.load( DataPoint.class, dp.getId() );
|
||||
assertFalse( Hibernate.isInitialized( dp ) );
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
s.setReadOnly( dp, true );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
s.evict( dp );
|
||||
s.refresh( dp );
|
||||
assertFalse( Hibernate.isInitialized( dp ) );
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
assertTrue( Hibernate.isInitialized( dp ) );
|
||||
s.setReadOnly( dp, true );
|
||||
s.evict( dp );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
t.commit();
|
||||
|
||||
s.clear();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
public void testReadOnlyProxyMergeDetachedProxyWithChange() {
|
||||
DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ public class ReadOnlySessionLazyNonLazyTest extends FunctionalTestCase {
|
|||
c = ( Container ) s.get( Container.class, cOrig.getId() );
|
||||
assertSame( cOrig, c );
|
||||
checkContainer( cOrig, expectedInitializedObjects, expectedReadOnlyObjects, s );
|
||||
//s.refresh( cOrig );
|
||||
s.refresh( cOrig );
|
||||
assertSame( cOrig, c );
|
||||
checkContainer( cOrig, expectedInitializedObjects, expectedReadOnlyObjects, s );
|
||||
s.evict( cOrig );
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.hibernate.cfg.Configuration;
|
|||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.junit.functional.FunctionalTestCase;
|
||||
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -183,7 +184,7 @@ public class ReadOnlySessionTest extends FunctionalTestCase {
|
|||
s.close();
|
||||
}
|
||||
|
||||
public void testReadOnlyRefreshFailureExpected() {
|
||||
public void testReadOnlyRefresh() {
|
||||
|
||||
Session s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
|
@ -201,11 +202,18 @@ public class ReadOnlySessionTest extends FunctionalTestCase {
|
|||
s.setDefaultReadOnly( true );
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.refresh( dp );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.setDefaultReadOnly( false );
|
||||
s.refresh( dp );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
|
@ -218,7 +226,169 @@ public class ReadOnlySessionTest extends FunctionalTestCase {
|
|||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
public void testReadOnlyRefreshDetached() {
|
||||
|
||||
Session s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
Transaction t = s.beginTransaction();
|
||||
DataPoint dp = new DataPoint();
|
||||
dp.setDescription( "original" );
|
||||
dp.setX( new BigDecimal(0.1d).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
s.save(dp);
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
t = s.beginTransaction();
|
||||
s.setDefaultReadOnly( false );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.evict( dp );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.setDefaultReadOnly( true );
|
||||
s.evict( dp );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
dp.setDescription( "changed" );
|
||||
t.commit();
|
||||
|
||||
s.clear();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
public void testReadOnlyProxyRefresh() {
|
||||
|
||||
Session s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
Transaction t = s.beginTransaction();
|
||||
DataPoint dp = new DataPoint();
|
||||
dp.setDescription( "original" );
|
||||
dp.setX( new BigDecimal(0.1d).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
s.save(dp);
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
t = s.beginTransaction();
|
||||
s.setDefaultReadOnly( true );
|
||||
dp = ( DataPoint ) s.load( DataPoint.class, dp.getId() );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
assertFalse( Hibernate.isInitialized( dp ) );
|
||||
s.refresh( dp );
|
||||
assertFalse( Hibernate.isInitialized( dp ) );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
s.setDefaultReadOnly( false );
|
||||
s.refresh( dp );
|
||||
assertFalse( Hibernate.isInitialized( dp ) );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertTrue( Hibernate.isInitialized( dp ) );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
assertTrue( s.isReadOnly( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getImplementation() ) );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
assertTrue( s.isReadOnly( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getImplementation() ) );
|
||||
s.setDefaultReadOnly( true );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.refresh( dp );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
assertTrue( s.isReadOnly( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getImplementation() ) );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
dp.setDescription( "changed" );
|
||||
t.commit();
|
||||
|
||||
s.clear();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
}
|
||||
|
||||
public void testReadOnlyProxyRefreshDetached() {
|
||||
|
||||
Session s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
Transaction t = s.beginTransaction();
|
||||
DataPoint dp = new DataPoint();
|
||||
dp.setDescription( "original" );
|
||||
dp.setX( new BigDecimal(0.1d).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
s.save(dp);
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
t = s.beginTransaction();
|
||||
s.setDefaultReadOnly( true );
|
||||
dp = ( DataPoint ) s.load( DataPoint.class, dp.getId() );
|
||||
assertFalse( Hibernate.isInitialized( dp ) );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
s.evict( dp );
|
||||
s.refresh( dp );
|
||||
assertFalse( Hibernate.isInitialized( dp ) );
|
||||
s.setDefaultReadOnly( false );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
s.evict( dp );
|
||||
s.refresh( dp );
|
||||
assertFalse( Hibernate.isInitialized( dp ) );
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
assertFalse( s.isReadOnly( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getImplementation() ) );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
assertTrue( Hibernate.isInitialized( dp ) );
|
||||
s.evict( dp );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
assertFalse( s.isReadOnly( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getImplementation() ) );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.setDefaultReadOnly( true );
|
||||
s.evict( dp );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertTrue( s.isReadOnly( dp ) );
|
||||
assertTrue( s.isReadOnly( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getImplementation() ) );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
t.commit();
|
||||
|
||||
s.clear();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
public void testReadOnlyDelete() {
|
||||
|
@ -453,4 +623,56 @@ public class ReadOnlySessionTest extends FunctionalTestCase {
|
|||
s.close();
|
||||
|
||||
}
|
||||
|
||||
public void testMergeWithReadOnlyProxy() {
|
||||
|
||||
Session s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
Transaction t = s.beginTransaction();
|
||||
DataPoint dp = new DataPoint();
|
||||
dp.setX( new BigDecimal(0.1d).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
s.save(dp);
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
dp.setDescription( "description" );
|
||||
|
||||
s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
t = s.beginTransaction();
|
||||
s.setDefaultReadOnly( true );
|
||||
DataPoint dpProxy = ( DataPoint ) s.load( DataPoint.class, new Long( dp.getId() ) );
|
||||
assertTrue( s.isReadOnly( dpProxy ) );
|
||||
assertFalse( Hibernate.isInitialized( dpProxy ) );
|
||||
s.evict( dpProxy );
|
||||
dpProxy = ( DataPoint ) s.merge( dpProxy );
|
||||
assertTrue( s.isReadOnly( dpProxy ) );
|
||||
assertFalse( Hibernate.isInitialized( dpProxy ) );
|
||||
dpProxy = ( DataPoint ) s.merge( dp );
|
||||
assertTrue( s.isReadOnly( dpProxy ) );
|
||||
assertTrue( Hibernate.isInitialized( dpProxy ) );
|
||||
assertEquals( "description", dpProxy.getDescription() );
|
||||
s.evict( dpProxy );
|
||||
dpProxy = ( DataPoint ) s.merge( dpProxy );
|
||||
assertTrue( s.isReadOnly( dpProxy ) );
|
||||
assertTrue( Hibernate.isInitialized( dpProxy ) );
|
||||
assertEquals( "description", dpProxy.getDescription() );
|
||||
dpProxy.setDescription( null );
|
||||
dpProxy = ( DataPoint ) s.merge( dp );
|
||||
assertTrue( s.isReadOnly( dpProxy ) );
|
||||
assertTrue( Hibernate.isInitialized( dpProxy ) );
|
||||
assertEquals( "description", dpProxy.getDescription() );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, new Long( dp.getId() ) );
|
||||
assertNull( dp.getDescription() );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
}
|
||||
}
|
|
@ -169,7 +169,7 @@ public class ReadOnlyTest extends FunctionalTestCase {
|
|||
|
||||
}
|
||||
|
||||
public void testReadOnlyRefreshFailureExpected() {
|
||||
public void testReadOnlyRefresh() {
|
||||
|
||||
Session s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
|
@ -206,6 +206,45 @@ public class ReadOnlyTest extends FunctionalTestCase {
|
|||
|
||||
}
|
||||
|
||||
public void testReadOnlyRefreshDetached() {
|
||||
|
||||
Session s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
Transaction t = s.beginTransaction();
|
||||
DataPoint dp = new DataPoint();
|
||||
dp.setDescription( "original" );
|
||||
dp.setX( new BigDecimal(0.1d).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
s.save(dp);
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.setCacheMode(CacheMode.IGNORE);
|
||||
t = s.beginTransaction();
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
s.setReadOnly( dp, true );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.evict( dp );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
t.commit();
|
||||
|
||||
s.clear();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
public void testReadOnlyDelete() {
|
||||
|
||||
Session s = openSession();
|
||||
|
|
Loading…
Reference in New Issue