Author: gbadner
Date: 2010-01-12 20:04:55 -0500 (Tue, 12 Jan 2010)
New Revision: 18525
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/readonly/ReadOnlyProxyTest.java
Modified:
core/trunk/core/src/main/java/org/hibernate/Session.java
core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java
core/trunk/core/src/main/java/org/hibernate/engine/PersistenceContext.java
core/trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java
core/trunk/core/src/main/java/org/hibernate/engine/TwoPhaseLoad.java
core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java
core/trunk/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java
core/trunk/core/src/main/java/org/hibernate/proxy/LazyInitializer.java
core/trunk/testsuite/src/test/java/org/hibernate/test/readonly/ReadOnlyTest.java
Log:
Session.setReadOnly(Object, boolean) fails for proxies
Modified: core/trunk/core/src/main/java/org/hibernate/Session.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/Session.java 2010-01-12 21:00:11 UTC (rev
18524)
+++ core/trunk/core/src/main/java/org/hibernate/Session.java 2010-01-13 01:04:55 UTC (rev
18525)
@@ -839,15 +839,29 @@
* Get the statistics for this session.
*/
public SessionStatistics getStatistics();
-
+
/**
- * Set an unmodified persistent object to read only mode, or a read only
- * object to modifiable mode. In read only mode, no snapshot is maintained
+ * Is the specified entity or proxy read-only?
+ * @param entityOrProxy, an entity or HibernateProxy
+ * @return true, the entity or proxy is read-only;
+ * false, the entity or proxy is modifiable.
+ */
+ public boolean isReadOnly(Object entityOrProxy);
+
+ /**
+ * Set an unmodified persistent object to read-only mode, or a read-only
+ * object to modifiable mode. In read-only mode, no snapshot is maintained
* and the instance is never dirty checked.
+ *
+ * If the entity or proxy already has the specified read-only/modifiable
+ * setting, then this method does nothing.
*
+ * @param entityOrProxy, an entity or HibernateProxy
+ * @param readOnly, if true, the entity or proxy is made read-only;
+ * if false, the entity or proxy is made modifiable.
* @see Query#setReadOnly(boolean)
*/
- public void setReadOnly(Object entity, boolean readOnly);
+ public void setReadOnly(Object entityOrProxy, boolean readOnly);
/**
* Controller for allowing users to perform JDBC related work using the Connection
Modified: core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java 2010-01-12
21:00:11 UTC (rev 18524)
+++ core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java 2010-01-13
01:04:55 UTC (rev 18525)
@@ -261,22 +261,25 @@
);
}
+ public boolean isReadOnly() {
+ if (status != Status.MANAGED && status != Status.READ_ONLY) {
+ throw new HibernateException("instance was not in a valid state");
+ }
+ return status == Status.READ_ONLY;
+ }
+
public void setReadOnly(boolean readOnly, Object entity) {
- if ( ( readOnly && status == Status.READ_ONLY ) ||
- ( ( ! readOnly ) && status == Status.MANAGED ) ) {
+ if ( readOnly == isReadOnly() ) {
// simply return since the status is not being changed
return;
}
- if (status!=Status.MANAGED && status!=Status.READ_ONLY) {
- throw new HibernateException("instance was not in a valid state");
- }
- if (readOnly) {
- setStatus(Status.READ_ONLY);
+ if ( readOnly ) {
+ setStatus( Status.READ_ONLY );
loadedState = null;
}
else {
- setStatus(Status.MANAGED);
- loadedState = getPersister().getPropertyValues(entity, entityMode);
+ setStatus( Status.MANAGED );
+ loadedState = getPersister().getPropertyValues( entity, entityMode );
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/engine/PersistenceContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/PersistenceContext.java 2010-01-12
21:00:11 UTC (rev 18524)
+++ core/trunk/core/src/main/java/org/hibernate/engine/PersistenceContext.java 2010-01-13
01:04:55 UTC (rev 18525)
@@ -475,12 +475,27 @@
* Is the association property belonging to the keyed entity null?
*/
public boolean isPropertyNull(EntityKey ownerKey, String propertyName);
-
+
/**
- * Set the object to read only and discard it's snapshot
+ * Is the entity or proxy read-only?
+ *
+ * @param entityOrProxy
+ * @return true, the object is read-only; false, the object is modifiable.
*/
- public void setReadOnly(Object entity, boolean readOnly);
+ public boolean isReadOnly(Object entityOrProxy);
+ /**
+ * Set the entity or proxy to read only and discard it's snapshot.
+ *
+ * If the entity or proxy already has the specified read-only/modifiable
+ * setting, then this method does nothing.
+ *
+ * @param entityOrProxy, an entity or HibernateProxy
+ * @param readOnly, if true, the entity or proxy is made read-only;
+ * if false, the entity or proxy is made modifiable.
+ */
+ public void setReadOnly(Object entityOrProxy, boolean readOnly);
+
void replaceDelayedEntityIdentityInsertKeys(EntityKey oldKey, Serializable
generatedId);
/**
Modified:
core/trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java 2010-01-12
21:00:11 UTC (rev 18524)
+++
core/trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java 2010-01-13
01:04:55 UTC (rev 18525)
@@ -1302,13 +1302,67 @@
nullAssociations.clear();
}
- public void setReadOnly(Object entity, boolean readOnly) {
+ public boolean isReadOnly(Object entityOrProxy) {
+ if ( entityOrProxy == null ) {
+ throw new AssertionFailure( "object must be non-null." );
+ }
+ boolean isReadOnly;
+ if ( entityOrProxy instanceof HibernateProxy ) {
+ isReadOnly = ( ( HibernateProxy ) entityOrProxy
).getHibernateLazyInitializer().isReadOnly();
+ }
+ else {
+ EntityEntry ee = getEntry( entityOrProxy );
+ if ( ee == null ) {
+ throw new TransientObjectException("Instance was not associated with this
persistence context" );
+ }
+ isReadOnly = ee.isReadOnly();
+ }
+ return isReadOnly;
+ }
+
+ public void setReadOnly(Object object, boolean readOnly) {
+ if ( object == null ) {
+ throw new AssertionFailure( "object must be non-null." );
+ }
+ if ( isReadOnly( object ) == readOnly ) {
+ return;
+ }
+ if ( object instanceof HibernateProxy ) {
+ HibernateProxy proxy = ( HibernateProxy ) object;
+ setProxyReadOnly( proxy, readOnly );
+ if ( Hibernate.isInitialized( proxy ) ) {
+ setEntityReadOnly(
+ proxy.getHibernateLazyInitializer().getImplementation(),
+ readOnly
+ );
+ }
+ }
+ else {
+ setEntityReadOnly( object, readOnly );
+ // PersistenceContext.proxyFor( entity ) returns entity if there is no proxy for that
entity
+ // so need to check the return value to be sure it is really a proxy
+ Object maybeProxy = getSession().getPersistenceContext().proxyFor( object );
+ if ( maybeProxy instanceof HibernateProxy ) {
+ setProxyReadOnly( ( HibernateProxy ) maybeProxy, readOnly );
+ }
+ }
+ }
+
+ private void setProxyReadOnly(HibernateProxy proxy, boolean readOnly) {
+ if ( proxy.getHibernateLazyInitializer().getSession() != getSession() ) {
+ throw new AssertionFailure(
+ "Attempt to set a proxy to read-only that is associated with a different
session" );
+ }
+ proxy.getHibernateLazyInitializer().setReadOnly( readOnly );
+ }
+
+ private void setEntityReadOnly(Object entity, boolean readOnly) {
EntityEntry entry = getEntry(entity);
- if (entry==null) {
- throw new TransientObjectException("Instance was not associated with the
session");
+ if (entry == null) {
+ throw new TransientObjectException("Instance was not associated with this
persistence context" );
}
- entry.setReadOnly(readOnly, entity);
- hasNonReadOnlyEntities = hasNonReadOnlyEntities || !readOnly;
+ entry.setReadOnly(readOnly, entity );
+ hasNonReadOnlyEntities = hasNonReadOnlyEntities || ! readOnly;
}
public void replaceDelayedEntityIdentityInsertKeys(EntityKey oldKey, Serializable
generatedId) {
Modified: core/trunk/core/src/main/java/org/hibernate/engine/TwoPhaseLoad.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/TwoPhaseLoad.java 2010-01-12
21:00:11 UTC (rev 18524)
+++ core/trunk/core/src/main/java/org/hibernate/engine/TwoPhaseLoad.java 2010-01-13
01:04:55 UTC (rev 18525)
@@ -32,6 +32,7 @@
import org.hibernate.CacheMode;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
+import org.hibernate.proxy.HibernateProxy;
import org.hibernate.cache.CacheKey;
import org.hibernate.cache.entry.CacheEntry;
import org.hibernate.event.PostLoadEvent;
@@ -188,8 +189,18 @@
factory.getStatisticsImplementor().secondLevelCachePut(
persister.getCacheAccessStrategy().getRegion().getName() );
}
}
-
- if ( readOnly || !persister.isMutable() ) {
+
+ boolean isReallyReadOnly = readOnly || !persister.isMutable();
+ Object proxy = persistenceContext.getProxy(
+ new EntityKey(entityEntry.getId(), entityEntry.getPersister(),
session.getEntityMode()
+ )
+ );
+ if ( proxy != null ) {
+ // there is already a proxy for this impl
+ // only set the status to read-only if the proxy is read-only
+ isReallyReadOnly = ( ( HibernateProxy ) proxy
).getHibernateLazyInitializer().isReadOnly();
+ }
+ if ( isReallyReadOnly ) {
//no need to take a snapshot - this is a
//performance optimization, but not really
//important, except for entities with huge
Modified: core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java 2010-01-12 21:00:11
UTC (rev 18524)
+++ core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java 2010-01-13 01:04:55
UTC (rev 18525)
@@ -1956,6 +1956,12 @@
return true;
}
+ public boolean isReadOnly(Object entityOrProxy) {
+ errorIfClosed();
+ checkTransactionSynchStatus();
+ return persistenceContext.isReadOnly( entityOrProxy );
+ }
+
public void setReadOnly(Object entity, boolean readOnly) {
errorIfClosed();
checkTransactionSynchStatus();
Modified: core/trunk/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java 2010-01-12
21:00:11 UTC (rev 18524)
+++
core/trunk/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java 2010-01-13
01:04:55 UTC (rev 18525)
@@ -28,6 +28,8 @@
import org.hibernate.HibernateException;
import org.hibernate.LazyInitializationException;
+import org.hibernate.TransientObjectException;
+import org.hibernate.SessionException;
import org.hibernate.engine.EntityKey;
import org.hibernate.engine.SessionImplementor;
@@ -43,8 +45,8 @@
private Serializable id;
private Object target;
private boolean initialized;
+ private boolean readOnly;
private boolean unwrap;
-
private transient SessionImplementor session;
/**
@@ -63,7 +65,15 @@
protected AbstractLazyInitializer(String entityName, Serializable id, SessionImplementor
session) {
this.entityName = entityName;
this.id = id;
- this.session = session;
+ // initialize other fields depending on session state
+ if ( session == null ) {
+ // would be better to call unsetSession(), but it is not final...
+ session = null;
+ readOnly = false;
+ }
+ else {
+ setSession( session );
+ }
}
/**
@@ -108,7 +118,9 @@
if ( s != session ) {
// check for s == null first, since it is least expensive
if ( s == null ){
- unsetSession();
+ // would be better to call unsetSession(), but it is not final...
+ session = null;
+ readOnly = false;
}
else if ( isConnectedToSession() ) {
//TODO: perhaps this should be some other RuntimeException...
@@ -116,6 +128,8 @@
}
else {
session = s;
+ // NOTE: the proxy may not be connected to the session yet, so set readOnly directly
+ readOnly = ! session.getFactory().getEntityPersister( entityName ).isMutable();
}
}
}
@@ -132,6 +146,7 @@
*/
public void unsetSession() {
session = null;
+ readOnly = false;
}
/**
@@ -223,6 +238,48 @@
/**
* {@inheritDoc}
*/
+ public boolean isReadOnly() {
+ errorIfReadOnlySettingNotAvailable();
+ if ( !isConnectedToSession() ) {
+ throw new TransientObjectException(
+ "The read-only/modifiable setting is only accessible when the proxy is
associated with a session." );
+ }
+ return readOnly;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setReadOnly(boolean readOnly) {
+ errorIfReadOnlySettingNotAvailable();
+ // only update if readOnly is different from current setting
+ if ( this.readOnly != readOnly ) {
+ Object proxy = getProxyOrNull();
+ if ( proxy == null ) {
+ throw new TransientObjectException(
+ "Cannot set the read-only/modifiable mode unless the proxy is associated with
a session." );
+ }
+ this.readOnly = readOnly;
+ if ( initialized ) {
+ session.getPersistenceContext().setReadOnly( target, readOnly );
+ }
+ }
+ }
+
+ private void errorIfReadOnlySettingNotAvailable() {
+ if ( session == null ) {
+ throw new TransientObjectException(
+ "Proxy is detached (i.e, session is null). The read-only/modifiable setting is
only accessible when the proxy is associated with an open session." );
+ }
+ if ( session.isClosed() ) {
+ throw new SessionException(
+ "Session is closed. The read-only/modifiable setting is only accessible when
the proxy is associated with an open session." );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public boolean isUnwrap() {
return unwrap;
}
Modified: core/trunk/core/src/main/java/org/hibernate/proxy/LazyInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/LazyInitializer.java 2010-01-12
21:00:11 UTC (rev 18524)
+++ core/trunk/core/src/main/java/org/hibernate/proxy/LazyInitializer.java 2010-01-13
01:04:55 UTC (rev 18525)
@@ -105,6 +105,37 @@
public void setImplementation(Object target);
/**
+ * Is the proxy read-only?.
+ *
+ * @return true, if this proxy is read-only; false, otherwise
+ * @throws org.hibernate.TransientObjectException if the proxy is not association with a
session
+ * @throws org.hibernate.SessionException if the proxy is associated with a sesssion
that is closed
+ *
+ * @see org.hibernate.Session#isReadOnly(Object entityOrProxy)
+ */
+ public boolean isReadOnly();
+
+ /**
+ * Set an associated modifiable proxy to read-only mode, or a read-only
+ * proxy to modifiable mode. If the proxy is currently initialized, its
+ * implementation will be set to the same mode; otherwise, when the
+ * proxy is initialized, its implementation will have the same read-only/
+ * modifiable setting as the proxy. In read-only mode, no snapshot is
+ * maintained and the instance is never dirty checked.
+ *
+ * If the associated proxy already has the specified read-only/modifiable
+ * setting, then this method does nothing.
+ *
+ * @param readOnly, if true, the associated proxy is made read-only;
+ * if false, the associated proxy is made modifiable.
+ * @throws org.hibernate.TransientObjectException if the proxy is not association with a
session
+ * @throws org.hibernate.SessionException if the proxy is associated with a sesssion
that is closed
+ *
+ * @see org.hibernate.Session#setReadOnly(Object entityOrProxy, boolean readOnly)
+ */
+ public void setReadOnly(boolean readOnly);
+
+ /**
* Get the session to which this proxy is associated, or null if it is not attached.
*
* @return The associated session.
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/readonly/ReadOnlyProxyTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/readonly/ReadOnlyProxyTest.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/readonly/ReadOnlyProxyTest.java 2010-01-13
01:04:55 UTC (rev 18525)
@@ -0,0 +1,1491 @@
+//$Id: ReadOnlyTest.java 10977 2006-12-12 23:28:04Z steve.ebersole(a)jboss.com $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.readonly;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import junit.framework.Test;
+
+import org.hibernate.CacheMode;
+import org.hibernate.Hibernate;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.TransientObjectException;
+import org.hibernate.SessionException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.junit.functional.FunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * Tests making initialized and uninitialized proxies read-only/modifiable
+ *
+ * @author Gail Badner
+ */
+public class ReadOnlyProxyTest extends FunctionalTestCase {
+
+ public ReadOnlyProxyTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "readonly/DataPoint.hbm.xml",
"readonly/TextHolder.hbm.xml" };
+ }
+
+ public void configure(Configuration cfg) {
+ cfg.setProperty(Environment.STATEMENT_BATCH_SIZE, "20");
+ }
+
+ public String getCacheConcurrencyStrategy() {
+ return null;
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( ReadOnlyProxyTest.class );
+ }
+
+ public void testReadOnlyViaSessionDoesNotInit() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp, true );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ s.setReadOnly( dp, false );
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ s.flush();
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ s.getTransaction().commit();
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyViaLazyInitializerDoesNotInit() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ LazyInitializer dpLI = ( ( HibernateProxy ) dp ).getHibernateLazyInitializer();
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ dpLI.setReadOnly( true );
+ checkReadOnly( s, dp, true );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ dpLI.setReadOnly( false );
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ s.flush();
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ s.getTransaction().commit();
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyViaSessionNoChangeAfterInit() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ Hibernate.initialize( dp );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp, true );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ Hibernate.initialize( dp );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, true );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp, true );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ s.setReadOnly( dp, false );
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ Hibernate.initialize( dp );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyViaLazyInitializerNoChangeAfterInit() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ LazyInitializer dpLI = ( ( HibernateProxy ) dp ).getHibernateLazyInitializer();
+ checkReadOnly( s, dp, false );
+ assertTrue( dpLI.isUninitialized() );
+ Hibernate.initialize( dp );
+ assertFalse( dpLI.isUninitialized() );
+ checkReadOnly( s, dp, false );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ dpLI = ( ( HibernateProxy ) dp ).getHibernateLazyInitializer();
+ dpLI.setReadOnly( true );
+ checkReadOnly( s, dp, true );
+ assertTrue( dpLI.isUninitialized() );
+ Hibernate.initialize( dp );
+ assertFalse( dpLI.isUninitialized() );
+ checkReadOnly( s, dp, true );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ dpLI = ( ( HibernateProxy ) dp ).getHibernateLazyInitializer();
+ dpLI.setReadOnly( true );
+ checkReadOnly( s, dp, true );
+ assertTrue( dpLI.isUninitialized() );
+ dpLI.setReadOnly( false );
+ checkReadOnly( s, dp, false );
+ assertTrue( dpLI.isUninitialized() );
+ Hibernate.initialize( dp );
+ assertFalse( dpLI.isUninitialized() );
+ checkReadOnly( s, dp, false );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyViaSessionBeforeInit() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ s.setReadOnly( dp, true );
+ dp.setDescription( "changed" );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ assertEquals( "changed", dp.getDescription() );
+ checkReadOnly( s, dp, true );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testModifiableViaSessionBeforeInit() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ checkReadOnly( s, dp, false );
+ dp.setDescription( "changed" );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ assertEquals( "changed", dp.getDescription() );
+ checkReadOnly( s, dp, false );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( "changed", dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyViaSessionBeforeInitByModifiableQuery() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ s.setReadOnly( dp, true );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, true );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ DataPoint dpFromQuery = ( DataPoint ) s.createQuery( "from DataPoint where
id=" + dpOrig.getId() ).setReadOnly( false ).uniqueResult();
+ assertTrue( Hibernate.isInitialized( dpFromQuery ) );
+ assertSame( dp, dpFromQuery );
+ checkReadOnly( s, dp, true );
+ dp.setDescription( "changed" );
+ assertEquals( "changed", dp.getDescription() );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyViaSessionBeforeInitByReadOnlyQuery() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp, true );
+ DataPoint dpFromQuery = ( DataPoint ) s.createQuery( "from DataPoint where
id=" + dpOrig.getId() ).setReadOnly( true ).uniqueResult();
+ assertTrue( Hibernate.isInitialized( dpFromQuery ) );
+ assertSame( dp, dpFromQuery );
+ checkReadOnly( s, dp, true );
+ dp.setDescription( "changed" );
+ assertEquals( "changed", dp.getDescription() );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testModifiableViaSessionBeforeInitByModifiableQuery() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ DataPoint dpFromQuery = ( DataPoint ) s.createQuery( "from DataPoint where
id=" + dpOrig.getId() ).setReadOnly( false ).uniqueResult();
+ assertTrue( Hibernate.isInitialized( dpFromQuery ) );
+ assertSame( dp, dpFromQuery );
+ checkReadOnly( s, dp, false );
+ dp.setDescription( "changed" );
+ assertEquals( "changed", dp.getDescription() );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( "changed", dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testModifiableViaSessionBeforeInitByReadOnlyQuery() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ DataPoint dpFromQuery = ( DataPoint ) s.createQuery( "from DataPoint where
id=" + dpOrig.getId() ).setReadOnly( true ).uniqueResult();
+ assertTrue( Hibernate.isInitialized( dpFromQuery ) );
+ assertSame( dp, dpFromQuery );
+ checkReadOnly( s, dp, false );
+ dp.setDescription( "changed" );
+ assertEquals( "changed", dp.getDescription() );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( "changed", dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyViaLazyInitializerBeforeInit() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ LazyInitializer dpLI = ( ( HibernateProxy ) dp ).getHibernateLazyInitializer();
+ assertTrue( dpLI.isUninitialized() );
+ checkReadOnly( s, dp, false );
+ dpLI.setReadOnly( true );
+ checkReadOnly( s, dp, true );
+ dp.setDescription( "changed" );
+ assertFalse( dpLI.isUninitialized() );
+ assertEquals( "changed", dp.getDescription() );
+ checkReadOnly( s, dp, true );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testModifiableViaLazyInitializerBeforeInit() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ LazyInitializer dpLI = ( ( HibernateProxy ) dp ).getHibernateLazyInitializer();
+ assertTrue( dp instanceof HibernateProxy );
+ assertTrue( dpLI.isUninitialized() );
+ checkReadOnly( s, dp, false );
+ dp.setDescription( "changed" );
+ assertFalse( dpLI.isUninitialized() );
+ assertEquals( "changed", dp.getDescription() );
+ checkReadOnly( s, dp, false );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( "changed", dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+
+ public void testReadOnlyViaLazyInitializerAfterInit() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ LazyInitializer dpLI = ( ( HibernateProxy ) dp ).getHibernateLazyInitializer();
+ assertTrue( dpLI.isUninitialized() );
+ checkReadOnly( s, dp, false );
+ dp.setDescription( "changed" );
+ assertFalse( dpLI.isUninitialized() );
+ assertEquals( "changed", dp.getDescription() );
+ checkReadOnly( s, dp, false );
+ dpLI.setReadOnly( true );
+ checkReadOnly( s, dp, true );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testModifiableViaLazyInitializerAfterInit() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ LazyInitializer dpLI = ( ( HibernateProxy ) dp ).getHibernateLazyInitializer();
+ assertTrue( dpLI.isUninitialized() );
+ checkReadOnly( s, dp, false );
+ dp.setDescription( "changed" );
+ assertFalse( dpLI.isUninitialized() );
+ assertEquals( "changed", dp.getDescription() );
+ checkReadOnly( s, dp, false );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( "changed", dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testModifyToReadOnlyToModifiableIsUpdatedFailureExpected() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ));
+ checkReadOnly( s, dp, false );
+ dp.setDescription( "changed" );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ assertEquals( "changed", dp.getDescription() );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp,true );
+ s.setReadOnly( dp, false );
+ checkReadOnly( s, dp, false );
+ assertEquals( "changed", dp.getDescription() );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ try {
+ assertEquals( "changed", dp.getDescription() );
+ // should fail due to HHH-4642
+ }
+ finally {
+ s.getTransaction().rollback();
+ s.close();
+ s = openSession();
+ s.beginTransaction();
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+ }
+
+ public void testReadOnlyModifiedToModifiableIsUpdatedFailureExpected() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ));
+ checkReadOnly( s, dp, false );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp,true );
+ dp.setDescription( "changed" );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ assertEquals( "changed", dp.getDescription() );
+ s.setReadOnly( dp, false );
+ checkReadOnly( s, dp, false );
+ assertEquals( "changed", dp.getDescription() );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ try {
+ assertEquals( "changed", dp.getDescription() );
+ // should fail due to HHH-4642
+ }
+ finally {
+ s.getTransaction().rollback();
+ s.close();
+ s = openSession();
+ s.beginTransaction();
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+ }
+
+ public void testReadOnlyChangedEvictedUpdate() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ));
+ checkReadOnly( s, dp, false );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp,true );
+ dp.setDescription( "changed" );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ assertEquals( "changed", dp.getDescription() );
+ s.evict( dp );
+ assertFalse( s.contains( dp ) );
+ s.update( dp );
+ checkReadOnly( s, dp, false );
+ assertEquals( "changed", dp.getDescription() );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( "changed", dp.getDescription() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyToModifiableInitWhenModifiedIsUpdated() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ checkReadOnly( s, dp, false );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp,true );
+ s.setReadOnly( dp, false );
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ));
+ dp.setDescription( "changed" );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ assertEquals( "changed", dp.getDescription() );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( "changed", dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyInitToModifiableModifiedIsUpdated() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ checkReadOnly( s, dp, false );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp,true );
+ assertFalse( Hibernate.isInitialized( dp ));
+ Hibernate.initialize( dp );
+ assertTrue( Hibernate.isInitialized( dp ));
+ checkReadOnly( s, dp,true );
+ s.setReadOnly( dp, false );
+ checkReadOnly( s, dp, false );
+ dp.setDescription( "changed" );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ assertEquals( "changed", dp.getDescription() );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( "changed", dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyModifiedUpdate() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ checkReadOnly( s, dp, false );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp,true );
+ assertFalse( Hibernate.isInitialized( dp ));
+ dp.setDescription( "changed" );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ assertEquals( "changed", dp.getDescription() );
+ checkReadOnly( s, dp,true );
+ s.update( dp );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyDelete() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ checkReadOnly( s, dp, false );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp,true );
+ assertFalse( Hibernate.isInitialized( dp ));
+ s.delete( dp );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertNull( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyProxyMergeDetachedProxyWithChange() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ));
+ Hibernate.initialize( dp );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ s.getTransaction().commit();
+ s.close();
+
+ // modify detached proxy
+ dp.setDescription( "changed" );
+
+ s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dpLoaded = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() )
);
+ assertTrue( dpLoaded instanceof HibernateProxy );
+ checkReadOnly( s, dpLoaded, false );
+ s.setReadOnly( dpLoaded, true );
+ checkReadOnly( s, dpLoaded,true );
+ assertFalse( Hibernate.isInitialized( dpLoaded ) );
+ DataPoint dpMerged = ( DataPoint ) s.merge( dp );
+ assertSame( dpLoaded, dpMerged );
+ assertTrue( Hibernate.isInitialized( dpLoaded ) );
+ assertEquals( "changed", dpLoaded.getDescription() );
+ checkReadOnly( s, dpLoaded, true );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyProxyInitMergeDetachedProxyWithChange() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ));
+ Hibernate.initialize( dp );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ s.getTransaction().commit();
+ s.close();
+
+ // modify detached proxy
+ dp.setDescription( "changed" );
+
+ s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dpLoaded = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() )
);
+ assertTrue( dpLoaded instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dpLoaded ) );
+ Hibernate.initialize( dpLoaded );
+ assertTrue( Hibernate.isInitialized( dpLoaded ) );
+ checkReadOnly( s, dpLoaded, false );
+ s.setReadOnly( dpLoaded, true );
+ checkReadOnly( s, dpLoaded,true );
+ DataPoint dpMerged = ( DataPoint ) s.merge( dp );
+ assertSame( dpLoaded, dpMerged );
+ assertEquals( "changed", dpLoaded.getDescription() );
+ checkReadOnly( s, dpLoaded, true );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyProxyMergeDetachedEntityWithChange() {
+
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ));
+ Hibernate.initialize( dp );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ s.getTransaction().commit();
+ s.close();
+
+ // modify detached proxy target
+ DataPoint dpEntity = ( DataPoint ) ( ( HibernateProxy ) dp
).getHibernateLazyInitializer().getImplementation();
+ dpEntity.setDescription( "changed" );
+
+ s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dpLoaded = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() )
);
+ assertTrue( dpLoaded instanceof HibernateProxy );
+ checkReadOnly( s, dpLoaded, false );
+ s.setReadOnly( dpLoaded, true );
+ checkReadOnly( s, dpLoaded,true );
+ assertFalse( Hibernate.isInitialized( dpLoaded ) );
+ DataPoint dpMerged = ( DataPoint ) s.merge( dpEntity );
+ assertSame( dpLoaded, dpMerged );
+ assertTrue( Hibernate.isInitialized( dpLoaded ) );
+ assertEquals( "changed", dpLoaded.getDescription() );
+ checkReadOnly( s, dpLoaded, true );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyProxyInitMergeDetachedEntityWithChange() {
+
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ));
+ Hibernate.initialize( dp );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ s.getTransaction().commit();
+ s.close();
+
+ // modify detached proxy target
+ DataPoint dpEntity = ( DataPoint ) ( ( HibernateProxy ) dp
).getHibernateLazyInitializer().getImplementation();
+ dpEntity.setDescription( "changed" );
+
+ s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dpLoaded = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() )
);
+ assertTrue( dpLoaded instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dpLoaded ) );
+ Hibernate.initialize( dpLoaded );
+ assertTrue( Hibernate.isInitialized( dpLoaded ) );
+ checkReadOnly( s, dpLoaded, false );
+ s.setReadOnly( dpLoaded, true );
+ checkReadOnly( s, dpLoaded,true );
+ DataPoint dpMerged = ( DataPoint ) s.merge( dpEntity );
+ assertSame( dpLoaded, dpMerged );
+ assertEquals( "changed", dpLoaded.getDescription() );
+ checkReadOnly( s, dpLoaded, true );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testReadOnlyEntityMergeDetachedProxyWithChange() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ checkReadOnly( s, dp, false );
+ assertFalse( Hibernate.isInitialized( dp ));
+ Hibernate.initialize( dp );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ s.getTransaction().commit();
+ s.close();
+
+ // modify detached proxy
+ dp.setDescription( "changed" );
+
+ s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
+ DataPoint dpEntity = ( DataPoint ) s.get( DataPoint.class, new Long( dpOrig.getId() )
);
+ assertFalse( dpEntity instanceof HibernateProxy );
+ assertFalse( s.isReadOnly( dpEntity ) );
+ s.setReadOnly( dpEntity, true );
+ assertTrue( s.isReadOnly( dpEntity ) );
+ DataPoint dpMerged = ( DataPoint ) s.merge( dp );
+ assertSame( dpEntity, dpMerged );
+ assertEquals( "changed", dpEntity.getDescription() );
+ assertTrue( s.isReadOnly( dpEntity ) );
+ s.flush();
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testSetReadOnlyInTwoTransactionsSameSession() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp, true );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ dp.setDescription( "changed" );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ assertEquals( "changed", dp.getDescription() );
+ s.flush();
+ s.getTransaction().commit();
+
+ checkReadOnly( s, dp, true );
+
+ s.beginTransaction();
+ checkReadOnly( s, dp, true );
+ dp.setDescription( "changed again" );
+ assertEquals( "changed again", dp.getDescription() );
+ s.flush();
+ s.getTransaction().commit();
+
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testSetReadOnlyBetweenTwoTransactionsSameSession() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ dp.setDescription( "changed" );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ assertEquals( "changed", dp.getDescription() );
+ checkReadOnly( s, dp, false );
+ s.flush();
+ s.getTransaction().commit();
+
+ checkReadOnly( s, dp, false );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp, true );
+
+ s.beginTransaction();
+ checkReadOnly( s, dp, true );
+ dp.setDescription( "changed again" );
+ assertEquals( "changed again", dp.getDescription() );
+ s.flush();
+ s.getTransaction().commit();
+
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( "changed", dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testSetModifiableBetweenTwoTransactionsSameSession() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ s.setReadOnly( dp, true );
+ checkReadOnly( s, dp, true );
+ dp.setDescription( "changed" );
+ assertTrue( Hibernate.isInitialized( dp ) );
+ assertEquals( "changed", dp.getDescription() );
+ checkReadOnly( s, dp, true );
+ s.flush();
+ s.getTransaction().commit();
+
+ checkReadOnly( s, dp, true );
+ s.setReadOnly( dp, false );
+ checkReadOnly( s, dp, false );
+
+ s.beginTransaction();
+ checkReadOnly( s, dp, false );
+ assertEquals( "changed", dp.getDescription() );
+ s.refresh( dp );
+ assertEquals( dpOrig.getDescription(), dp.getDescription() );
+ checkReadOnly( s, dp, false );
+ dp.setDescription( "changed again" );
+ assertEquals( "changed again", dp.getDescription() );
+ s.flush();
+ s.getTransaction().commit();
+
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dpOrig.getId() );
+ assertEquals( dpOrig.getId(), dp.getId() );
+ assertEquals( "changed again", dp.getDescription() );
+ assertEquals( dpOrig.getX(), dp.getX() );
+ assertEquals( dpOrig.getY(), dp.getY() );
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testIsReadOnlyAfterSessionClosed() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ s.getTransaction().commit();
+ s.close();
+
+ try {
+ s.isReadOnly( dp );
+ fail( "should have failed because session was closed" );
+ }
+ catch ( SessionException ex) {
+ // expected
+ }
+ finally {
+ s = openSession();
+ s.beginTransaction();
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+ }
+
+ public void testIsReadOnlyAfterSessionClosedViaLazyInitializer() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ s.getTransaction().commit();
+ assertTrue( s.contains( dp ) );
+ s.close();
+
+ assertNull( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getSession() );
+ try {
+ ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().isReadOnly();
+ fail( "should have failed because session was detached" );
+ }
+ catch ( TransientObjectException ex) {
+ // expected
+ }
+ finally {
+ s = openSession();
+ s.beginTransaction();
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+ }
+
+
+ public void testDetachedIsReadOnlyAfterEvictViaSession() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ assertTrue( s.contains( dp ) );
+ s.evict( dp );
+ assertFalse( s.contains( dp ) );
+ assertNull( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getSession() );
+
+ try {
+ s.isReadOnly( dp );
+ fail( "should have failed because proxy was detached" );
+ }
+ catch ( TransientObjectException ex) {
+ // expected
+ }
+ finally {
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+ }
+
+ public void testDetachedIsReadOnlyAfterEvictViaLazyInitializer() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ s.evict( dp );
+ assertFalse( s.contains( dp ) );
+ assertNull( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getSession() );
+ try {
+ ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().isReadOnly();
+ fail( "should have failed because proxy was detached" );
+ }
+ catch ( TransientObjectException ex) {
+ // expected
+ }
+ finally {
+ s.beginTransaction();
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+ }
+
+ public void testSetReadOnlyAfterSessionClosed() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ s.getTransaction().commit();
+ s.close();
+
+ try {
+ s.setReadOnly( dp, true );
+ fail( "should have failed because session was closed" );
+ }
+ catch ( SessionException ex) {
+ // expected
+ }
+ finally {
+ s = openSession();
+ s.beginTransaction();
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+ }
+
+ public void testSetReadOnlyAfterSessionClosedViaLazyInitializer() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ s.getTransaction().commit();
+ assertTrue( s.contains( dp ) );
+ s.close();
+
+ assertNull( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getSession() );
+ try {
+ ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().setReadOnly( true );
+ fail( "should have failed because session was detached" );
+ }
+ catch ( TransientObjectException ex) {
+ // expected
+ }
+ finally {
+ s = openSession();
+ s.beginTransaction();
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+ }
+
+
+ public void testDetachedSetReadOnlyAfterEvictViaSession() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ assertTrue( s.contains( dp ) );
+ s.evict( dp );
+ assertFalse( s.contains( dp ) );
+ assertNull( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getSession() );
+
+ try {
+ s.setReadOnly( dp, true );
+ fail( "should have failed because proxy was detached" );
+ }
+ catch ( TransientObjectException ex) {
+ // expected
+ }
+ finally {
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+ }
+
+ public void testDetachedSetReadOnlyAfterEvictViaLazyInitializer() {
+ DataPoint dpOrig = createDataPoint( CacheMode.IGNORE );
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+
+ s.beginTransaction();
+ DataPoint dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpOrig.getId() ) );
+ assertTrue( dp instanceof HibernateProxy );
+ assertFalse( Hibernate.isInitialized( dp ) );
+ checkReadOnly( s, dp, false );
+ s.evict( dp );
+ assertFalse( s.contains( dp ) );
+ assertNull( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().getSession() );
+ try {
+ ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().setReadOnly( true );
+ fail( "should have failed because proxy was detached" );
+ }
+ catch ( TransientObjectException ex) {
+ // expected
+ }
+ finally {
+ s.beginTransaction();
+ s.delete( dp );
+ s.getTransaction().commit();
+ s.close();
+ }
+ }
+
+ private DataPoint createDataPoint(CacheMode cacheMode) {
+ Session s = openSession();
+ s.setCacheMode( cacheMode );
+ 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) );
+ dp.setDescription( "original" );
+ s.save( dp );
+ s.getTransaction().commit();
+ s.close();
+ return dp;
+ }
+
+ private void checkReadOnly(Session s, Object proxy, boolean expectedReadOnly) {
+ assertTrue( proxy instanceof HibernateProxy );
+ LazyInitializer li = ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer();
+ assertSame( s, li.getSession() );
+ assertEquals( expectedReadOnly, s.isReadOnly( proxy ) );
+ assertEquals( expectedReadOnly, li.isReadOnly() );
+ assertEquals( Hibernate.isInitialized( proxy ), ! li.isUninitialized() );
+ if ( Hibernate.isInitialized( proxy ) ) {
+ assertEquals( expectedReadOnly, s.isReadOnly( li.getImplementation() ) );
+ }
+ }
+}
Modified:
core/trunk/testsuite/src/test/java/org/hibernate/test/readonly/ReadOnlyTest.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/readonly/ReadOnlyTest.java 2010-01-12
21:00:11 UTC (rev 18524)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/readonly/ReadOnlyTest.java 2010-01-13
01:04:55 UTC (rev 18525)
@@ -67,7 +67,7 @@
return new FunctionalTestClassTestSuite( ReadOnlyTest.class );
}
- public void testReadOnlyOnProxiesFailureExpected() {
+ public void testReadOnlyOnProxies() {
Session s = openSession();
s.setCacheMode( CacheMode.IGNORE );
s.beginTransaction();
@@ -82,6 +82,7 @@
s = openSession();
s.setCacheMode(CacheMode.IGNORE);
+ s.beginTransaction();
dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpId ) );
assertFalse( "was initialized", Hibernate.isInitialized( dp ) );
s.setReadOnly( dp, true );
@@ -178,6 +179,138 @@
}
+ public void testReadOnlyDelete() {
+
+ 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();
+
+ s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ t = s.beginTransaction();
+ dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
+ s.setReadOnly( dp, true );
+ s.delete( dp );
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ List list = s.createQuery("from DataPoint where
description='done!'").list();
+ assertTrue( list.isEmpty() );
+ t.commit();
+ s.close();
+
+ }
+
+ public void testReadOnlyModeWithExistingModifiableEntity() {
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ Transaction t = s.beginTransaction();
+ DataPoint dp = null;
+ for ( int i=0; i<100; i++ ) {
+ dp = new DataPoint();
+ dp.setX( new BigDecimal(i * 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();
+ DataPoint dpLast = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
+ assertFalse( s.isReadOnly( dpLast ) );
+ int i = 0;
+ ScrollableResults sr = s.createQuery("from DataPoint dp order by dp.x asc")
+ .setReadOnly(true)
+ .scroll(ScrollMode.FORWARD_ONLY);
+ int nExpectedChanges = 0;
+ while ( sr.next() ) {
+ dp = (DataPoint) sr.get(0);
+ if ( dp.getId() == dpLast.getId() ) {
+ //dpLast existed in the session before executing the read-only query
+ assertFalse( s.isReadOnly( dp ) );
+ }
+ else {
+ assertTrue( s.isReadOnly( dp ) );
+ }
+ if (++i==50) {
+ s.setReadOnly(dp, false);
+ nExpectedChanges = ( dp == dpLast ? 1 : 2 );
+ }
+ dp.setDescription("done!");
+ }
+ t.commit();
+ s.clear();
+ t = s.beginTransaction();
+ List list = s.createQuery("from DataPoint where
description='done!'").list();
+ assertEquals( list.size(), nExpectedChanges );
+ s.createQuery("delete from DataPoint").executeUpdate();
+ t.commit();
+ s.close();
+ }
+
+ public void testModifiableModeWithExistingReadOnlyEntity() {
+
+ Session s = openSession();
+ s.setCacheMode(CacheMode.IGNORE);
+ Transaction t = s.beginTransaction();
+ DataPoint dp = null;
+ for ( int i=0; i<100; i++ ) {
+ dp = new DataPoint();
+ dp.setX( new BigDecimal(i * 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();
+ DataPoint dpLast = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
+ assertFalse( s.isReadOnly( dpLast ) );
+ s.setReadOnly( dpLast, true );
+ assertTrue( s.isReadOnly( dpLast ) );
+ int i = 0;
+ ScrollableResults sr = s.createQuery("from DataPoint dp order by dp.x asc")
+ .setReadOnly(false)
+ .scroll(ScrollMode.FORWARD_ONLY);
+ int nExpectedChanges = 0;
+ while ( sr.next() ) {
+ dp = (DataPoint) sr.get(0);
+ if ( dp.getId() == dpLast.getId() ) {
+ //dpLast existed in the session before executing the read-only query
+ assertTrue( s.isReadOnly( dp ) );
+ }
+ else {
+ assertFalse( s.isReadOnly( dp ) );
+ }
+ if (++i==50) {
+ s.setReadOnly(dp, true);
+ nExpectedChanges = ( dp == dpLast ? 99 : 98 );
+ }
+ dp.setDescription("done!");
+ }
+ t.commit();
+ s.clear();
+ t = s.beginTransaction();
+ List list = s.createQuery("from DataPoint where
description='done!'").list();
+ assertEquals( list.size(), nExpectedChanges );
+ s.createQuery("delete from DataPoint").executeUpdate();
+ t.commit();
+ s.close();
+ }
+
public void testReadOnlyOnTextType() {
final String origText = "some huge text string";
final String newText = "some even bigger text string";