HHH-4828 : Entities returned by Query...setReadOnly(true)...iterate() should be read-only

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18660 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Gail Badner 2010-01-27 23:59:29 +00:00
parent c1fb90d575
commit d586421cfb
4 changed files with 592 additions and 41 deletions

View File

@ -951,7 +951,7 @@ public class QueryTranslatorImpl extends BasicLoader implements FilterTranslator
PreparedStatement st = prepareQueryStatement( queryParameters, false, session ); PreparedStatement st = prepareQueryStatement( queryParameters, false, session );
ResultSet rs = getResultSet( st, queryParameters.hasAutoDiscoverScalarTypes(), false, queryParameters.getRowSelection(), session ); ResultSet rs = getResultSet( st, queryParameters.hasAutoDiscoverScalarTypes(), false, queryParameters.getRowSelection(), session );
HolderInstantiator hi = HolderInstantiator.createClassicHolderInstantiator(holderConstructor, queryParameters.getResultTransformer()); HolderInstantiator hi = HolderInstantiator.createClassicHolderInstantiator(holderConstructor, queryParameters.getResultTransformer());
Iterator result = new IteratorImpl( rs, st, session, returnTypes, getColumnNames(), hi ); Iterator result = new IteratorImpl( rs, st, session, queryParameters.isReadOnly( session ), returnTypes, getColumnNames(), hi );
if ( stats ) { if ( stats ) {
session.getFactory().getStatisticsImplementor().queryExecuted( session.getFactory().getStatisticsImplementor().queryExecuted(

View File

@ -51,6 +51,7 @@ public final class IteratorImpl implements HibernateIterator {
private ResultSet rs; private ResultSet rs;
private final EventSource session; private final EventSource session;
private boolean readOnly;
private final Type[] types; private final Type[] types;
private final boolean single; private final boolean single;
private Object currentResult; private Object currentResult;
@ -63,6 +64,7 @@ public final class IteratorImpl implements HibernateIterator {
ResultSet rs, ResultSet rs,
PreparedStatement ps, PreparedStatement ps,
EventSource sess, EventSource sess,
boolean readOnly,
Type[] types, Type[] types,
String[][] columnNames, String[][] columnNames,
HolderInstantiator holderInstantiator) HolderInstantiator holderInstantiator)
@ -71,6 +73,7 @@ public final class IteratorImpl implements HibernateIterator {
this.rs=rs; this.rs=rs;
this.ps=ps; this.ps=ps;
this.session = sess; this.session = sess;
this.readOnly = readOnly;
this.types = types; this.types = types;
this.names = columnNames; this.names = columnNames;
this.holderInstantiator = holderInstantiator; this.holderInstantiator = holderInstantiator;
@ -127,6 +130,8 @@ public final class IteratorImpl implements HibernateIterator {
public Object next() throws HibernateException { public Object next() throws HibernateException {
if ( !hasNext ) throw new NoSuchElementException("No more results"); if ( !hasNext ) throw new NoSuchElementException("No more results");
boolean sessionDefaultReadOnlyOrig = session.isDefaultReadOnly();
session.setDefaultReadOnly( readOnly );
try { try {
boolean isHolder = holderInstantiator.isRequired(); boolean isHolder = holderInstantiator.isRequired();
@ -159,6 +164,9 @@ public final class IteratorImpl implements HibernateIterator {
"could not get next iterator result" "could not get next iterator result"
); );
} }
finally {
session.setDefaultReadOnly( sessionDefaultReadOnlyOrig );
}
} }
public void remove() { public void remove() {

View File

@ -442,6 +442,7 @@ public class QueryLoader extends BasicLoader {
rs, rs,
st, st,
session, session,
queryParameters.isReadOnly( session ),
queryReturnTypes, queryReturnTypes,
queryTranslator.getColumnNames(), queryTranslator.getColumnNames(),
buildHolderInstantiator( queryParameters.getResultTransformer() ) buildHolderInstantiator( queryParameters.getResultTransformer() )

View File

@ -26,12 +26,14 @@
package org.hibernate.test.readonly; package org.hibernate.test.readonly;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Iterator;
import java.util.List; import java.util.List;
import junit.framework.Test; import junit.framework.Test;
import org.hibernate.CacheMode; import org.hibernate.CacheMode;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.ScrollMode; import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults; import org.hibernate.ScrollableResults;
import org.hibernate.Session; import org.hibernate.Session;
@ -107,45 +109,7 @@ public class ReadOnlySessionTest extends FunctionalTestCase {
s.close(); s.close();
} }
public void testReadOnlyMode() { public void testReadOnlySessionDefaultQueryScroll() {
Session s = openSession();
s.setCacheMode(CacheMode.IGNORE);
Transaction t = s.beginTransaction();
for ( int i=0; i<100; i++ ) {
DataPoint 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();
s.setDefaultReadOnly( true );
int i = 0;
ScrollableResults sr = s.createQuery("from DataPoint dp order by dp.x asc")
.scroll(ScrollMode.FORWARD_ONLY);
while ( sr.next() ) {
DataPoint dp = (DataPoint) sr.get(0);
if (++i==50) {
s.setReadOnly(dp, false);
}
dp.setDescription("done!");
}
t.commit();
s.clear();
t = s.beginTransaction();
List single = s.createQuery("from DataPoint where description='done!'").list();
assertEquals( single.size(), 1 );
s.createQuery("delete from DataPoint").executeUpdate();
t.commit();
s.close();
}
public void testReadOnlyQueryScrollChangeToModifiableBeforeIterate() {
Session s = openSession(); Session s = openSession();
s.setCacheMode(CacheMode.IGNORE); s.setCacheMode(CacheMode.IGNORE);
@ -184,6 +148,584 @@ public class ReadOnlySessionTest extends FunctionalTestCase {
s.close(); s.close();
} }
public void testReadOnlySessionModifiableQueryScroll() {
Session s = openSession();
s.setCacheMode(CacheMode.IGNORE);
Transaction t = s.beginTransaction();
for ( int i=0; i<100; i++ ) {
DataPoint 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();
s.setDefaultReadOnly( true );
int i = 0;
ScrollableResults sr = s.createQuery("from DataPoint dp order by dp.x asc")
.setReadOnly( false )
.scroll(ScrollMode.FORWARD_ONLY);
while ( sr.next() ) {
DataPoint dp = (DataPoint) sr.get(0);
if (++i==50) {
s.setReadOnly(dp, true);
}
dp.setDescription("done!");
}
t.commit();
s.clear();
t = s.beginTransaction();
List list = s.createQuery("from DataPoint where description='done!'").list();
assertEquals( 99, list.size() );
s.createQuery("delete from DataPoint").executeUpdate();
t.commit();
s.close();
}
public void testModifiableSessionReadOnlyQueryScroll() {
Session s = openSession();
s.setCacheMode(CacheMode.IGNORE);
Transaction t = s.beginTransaction();
for ( int i=0; i<100; i++ ) {
DataPoint 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();
assertFalse( s.isDefaultReadOnly() );
int i = 0;
ScrollableResults sr = s.createQuery("from DataPoint dp order by dp.x asc")
.setReadOnly( true )
.scroll(ScrollMode.FORWARD_ONLY);
while ( sr.next() ) {
DataPoint dp = (DataPoint) sr.get(0);
if (++i==50) {
s.setReadOnly(dp, false);
}
dp.setDescription("done!");
}
t.commit();
s.clear();
t = s.beginTransaction();
List single = s.createQuery("from DataPoint where description='done!'").list();
assertEquals( 1, single.size() );
s.createQuery("delete from DataPoint").executeUpdate();
t.commit();
s.close();
}
public void testModifiableSessionDefaultQueryReadOnlySessionScroll() {
Session s = openSession();
s.setCacheMode(CacheMode.IGNORE);
Transaction t = s.beginTransaction();
for ( int i=0; i<100; i++ ) {
DataPoint 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();
s.setDefaultReadOnly( false );
int i = 0;
Query query = s.createQuery("from DataPoint dp order by dp.x asc");
s.setDefaultReadOnly( true );
ScrollableResults sr = query.scroll(ScrollMode.FORWARD_ONLY);
s.setDefaultReadOnly( false );
while ( sr.next() ) {
DataPoint dp = (DataPoint) sr.get(0);
if (++i==50) {
s.setReadOnly(dp, false);
}
dp.setDescription("done!");
}
t.commit();
s.clear();
t = s.beginTransaction();
List single = s.createQuery("from DataPoint where description='done!'").list();
assertEquals( 1, single.size() );
s.createQuery("delete from DataPoint").executeUpdate();
t.commit();
s.close();
}
public void testQueryReadOnlyScroll() {
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();
s.setDefaultReadOnly( false );
int i = 0;
Query query = s.createQuery("from DataPoint dp order by dp.x asc");
assertFalse( query.isReadOnly() );
s.setDefaultReadOnly( true );
assertTrue( query.isReadOnly() );
s.setDefaultReadOnly( false );
assertFalse( query.isReadOnly() );
query.setReadOnly( true );
assertTrue( query.isReadOnly() );
s.setDefaultReadOnly( true );
assertTrue( query.isReadOnly() );
s.setDefaultReadOnly( false );
assertTrue( query.isReadOnly() );
query.setReadOnly( false );
assertFalse( query.isReadOnly() );
s.setDefaultReadOnly( true );
assertFalse( query.isReadOnly() );
query.setReadOnly( true );
assertTrue( query.isReadOnly() );
s.setDefaultReadOnly( false );
assertFalse( s.isDefaultReadOnly() );
ScrollableResults sr = query.scroll(ScrollMode.FORWARD_ONLY);
assertFalse( s.isDefaultReadOnly() );
assertTrue( query.isReadOnly() );
DataPoint dpLast = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
assertFalse( s.isReadOnly( dpLast ) );
query.setReadOnly( false );
assertFalse( query.isReadOnly() );
int nExpectedChanges = 0;
assertFalse( s.isDefaultReadOnly() );
while ( sr.next() ) {
assertFalse( s.isDefaultReadOnly() );
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!");
}
assertFalse( s.isDefaultReadOnly() );
t.commit();
s.clear();
t = s.beginTransaction();
List list = s.createQuery("from DataPoint where description='done!'").list();
assertEquals( nExpectedChanges, list.size() );
s.createQuery("delete from DataPoint").executeUpdate();
t.commit();
s.close();
}
public void testQueryModifiableScroll() {
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();
s.setDefaultReadOnly( true );
int i = 0;
Query query = s.createQuery("from DataPoint dp order by dp.x asc");
assertTrue( query.isReadOnly() );
s.setDefaultReadOnly( false );
assertFalse( query.isReadOnly() );
s.setDefaultReadOnly( true );
assertTrue( query.isReadOnly() );
query.setReadOnly( false );
assertFalse( query.isReadOnly() );
s.setDefaultReadOnly( false );
assertFalse( query.isReadOnly() );
s.setDefaultReadOnly( true );
assertFalse( query.isReadOnly() );
query.setReadOnly( true );
assertTrue( query.isReadOnly() );
s.setDefaultReadOnly( false );
assertTrue( query.isReadOnly() );
query.setReadOnly( false );
assertFalse( query.isReadOnly() );
s.setDefaultReadOnly( true );
assertTrue( s.isDefaultReadOnly() );
ScrollableResults sr = query.scroll(ScrollMode.FORWARD_ONLY);
assertFalse( query.isReadOnly() );
DataPoint dpLast = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
assertTrue( s.isReadOnly( dpLast ) );
query.setReadOnly( true );
assertTrue( query.isReadOnly() );
int nExpectedChanges = 0;
assertTrue( s.isDefaultReadOnly() );
while ( sr.next() ) {
assertTrue( s.isDefaultReadOnly() );
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!");
}
assertTrue( s.isDefaultReadOnly() );
t.commit();
s.clear();
t = s.beginTransaction();
List list = s.createQuery("from DataPoint where description='done!'").list();
assertEquals( nExpectedChanges, list.size() );
s.createQuery("delete from DataPoint").executeUpdate();
t.commit();
s.close();
}
public void testReadOnlySessionDefaultQueryIterate() {
Session s = openSession();
s.setCacheMode(CacheMode.IGNORE);
Transaction t = s.beginTransaction();
for ( int i=0; i<100; i++ ) {
DataPoint 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();
s.setDefaultReadOnly( true );
int i = 0;
Iterator it = s.createQuery("from DataPoint dp order by dp.x asc")
.iterate();
s.setDefaultReadOnly( false );
while ( it.hasNext() ) {
DataPoint dp = (DataPoint) it.next();
if (++i==50) {
s.setReadOnly(dp, false);
}
dp.setDescription("done!");
}
t.commit();
s.clear();
t = s.beginTransaction();
List single = s.createQuery("from DataPoint where description='done!'").list();
assertEquals( 1, single.size() );
s.createQuery("delete from DataPoint").executeUpdate();
t.commit();
s.close();
}
public void testReadOnlySessionModifiableQueryIterate() {
Session s = openSession();
s.setCacheMode(CacheMode.IGNORE);
Transaction t = s.beginTransaction();
for ( int i=0; i<100; i++ ) {
DataPoint 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();
s.setDefaultReadOnly( true );
int i = 0;
Iterator it = s.createQuery("from DataPoint dp order by dp.x asc")
.setReadOnly( false )
.iterate();
while ( it.hasNext() ) {
DataPoint dp = (DataPoint) it.next();
if (++i==50) {
s.setReadOnly(dp, true);
}
dp.setDescription("done!");
}
t.commit();
s.clear();
t = s.beginTransaction();
List list = s.createQuery("from DataPoint where description='done!'").list();
assertEquals( 99, list.size() );
s.createQuery("delete from DataPoint").executeUpdate();
t.commit();
s.close();
}
public void testModifiableSessionReadOnlyQueryIterate() {
Session s = openSession();
s.setCacheMode(CacheMode.IGNORE);
Transaction t = s.beginTransaction();
for ( int i=0; i<100; i++ ) {
DataPoint 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();
assertFalse( s.isDefaultReadOnly() );
int i = 0;
Iterator it = s.createQuery("from DataPoint dp order by dp.x asc")
.setReadOnly( true )
.iterate();
while ( it.hasNext() ) {
DataPoint dp = (DataPoint) it.next();
if (++i==50) {
s.setReadOnly(dp, false);
}
dp.setDescription("done!");
}
t.commit();
s.clear();
t = s.beginTransaction();
List single = s.createQuery("from DataPoint where description='done!'").list();
assertEquals( 1, single.size() );
s.createQuery("delete from DataPoint").executeUpdate();
t.commit();
s.close();
}
public void testModifiableSessionDefaultQueryReadOnlySessionIterate() {
Session s = openSession();
s.setCacheMode(CacheMode.IGNORE);
Transaction t = s.beginTransaction();
for ( int i=0; i<100; i++ ) {
DataPoint 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();
s.setDefaultReadOnly( false );
int i = 0;
Query query = s.createQuery("from DataPoint dp order by dp.x asc");
s.setDefaultReadOnly( true );
Iterator it = query.iterate();
s.setDefaultReadOnly( false );
while ( it.hasNext() ) {
DataPoint dp = (DataPoint) it.next();
if (++i==50) {
s.setReadOnly(dp, false);
}
dp.setDescription("done!");
}
t.commit();
s.clear();
t = s.beginTransaction();
List single = s.createQuery("from DataPoint where description='done!'").list();
assertEquals( 1, single.size() );
s.createQuery("delete from DataPoint").executeUpdate();
t.commit();
s.close();
}
public void testQueryReadOnlyIterate() {
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();
s.setDefaultReadOnly( false );
int i = 0;
Query query = s.createQuery("from DataPoint dp order by dp.x asc");
assertFalse( query.isReadOnly() );
s.setDefaultReadOnly( true );
assertTrue( query.isReadOnly() );
s.setDefaultReadOnly( false );
assertFalse( query.isReadOnly() );
query.setReadOnly( true );
assertTrue( query.isReadOnly() );
s.setDefaultReadOnly( true );
assertTrue( query.isReadOnly() );
s.setDefaultReadOnly( false );
assertTrue( query.isReadOnly() );
query.setReadOnly( false );
assertFalse( query.isReadOnly() );
s.setDefaultReadOnly( true );
assertFalse( query.isReadOnly() );
query.setReadOnly( true );
assertTrue( query.isReadOnly() );
s.setDefaultReadOnly( false );
assertFalse( s.isDefaultReadOnly() );
Iterator it = query.iterate();
assertTrue( query.isReadOnly() );
DataPoint dpLast = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
assertFalse( s.isReadOnly( dpLast ) );
query.setReadOnly( false );
assertFalse( query.isReadOnly() );
int nExpectedChanges = 0;
assertFalse( s.isDefaultReadOnly() );
while ( it.hasNext() ) {
assertFalse( s.isDefaultReadOnly() );
dp = (DataPoint) it.next();
assertFalse( s.isDefaultReadOnly() );
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!");
}
assertFalse( s.isDefaultReadOnly() );
t.commit();
s.clear();
t = s.beginTransaction();
List list = s.createQuery("from DataPoint where description='done!'").list();
assertEquals( nExpectedChanges, list.size() );
s.createQuery("delete from DataPoint").executeUpdate();
t.commit();
s.close();
}
public void testQueryModifiableIterate() {
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();
s.setDefaultReadOnly( true );
int i = 0;
Query query = s.createQuery("from DataPoint dp order by dp.x asc");
assertTrue( query.isReadOnly() );
s.setDefaultReadOnly( false );
assertFalse( query.isReadOnly() );
s.setDefaultReadOnly( true );
assertTrue( query.isReadOnly() );
query.setReadOnly( false );
assertFalse( query.isReadOnly() );
s.setDefaultReadOnly( false );
assertFalse( query.isReadOnly() );
s.setDefaultReadOnly( true );
assertFalse( query.isReadOnly() );
query.setReadOnly( true );
assertTrue( query.isReadOnly() );
s.setDefaultReadOnly( false );
assertTrue( query.isReadOnly() );
query.setReadOnly( false );
assertFalse( query.isReadOnly() );
s.setDefaultReadOnly( true );
assertTrue( s.isDefaultReadOnly() );
Iterator it = query.iterate();
assertFalse( query.isReadOnly() );
DataPoint dpLast = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
assertTrue( s.isReadOnly( dpLast ) );
query.setReadOnly( true );
assertTrue( query.isReadOnly() );
int nExpectedChanges = 0;
assertTrue( s.isDefaultReadOnly() );
while ( it.hasNext() ) {
assertTrue( s.isDefaultReadOnly() );
dp = (DataPoint) it.next();
assertTrue( s.isDefaultReadOnly() );
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!");
}
assertTrue( s.isDefaultReadOnly() );
t.commit();
s.clear();
t = s.beginTransaction();
List list = s.createQuery("from DataPoint where description='done!'").list();
assertEquals( nExpectedChanges, list.size() );
s.createQuery("delete from DataPoint").executeUpdate();
t.commit();
s.close();
}
public void testReadOnlyRefresh() { public void testReadOnlyRefresh() {
Session s = openSession(); Session s = openSession();
@ -675,4 +1217,4 @@ public class ReadOnlySessionTest extends FunctionalTestCase {
s.close(); s.close();
} }
} }