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:
parent
c1fb90d575
commit
d586421cfb
|
@ -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(
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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() )
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue