Fix refresh of a Proxy instance
This commit is contained in:
parent
1589686608
commit
0fbfc30eaa
|
@ -590,9 +590,6 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||
if ( entityInstance instanceof HibernateProxy ) {
|
||||
LazyInitializer hibernateLazyInitializer = ( (HibernateProxy) entityInstance ).getHibernateLazyInitializer();
|
||||
if ( !hibernateLazyInitializer.isUninitialized() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object instance = persistenceContext.getEntity( entityKey );
|
||||
if ( instance == null ) {
|
||||
|
|
|
@ -127,26 +127,6 @@ public class StandardRowReader<T> implements RowReader<T> {
|
|||
// todo (6.0) : we may want to split handling of initializers into specific sub-type handling
|
||||
// - meaning we'd have something like:
|
||||
|
||||
// for ( EntityInitializer initializer : entityInitializers ) {
|
||||
// initializer.resolveKey( rowProcessingState );
|
||||
// }
|
||||
//
|
||||
// for ( EntityInitializer initializer : collectionInitializers ) {
|
||||
// initializer.resolveKey( rowProcessingState );
|
||||
// }
|
||||
//
|
||||
// for ( Initializer initializer : entityInitializers ) {
|
||||
// initializer.resolveInstance( rowProcessingState );
|
||||
// }
|
||||
//
|
||||
// for ( EntityInitializer initializer : collectionInitializers ) {
|
||||
// initializer.resolveInstance( rowProcessingState );
|
||||
// }
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// old
|
||||
|
||||
final int numberOfInitializers = initializers.size();
|
||||
|
||||
for ( int i = 0; i < numberOfInitializers; i++ ) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.readonly;
|
||||
package org.hibernate.orm.test.readonly;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
|
@ -18,14 +18,21 @@ import org.hibernate.Transaction;
|
|||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.test.readonly.AbstractReadOnlyTest;
|
||||
import org.hibernate.test.readonly.Container;
|
||||
import org.hibernate.test.readonly.DataPoint;
|
||||
import org.hibernate.test.readonly.Info;
|
||||
import org.hibernate.test.readonly.Owner;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Model:
|
||||
|
@ -48,15 +55,14 @@ import static org.junit.Assert.assertTrue;
|
|||
*
|
||||
* @author Gail Badner
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = { "org/hibernate/test/readonly/DataPoint.hbm.xml" }
|
||||
)
|
||||
public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
return new String[] { "readonly/DataPoint.hbm.xml" };
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public void testExistingModifiableAfterSetSessionReadOnly() {
|
||||
public void testExistingModifiableAfterSetSessionReadOnly(SessionFactoryScope scope) {
|
||||
Container cOrig = createContainer();
|
||||
Set expectedInitializedObjects = new HashSet(
|
||||
Arrays.asList(
|
||||
|
@ -74,7 +80,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
);
|
||||
Set expectedReadOnlyObjects = new HashSet();
|
||||
|
||||
Session s = openSession();
|
||||
Session s = openSession(scope);
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
Transaction t = s.beginTransaction();
|
||||
s.save( cOrig );
|
||||
|
@ -97,7 +103,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
assertSame( cOrig, c );
|
||||
checkContainer( cOrig, expectedInitializedObjects, expectedReadOnlyObjects, s );
|
||||
s.evict( cOrig );
|
||||
c = ( Container ) s.get( Container.class, cOrig.getId() );
|
||||
c = s.get( Container.class, cOrig.getId() );
|
||||
assertNotSame( cOrig, c );
|
||||
expectedInitializedObjects = new HashSet(
|
||||
Arrays.asList(
|
||||
|
@ -140,7 +146,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
checkContainer( c, expectedInitializedObjects, expectedReadOnlyObjects, s );
|
||||
t.commit();
|
||||
s.close();
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from DataPoint").executeUpdate();
|
||||
s.createQuery("delete from Container").executeUpdate();
|
||||
|
@ -153,7 +159,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
|
||||
@Test
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public void testExistingReadOnlyAfterSetSessionModifiable() {
|
||||
public void testExistingReadOnlyAfterSetSessionModifiable(SessionFactoryScope scope) {
|
||||
|
||||
Container cOrig = createContainer();
|
||||
Set expectedInitializedObjects = new HashSet(
|
||||
|
@ -171,7 +177,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
)
|
||||
);
|
||||
Set expectedReadOnlyObjects = new HashSet();
|
||||
Session s = openSession();
|
||||
Session s = openSession(scope);
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
Transaction t = s.beginTransaction();
|
||||
s.save( cOrig );
|
||||
|
@ -182,7 +188,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.setDefaultReadOnly( true );
|
||||
Container c = ( Container ) s.get( Container.class, cOrig.getId() );
|
||||
|
@ -230,7 +236,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
checkContainer( c, expectedInitializedObjects, expectedReadOnlyObjects, s );
|
||||
t.commit();
|
||||
s.close();
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from DataPoint").executeUpdate();
|
||||
s.createQuery("delete from Container").executeUpdate();
|
||||
|
@ -243,7 +249,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
|
||||
@Test
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public void testExistingReadOnlyAfterSetSessionModifiableExisting() {
|
||||
public void testExistingReadOnlyAfterSetSessionModifiableExisting(SessionFactoryScope scope) {
|
||||
Container cOrig = createContainer();
|
||||
Set expectedInitializedObjects = new HashSet(
|
||||
Arrays.asList(
|
||||
|
@ -261,7 +267,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
);
|
||||
Set expectedReadOnlyObjects = new HashSet();
|
||||
DataPoint lazyDataPointOrig = ( DataPoint ) cOrig.getLazyDataPoints().iterator().next();
|
||||
Session s = openSession();
|
||||
Session s = openSession(scope);
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
Transaction t = s.beginTransaction();
|
||||
s.save( cOrig );
|
||||
|
@ -272,7 +278,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.setDefaultReadOnly( true );
|
||||
Container c = ( Container ) s.get( Container.class, cOrig.getId() );
|
||||
|
@ -321,7 +327,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
checkContainer( c, expectedInitializedObjects, expectedReadOnlyObjects, s );
|
||||
t.commit();
|
||||
s.close();
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from DataPoint").executeUpdate();
|
||||
s.createQuery("delete from Container").executeUpdate();
|
||||
|
@ -334,7 +340,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
@Test
|
||||
public void testExistingReadOnlyAfterSetSessionModifiableExistingEntityReadOnly() {
|
||||
public void testExistingReadOnlyAfterSetSessionModifiableExistingEntityReadOnly(SessionFactoryScope scope) {
|
||||
Container cOrig = createContainer();
|
||||
Set expectedInitializedObjects = new HashSet(
|
||||
Arrays.asList(
|
||||
|
@ -352,7 +358,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
);
|
||||
Set expectedReadOnlyObjects = new HashSet();
|
||||
DataPoint lazyDataPointOrig = ( DataPoint ) cOrig.getLazyDataPoints().iterator().next();
|
||||
Session s = openSession();
|
||||
Session s = openSession(scope);
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
Transaction t = s.beginTransaction();
|
||||
s.save( cOrig );
|
||||
|
@ -363,7 +369,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.setDefaultReadOnly( true );
|
||||
Container c = ( Container ) s.get( Container.class, cOrig.getId() );
|
||||
|
@ -415,7 +421,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
checkContainer( c, expectedInitializedObjects, expectedReadOnlyObjects, s );
|
||||
t.commit();
|
||||
s.close();
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from DataPoint").executeUpdate();
|
||||
s.createQuery("delete from Container").executeUpdate();
|
||||
|
@ -428,7 +434,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
@Test
|
||||
public void testExistingReadOnlyAfterSetSessionModifiableProxyExisting() {
|
||||
public void testExistingReadOnlyAfterSetSessionModifiableProxyExisting(SessionFactoryScope scope) {
|
||||
Container cOrig = createContainer();
|
||||
Set expectedInitializedObjects = new HashSet(
|
||||
Arrays.asList(
|
||||
|
@ -446,7 +452,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
);
|
||||
Set expectedReadOnlyObjects = new HashSet();
|
||||
DataPoint lazyDataPointOrig = ( DataPoint ) cOrig.getLazyDataPoints().iterator().next();
|
||||
Session s = openSession();
|
||||
Session s = openSession(scope);
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
Transaction t = s.beginTransaction();
|
||||
s.save( cOrig );
|
||||
|
@ -457,7 +463,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.setDefaultReadOnly( true );
|
||||
Container c = ( Container ) s.get( Container.class, cOrig.getId() );
|
||||
|
@ -506,7 +512,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
checkContainer( c, expectedInitializedObjects, expectedReadOnlyObjects, s );
|
||||
t.commit();
|
||||
s.close();
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from DataPoint").executeUpdate();
|
||||
s.createQuery("delete from Container").executeUpdate();
|
||||
|
@ -519,7 +525,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
@Test
|
||||
public void testExistingReadOnlyAfterSetSessionModifiableExistingProxyReadOnly() {
|
||||
public void testExistingReadOnlyAfterSetSessionModifiableExistingProxyReadOnly(SessionFactoryScope scope) {
|
||||
Container cOrig = createContainer();
|
||||
Set expectedInitializedObjects = new HashSet(
|
||||
Arrays.asList(
|
||||
|
@ -537,7 +543,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
);
|
||||
Set expectedReadOnlyObjects = new HashSet();
|
||||
DataPoint lazyDataPointOrig = ( DataPoint ) cOrig.getLazyDataPoints().iterator().next();
|
||||
Session s = openSession();
|
||||
Session s = openSession(scope);
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
Transaction t = s.beginTransaction();
|
||||
s.save( cOrig );
|
||||
|
@ -548,7 +554,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.setDefaultReadOnly( true );
|
||||
Container c = ( Container ) s.get( Container.class, cOrig.getId() );
|
||||
|
@ -600,7 +606,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
checkContainer( c, expectedInitializedObjects, expectedReadOnlyObjects, s );
|
||||
t.commit();
|
||||
s.close();
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from DataPoint").executeUpdate();
|
||||
s.createQuery("delete from Container").executeUpdate();
|
||||
|
@ -612,7 +618,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
@Test
|
||||
public void testDefaultModifiableWithReadOnlyQueryForEntity() {
|
||||
public void testDefaultModifiableWithReadOnlyQueryForEntity(SessionFactoryScope scope) {
|
||||
Container cOrig = createContainer();
|
||||
Set expectedInitializedObjects = new HashSet(
|
||||
Arrays.asList(
|
||||
|
@ -630,7 +636,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
);
|
||||
Set expectedReadOnlyObjects = new HashSet();
|
||||
|
||||
Session s = openSession();
|
||||
Session s = openSession(scope);
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
Transaction t = s.beginTransaction();
|
||||
s.save( cOrig );
|
||||
|
@ -641,7 +647,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
Container c = ( Container ) s.createQuery( "from Container where id=" + cOrig.getId() )
|
||||
|
@ -687,7 +693,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
checkContainer( c, expectedInitializedObjects, expectedReadOnlyObjects, s );
|
||||
t.commit();
|
||||
s.close();
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from DataPoint").executeUpdate();
|
||||
s.createQuery("delete from Container").executeUpdate();
|
||||
|
@ -699,7 +705,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
@Test
|
||||
public void testDefaultReadOnlyWithModifiableQueryForEntity() {
|
||||
public void testDefaultReadOnlyWithModifiableQueryForEntity(SessionFactoryScope scope) {
|
||||
Container cOrig = createContainer();
|
||||
Set expectedInitializedObjects = new HashSet(
|
||||
Arrays.asList(
|
||||
|
@ -717,7 +723,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
);
|
||||
Set expectedReadOnlyObjects = new HashSet();
|
||||
|
||||
Session s = openSession();
|
||||
Session s = openSession(scope);
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
Transaction t = s.beginTransaction();
|
||||
s.save( cOrig );
|
||||
|
@ -728,7 +734,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.setDefaultReadOnly( true );
|
||||
assertTrue( s.isDefaultReadOnly() );
|
||||
|
@ -762,7 +768,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
checkContainer( c, expectedInitializedObjects, expectedReadOnlyObjects, s );
|
||||
t.commit();
|
||||
s.close();
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from DataPoint").executeUpdate();
|
||||
s.createQuery("delete from Container").executeUpdate();
|
||||
|
@ -774,7 +780,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
@Test
|
||||
public void testDefaultReadOnlyWithQueryForEntity() {
|
||||
public void testDefaultReadOnlyWithQueryForEntity(SessionFactoryScope scope) {
|
||||
Container cOrig = createContainer();
|
||||
Set expectedInitializedObjects = new HashSet(
|
||||
Arrays.asList(
|
||||
|
@ -792,7 +798,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
);
|
||||
Set expectedReadOnlyObjects = new HashSet();
|
||||
|
||||
Session s = openSession();
|
||||
Session s = openSession(scope);
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
Transaction t = s.beginTransaction();
|
||||
s.save( cOrig );
|
||||
|
@ -803,7 +809,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.setDefaultReadOnly( true );
|
||||
assertTrue( s.isDefaultReadOnly() );
|
||||
|
@ -850,7 +856,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
checkContainer( c, expectedInitializedObjects, expectedReadOnlyObjects, s );
|
||||
t.commit();
|
||||
s.close();
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from DataPoint").executeUpdate();
|
||||
s.createQuery("delete from Container").executeUpdate();
|
||||
|
@ -862,7 +868,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
@Test
|
||||
public void testDefaultModifiableWithQueryForEntity() {
|
||||
public void testDefaultModifiableWithQueryForEntity(SessionFactoryScope scope) {
|
||||
Container cOrig = createContainer();
|
||||
Set expectedInitializedObjects = new HashSet(
|
||||
Arrays.asList(
|
||||
|
@ -880,7 +886,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
);
|
||||
Set expectedReadOnlyObjects = new HashSet();
|
||||
|
||||
Session s = openSession();
|
||||
Session s = openSession(scope);
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
Transaction t = s.beginTransaction();
|
||||
s.save( cOrig );
|
||||
|
@ -891,7 +897,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
Container c = ( Container ) s.createQuery( "from Container where id=" + cOrig.getId() )
|
||||
|
@ -924,7 +930,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
checkContainer( c, expectedInitializedObjects, expectedReadOnlyObjects, s );
|
||||
t.commit();
|
||||
s.close();
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from DataPoint").executeUpdate();
|
||||
s.createQuery("delete from Container").executeUpdate();
|
||||
|
@ -936,7 +942,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
@Test
|
||||
public void testDefaultModifiableWithReadOnlyQueryForCollectionEntities() {
|
||||
public void testDefaultModifiableWithReadOnlyQueryForCollectionEntities(SessionFactoryScope scope) {
|
||||
Container cOrig = createContainer();
|
||||
Set expectedInitializedObjects = new HashSet(
|
||||
Arrays.asList(
|
||||
|
@ -954,7 +960,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
);
|
||||
Set expectedReadOnlyObjects = new HashSet();
|
||||
|
||||
Session s = openSession();
|
||||
Session s = openSession(scope);
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
Transaction t = s.beginTransaction();
|
||||
s.save( cOrig );
|
||||
|
@ -965,7 +971,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
assertFalse( s.isDefaultReadOnly() );
|
||||
DataPoint dp = ( DataPoint ) s.createQuery( "select c.lazyDataPoints from Container c join c.lazyDataPoints where c.id=" + cOrig.getId() )
|
||||
|
@ -973,7 +979,7 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
assertTrue( s.isReadOnly( dp ) );
|
||||
t.commit();
|
||||
s.close();
|
||||
s = openSession();
|
||||
s = openSession(scope);
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from DataPoint").executeUpdate();
|
||||
s.createQuery("delete from Container").executeUpdate();
|
||||
|
@ -1037,4 +1043,8 @@ public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {
|
|||
}
|
||||
}
|
||||
|
||||
private Session openSession(SessionFactoryScope scope) {
|
||||
return scope.getSessionFactory().openSession();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,658 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.orm.test.readonly;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.test.readonly.AbstractReadOnlyTest;
|
||||
import org.hibernate.test.readonly.DataPoint;
|
||||
import org.hibernate.test.readonly.TextHolder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
* @author Gail Badner
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = {
|
||||
"org/hibernate/test/readonly/DataPoint.hbm.xml",
|
||||
"org/hibernate/test/readonly/TextHolder.hbm.xml"
|
||||
}
|
||||
)
|
||||
public class ReadOnlyTest extends AbstractReadOnlyTest {
|
||||
|
||||
@Test
|
||||
public void testReadOnlyOnProxies(SessionFactoryScope scope) {
|
||||
clearCounts( scope );
|
||||
|
||||
long dpId = scope.fromTransaction(
|
||||
session -> {
|
||||
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" );
|
||||
session.save( dp );
|
||||
return dp.getId();
|
||||
}
|
||||
);
|
||||
|
||||
assertInsertCount( 1, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
DataPoint dp = session.load( DataPoint.class, new Long( dpId ) );
|
||||
assertFalse( Hibernate.isInitialized( dp ), "was initialized" );
|
||||
session.setReadOnly( dp, true );
|
||||
assertFalse( Hibernate.isInitialized( dp ), "was initialized during setReadOnly" );
|
||||
dp.setDescription( "changed" );
|
||||
assertTrue( Hibernate.isInitialized( dp ), "was not initialized during mod" );
|
||||
assertEquals( "changed", dp.getDescription(), "desc not changed in memory" );
|
||||
session.flush();
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
List list = session.createQuery( "from DataPoint where description = 'changed'" ).list();
|
||||
assertEquals( 0, list.size(), "change written to database" );
|
||||
assertEquals( 1, session.createQuery( "delete from DataPoint" ).executeUpdate() );
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
//deletes from Query.executeUpdate() are not tracked
|
||||
//assertDeleteCount( 1 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyMode(SessionFactoryScope scope) {
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
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
|
||||
) );
|
||||
session.save( dp );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
assertInsertCount( 100, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inSession(
|
||||
session -> {
|
||||
try {
|
||||
session.getTransaction().begin();
|
||||
int i = 0;
|
||||
ScrollableResults sr = session.createQuery( "from DataPoint dp order by dp.x asc" )
|
||||
.setReadOnly( true )
|
||||
.scroll( ScrollMode.FORWARD_ONLY );
|
||||
while ( sr.next() ) {
|
||||
DataPoint dp = (DataPoint) sr.get();
|
||||
if ( ++i == 50 ) {
|
||||
session.setReadOnly( dp, false );
|
||||
}
|
||||
dp.setDescription( "done!" );
|
||||
}
|
||||
session.getTransaction().commit();
|
||||
|
||||
assertUpdateCount( 1, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
session.clear();
|
||||
session.getTransaction().begin();
|
||||
|
||||
List single = session.createQuery( "from DataPoint where description='done!'" ).list();
|
||||
assertEquals( single.size(), 1 );
|
||||
assertEquals( 100, session.createQuery( "delete from DataPoint" ).executeUpdate() );
|
||||
session.getTransaction().commit();
|
||||
}
|
||||
finally {
|
||||
if ( session.getTransaction().isActive() ) {
|
||||
session.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
//deletes from Query.executeUpdate() are not tracked
|
||||
//assertDeleteCount( 100 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyModeAutoFlushOnQuery(SessionFactoryScope scope) {
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
DataPoint dpFirst = null;
|
||||
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
|
||||
) );
|
||||
session.save( dp );
|
||||
}
|
||||
|
||||
assertInsertCount( 0, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
|
||||
ScrollableResults sr = session.createQuery( "from DataPoint dp order by dp.x asc" )
|
||||
.setReadOnly( true )
|
||||
.scroll( ScrollMode.FORWARD_ONLY );
|
||||
|
||||
assertInsertCount( 100, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
while ( sr.next() ) {
|
||||
DataPoint dp = (DataPoint) sr.get();
|
||||
assertFalse( session.isReadOnly( dp ) );
|
||||
session.delete( dp );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 100, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveReadOnlyModifyInSaveTransaction(SessionFactoryScope scope) {
|
||||
clearCounts( scope );
|
||||
|
||||
DataPoint d = new DataPoint();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
d.setDescription( "original" );
|
||||
d.setX( new BigDecimal( 0.1d ).setScale( 19, BigDecimal.ROUND_DOWN ) );
|
||||
d.setY( new BigDecimal( Math.cos( d.getX().doubleValue() ) ).setScale(
|
||||
19,
|
||||
BigDecimal.ROUND_DOWN
|
||||
) );
|
||||
session.save( d );
|
||||
session.setReadOnly( d, true );
|
||||
d.setDescription( "different" );
|
||||
}
|
||||
);
|
||||
|
||||
assertInsertCount( 1, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inSession(
|
||||
session -> {
|
||||
try {
|
||||
session.beginTransaction();
|
||||
DataPoint dp = session.get( DataPoint.class, d.getId() );
|
||||
session.setReadOnly( dp, true );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
session.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
session.getTransaction().commit();
|
||||
|
||||
assertInsertCount( 0, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
|
||||
session.clear();
|
||||
session.beginTransaction();
|
||||
dp = session.get( DataPoint.class, dp.getId() );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
session.delete( dp );
|
||||
session.getTransaction().commit();
|
||||
}
|
||||
finally {
|
||||
if ( session.getTransaction().isActive() ) {
|
||||
session.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 1, scope );
|
||||
clearCounts( scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyRefresh(SessionFactoryScope scope) {
|
||||
clearCounts( scope );
|
||||
|
||||
DataPoint d = new DataPoint();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
d.setDescription( "original" );
|
||||
d.setX( new BigDecimal( 0.1d ).setScale( 19, BigDecimal.ROUND_DOWN ) );
|
||||
d.setY( new BigDecimal( Math.cos( d.getX().doubleValue() ) ).setScale(
|
||||
19,
|
||||
BigDecimal.ROUND_DOWN
|
||||
) );
|
||||
session.save( d );
|
||||
}
|
||||
);
|
||||
|
||||
assertInsertCount( 1, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inSession(
|
||||
session -> {
|
||||
try {
|
||||
session.beginTransaction();
|
||||
|
||||
DataPoint dp = session.get( DataPoint.class, d.getId() );
|
||||
session.setReadOnly( dp, true );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
session.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
session.getTransaction().commit();
|
||||
|
||||
assertInsertCount( 0, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
|
||||
session.clear();
|
||||
session.beginTransaction();
|
||||
dp = session.get( DataPoint.class, dp.getId() );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
session.delete( dp );
|
||||
session.getTransaction().commit();
|
||||
}
|
||||
finally {
|
||||
if ( session.getTransaction().isActive() ) {
|
||||
session.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 1, scope );
|
||||
clearCounts( scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyRefreshDetached(SessionFactoryScope scope) {
|
||||
clearCounts( scope );
|
||||
|
||||
Session s = openSession( scope );
|
||||
Transaction t = s.beginTransaction();
|
||||
DataPoint dp = new DataPoint();
|
||||
dp.setDescription( "original" );
|
||||
dp.setX( new BigDecimal( 0.1d ).setScale( 19, BigDecimal.ROUND_DOWN ) );
|
||||
dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale( 19, BigDecimal.ROUND_DOWN ) );
|
||||
s.save( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertInsertCount( 1, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
s = openSession( scope );
|
||||
t = s.beginTransaction();
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
s.setReadOnly( dp, true );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.evict( dp );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
t.commit();
|
||||
|
||||
assertInsertCount( 0, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
|
||||
s.clear();
|
||||
t = s.beginTransaction();
|
||||
dp = (DataPoint) s.get( DataPoint.class, dp.getId() );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 1, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyDelete(SessionFactoryScope scope) {
|
||||
clearCounts( scope );
|
||||
|
||||
Session s = openSession( scope );
|
||||
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();
|
||||
|
||||
assertInsertCount( 1, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
s = openSession( scope );
|
||||
t = s.beginTransaction();
|
||||
dp = (DataPoint) s.get( DataPoint.class, dp.getId() );
|
||||
s.setReadOnly( dp, true );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 1, scope );
|
||||
|
||||
s = openSession( scope );
|
||||
t = s.beginTransaction();
|
||||
List list = s.createQuery( "from DataPoint where description='done!'" ).list();
|
||||
assertTrue( list.isEmpty() );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyGetModifyAndDelete(SessionFactoryScope scope) {
|
||||
clearCounts( scope );
|
||||
|
||||
Session s = openSession( scope );
|
||||
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();
|
||||
|
||||
assertInsertCount( 1, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
s = openSession( scope );
|
||||
t = s.beginTransaction();
|
||||
dp = (DataPoint) s.get( DataPoint.class, dp.getId() );
|
||||
s.setReadOnly( dp, true );
|
||||
dp.setDescription( "a DataPoint" );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 1, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
s = openSession( scope );
|
||||
t = s.beginTransaction();
|
||||
List list = s.createQuery( "from DataPoint where description='done!'" ).list();
|
||||
assertTrue( list.isEmpty() );
|
||||
t.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyModeWithExistingModifiableEntity(SessionFactoryScope scope) {
|
||||
clearCounts( scope );
|
||||
|
||||
Session s = openSession( scope );
|
||||
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();
|
||||
|
||||
assertInsertCount( 100, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
s = openSession( scope );
|
||||
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();
|
||||
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();
|
||||
|
||||
assertInsertCount( 0, scope );
|
||||
assertUpdateCount( nExpectedChanges, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
t = s.beginTransaction();
|
||||
List list = s.createQuery( "from DataPoint where description='done!'" ).list();
|
||||
assertEquals( list.size(), nExpectedChanges );
|
||||
assertEquals( 100, s.createQuery( "delete from DataPoint" ).executeUpdate() );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModifiableModeWithExistingReadOnlyEntity(SessionFactoryScope scope) {
|
||||
clearCounts( scope );
|
||||
|
||||
Session s = openSession( scope );
|
||||
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();
|
||||
|
||||
assertInsertCount( 100, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
s = openSession( scope );
|
||||
t = s.beginTransaction();
|
||||
DataPoint dpLast = (DataPoint) s.get( DataPoint.class, dp.getId() );
|
||||
assertFalse( s.isReadOnly( dpLast ) );
|
||||
s.setReadOnly( dpLast, true );
|
||||
assertTrue( s.isReadOnly( dpLast ) );
|
||||
dpLast.setDescription( "oy" );
|
||||
int i = 0;
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
|
||||
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();
|
||||
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();
|
||||
|
||||
assertUpdateCount( nExpectedChanges, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
t = s.beginTransaction();
|
||||
List list = s.createQuery( "from DataPoint where description='done!'" ).list();
|
||||
assertEquals( list.size(), nExpectedChanges );
|
||||
assertEquals( 100, s.createQuery( "delete from DataPoint" ).executeUpdate() );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyOnTextType(SessionFactoryScope scope) {
|
||||
final String origText = "some huge text string";
|
||||
final String newText = "some even bigger text string";
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
Session s = openSession( scope );
|
||||
s.beginTransaction();
|
||||
TextHolder holder = new TextHolder( origText );
|
||||
s.save( holder );
|
||||
Long id = holder.getId();
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertInsertCount( 1, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
s = openSession( scope );
|
||||
s.beginTransaction();
|
||||
holder = (TextHolder) s.get( TextHolder.class, id );
|
||||
s.setReadOnly( holder, true );
|
||||
holder.setTheText( newText );
|
||||
s.flush();
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
|
||||
s = openSession( scope );
|
||||
s.beginTransaction();
|
||||
holder = (TextHolder) s.get( TextHolder.class, id );
|
||||
assertEquals( origText, holder.getTheText(), "change written to database" );
|
||||
s.delete( holder );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 1, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeWithReadOnlyEntity(SessionFactoryScope scope) {
|
||||
clearCounts( scope );
|
||||
|
||||
Session s = openSession( scope );
|
||||
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();
|
||||
|
||||
assertInsertCount( 1, scope );
|
||||
assertUpdateCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
dp.setDescription( "description" );
|
||||
|
||||
s = openSession( scope );
|
||||
t = s.beginTransaction();
|
||||
DataPoint dpManaged = (DataPoint) s.get( DataPoint.class, new Long( dp.getId() ) );
|
||||
s.setReadOnly( dpManaged, true );
|
||||
DataPoint dpMerged = (DataPoint) s.merge( dp );
|
||||
assertSame( dpManaged, dpMerged );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
|
||||
s = openSession( scope );
|
||||
t = s.beginTransaction();
|
||||
dpManaged = (DataPoint) s.get( DataPoint.class, new Long( dp.getId() ) );
|
||||
assertNull( dpManaged.getDescription() );
|
||||
s.delete( dpManaged );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 1, scope );
|
||||
}
|
||||
|
||||
private Session openSession(SessionFactoryScope scope) {
|
||||
return scope.getSessionFactory().openSession();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,658 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.orm.test.readonly;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.FailureExpected;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.test.readonly.AbstractReadOnlyTest;
|
||||
import org.hibernate.test.readonly.VersionedNode;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/test/readonly/VersionedNode.hbm.xml"
|
||||
)
|
||||
public class ReadOnlyVersionedNodesTest extends AbstractReadOnlyTest {
|
||||
|
||||
@AfterEach
|
||||
public void tearDown(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createQuery( "select v from VersionedNode v" ).list()
|
||||
.forEach( node -> session.delete( node ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetReadOnlyTrueAndFalse(SessionFactoryScope scope) {
|
||||
VersionedNode n = createVersionNode( scope );
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inSession(
|
||||
session -> {
|
||||
try {
|
||||
session.beginTransaction();
|
||||
|
||||
VersionedNode node = session.get( VersionedNode.class, n.getId() );
|
||||
session.setReadOnly( node, true );
|
||||
node.setName( "node-name" );
|
||||
session.getTransaction().commit();
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertInsertCount( 0, scope );
|
||||
|
||||
// the changed name is still in node
|
||||
assertEquals( "node-name", node.getName() );
|
||||
|
||||
session.beginTransaction();
|
||||
node = session.get( VersionedNode.class, node.getId() );
|
||||
// the changed name is still in the session
|
||||
assertEquals( "node-name", node.getName() );
|
||||
session.refresh( node );
|
||||
// after refresh, the name reverts to the original value
|
||||
assertEquals( "node", node.getName() );
|
||||
node = session.get( VersionedNode.class, node.getId() );
|
||||
assertEquals( "node", node.getName() );
|
||||
session.getTransaction().commit();
|
||||
}
|
||||
finally {
|
||||
if ( session.getTransaction().isActive() ) {
|
||||
session.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertInsertCount( 0, scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode node = session.get( VersionedNode.class, n.getId() );
|
||||
assertEquals( "node", node.getName() );
|
||||
session.setReadOnly( node, true );
|
||||
node.setName( "diff-node-name" );
|
||||
session.flush();
|
||||
assertEquals( "diff-node-name", node.getName() );
|
||||
session.refresh( node );
|
||||
assertEquals( "node", node.getName() );
|
||||
session.setReadOnly( node, false );
|
||||
node.setName( "diff-node-name" );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 1, scope );
|
||||
assertInsertCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode node = session.get( VersionedNode.class, n.getId() );
|
||||
assertEquals( "diff-node-name", node.getName() );
|
||||
assertEquals( 1, node.getVersion() );
|
||||
session.setReadOnly( node, true );
|
||||
session.delete( node );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 1, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSetReadOnlyTwice(SessionFactoryScope scope) {
|
||||
VersionedNode n = createVersionNode( scope );
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode node = session.get( VersionedNode.class, n.getId() );
|
||||
node.setName( "node-name" );
|
||||
session.setReadOnly( node, true );
|
||||
session.setReadOnly( node, true );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertInsertCount( 0, scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode node = session.get( VersionedNode.class, n.getId() );
|
||||
assertEquals( "node", node.getName() );
|
||||
assertEquals( 0, node.getVersion() );
|
||||
session.setReadOnly( node, true );
|
||||
session.delete( node );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 1, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSetModifiable(SessionFactoryScope scope) {
|
||||
VersionedNode n = createVersionNode( scope );
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode node = session.get( VersionedNode.class, n.getId() );
|
||||
node.setName( "node-name" );
|
||||
session.setReadOnly( node, false );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 1, scope );
|
||||
assertInsertCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode node = session.get( VersionedNode.class, n.getId() );
|
||||
assertEquals( "node-name", node.getName() );
|
||||
assertEquals( 1, node.getVersion() );
|
||||
session.setReadOnly( node, true );
|
||||
session.delete( node );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 1, scope );
|
||||
}
|
||||
|
||||
private VersionedNode createVersionNode(SessionFactoryScope scope) {
|
||||
return scope.fromTransaction(
|
||||
session -> {
|
||||
VersionedNode nd = new VersionedNode( "node", "node" );
|
||||
session.persist( nd );
|
||||
return nd;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private VersionedNode createVersionNode(String id, String name, SessionFactoryScope scope) {
|
||||
return scope.fromTransaction(
|
||||
session -> {
|
||||
VersionedNode nd = new VersionedNode( id, name );
|
||||
session.persist( nd );
|
||||
return nd;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected(jiraKey = "unknown")
|
||||
public void testUpdateSetReadOnlySetModifiable(SessionFactoryScope scope) {
|
||||
VersionedNode n = createVersionNode( scope );
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode node = session.get( VersionedNode.class, n.getId() );
|
||||
node.setName( "node-name" );
|
||||
session.setReadOnly( node, true );
|
||||
session.setReadOnly( node, false );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 1, scope );
|
||||
assertInsertCount( 0, scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode node = session.get( VersionedNode.class, n.getId() );
|
||||
assertEquals( "node-name", node.getName() );
|
||||
assertEquals( 1, node.getVersion() );
|
||||
session.delete( node );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected(jiraKey = "unknown")
|
||||
public void testSetReadOnlyUpdateSetModifiable(SessionFactoryScope scope) {
|
||||
VersionedNode n = createVersionNode( scope );
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode node = session.get( VersionedNode.class, n.getId() );
|
||||
session.setReadOnly( node, true );
|
||||
node.setName( "node-name" );
|
||||
session.setReadOnly( node, false );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 1, scope );
|
||||
assertInsertCount( 0, scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode node = session.get( VersionedNode.class, n.getId() );
|
||||
assertEquals( "node-name", node.getName() );
|
||||
assertEquals( 1, node.getVersion() );
|
||||
session.delete( node );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddNewChildToReadOnlyParent(SessionFactoryScope scope) {
|
||||
VersionedNode p = createVersionNode( "parent", "parent", scope );
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
VersionedNode c = scope.fromTransaction(
|
||||
session -> {
|
||||
VersionedNode parentManaged = session.get( VersionedNode.class, p.getId() );
|
||||
session.setReadOnly( parentManaged, true );
|
||||
parentManaged.setName( "new parent name" );
|
||||
VersionedNode child = new VersionedNode( "child", "child" );
|
||||
parentManaged.addChild( child );
|
||||
return child;
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 1, scope );
|
||||
assertInsertCount( 1, scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode parent = session.get( VersionedNode.class, p.getId() );
|
||||
assertEquals( "parent", parent.getName() );
|
||||
assertEquals( 1, parent.getChildren().size() );
|
||||
assertEquals( 1, parent.getVersion() );
|
||||
VersionedNode child = session.get( VersionedNode.class, c.getId() );
|
||||
assertNotNull( child );
|
||||
session.delete( parent );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateParentWithNewChildCommitWithReadOnlyParent(SessionFactoryScope scope) {
|
||||
VersionedNode p = createVersionNode( "parent", "parent", scope );
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
p.setName( "new parent name" );
|
||||
VersionedNode c = new VersionedNode( "child", "child" );
|
||||
p.addChild( c );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.update( p );
|
||||
session.setReadOnly( p, true );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 1, scope );
|
||||
assertInsertCount( 1, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode parent = session.get( VersionedNode.class, p.getId() );
|
||||
VersionedNode child = session.get( VersionedNode.class, c.getId() );
|
||||
assertEquals( parent.getName(), "parent" );
|
||||
assertEquals( 1, parent.getChildren().size() );
|
||||
assertEquals( 1, parent.getVersion() );
|
||||
assertSame( parent, child.getParent() );
|
||||
assertSame( child, parent.getChildren().iterator().next() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
session.setReadOnly( parent, true );
|
||||
session.setReadOnly( child, true );
|
||||
session.delete( parent );
|
||||
session.delete( child );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 2, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeDetachedParentWithNewChildCommitWithReadOnlyParent(SessionFactoryScope scope) {
|
||||
VersionedNode p = createVersionNode( "parent", "parent", scope );
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
p.setName( "new parent name" );
|
||||
VersionedNode c = new VersionedNode( "child", "child" );
|
||||
p.addChild( c );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode parent = (VersionedNode) session.merge( p );
|
||||
session.setReadOnly( parent, true );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 1, scope );
|
||||
assertInsertCount( 1, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode parent = session.get( VersionedNode.class, p.getId() );
|
||||
VersionedNode child = session.get( VersionedNode.class, c.getId() );
|
||||
assertEquals( parent.getName(), "parent" );
|
||||
assertEquals( 1, parent.getChildren().size() );
|
||||
assertEquals( 1, parent.getVersion() );
|
||||
assertSame( parent, child.getParent() );
|
||||
assertSame( child, parent.getChildren().iterator().next() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
session.setReadOnly( parent, true );
|
||||
session.setReadOnly( child, true );
|
||||
session.delete( parent );
|
||||
session.delete( child );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 2, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetParentMakeReadOnlyThenMergeDetachedParentWithNewChildC(SessionFactoryScope scope) {
|
||||
VersionedNode p = createVersionNode( "parent", "parent", scope );
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
p.setName( "new parent name" );
|
||||
VersionedNode c = new VersionedNode( "child", "child" );
|
||||
p.addChild( c );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode parentManaged = session.get( VersionedNode.class, p.getId() );
|
||||
session.setReadOnly( parentManaged, true );
|
||||
VersionedNode parentMerged = (VersionedNode) session.merge( p );
|
||||
assertSame( parentManaged, parentMerged );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 1, scope );
|
||||
assertInsertCount( 1, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode parent = session.get( VersionedNode.class, p.getId() );
|
||||
VersionedNode child = session.get( VersionedNode.class, c.getId() );
|
||||
assertEquals( parent.getName(), "parent" );
|
||||
assertEquals( 1, parent.getChildren().size() );
|
||||
assertEquals( 1, parent.getVersion() );
|
||||
assertSame( parent, child.getParent() );
|
||||
assertSame( child, parent.getChildren().iterator().next() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
session.delete( parent );
|
||||
session.delete( child );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 2, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeUnchangedDetachedParentChildren(SessionFactoryScope scope) {
|
||||
VersionedNode p = new VersionedNode( "parent", "parent" );
|
||||
VersionedNode c = new VersionedNode( "child", "child" );
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
p.addChild( c );
|
||||
session.persist( p );
|
||||
}
|
||||
);
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
VersionedNode parent = scope.fromTransaction(
|
||||
session ->
|
||||
(VersionedNode) session.merge( p )
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertInsertCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode parentGet = session.get( p.getClass(), p.getId() );
|
||||
session.merge( parent );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertInsertCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode parentLoad = (VersionedNode) session.load( parent.getClass(), parent.getId() );
|
||||
session.merge( parent );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertInsertCount( 0, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode parent_ = session.get( VersionedNode.class, parent.getId() );
|
||||
VersionedNode child = session.get( VersionedNode.class, c.getId() );
|
||||
assertEquals( parent_.getName(), "parent" );
|
||||
assertEquals( 1, parent_.getChildren().size() );
|
||||
assertEquals( 0, parent_.getVersion() );
|
||||
assertSame( parent_, child.getParent() );
|
||||
assertSame( child, parent_.getChildren().iterator().next() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
session.delete( parent_ );
|
||||
session.delete( child );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 2, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddNewParentToReadOnlyChild(SessionFactoryScope scope) {
|
||||
VersionedNode c = createVersionNode( "child", "child", scope );
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
VersionedNode p = new VersionedNode( "parent", "parent" );
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode childManaged = session.get( VersionedNode.class, c.getId() );
|
||||
session.setReadOnly( childManaged, true );
|
||||
childManaged.setName( "new child name" );
|
||||
p.addChild( childManaged );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertInsertCount( 1, scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode child = session.get( VersionedNode.class, c.getId() );
|
||||
assertEquals( "child", child.getName() );
|
||||
assertNull( child.getParent() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
VersionedNode parent = session.get( VersionedNode.class, p.getId() );
|
||||
assertNotNull( parent );
|
||||
session.setReadOnly( child, true );
|
||||
session.delete( child );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 1, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateChildWithNewParentCommitWithReadOnlyChild(SessionFactoryScope scope) {
|
||||
VersionedNode c = createVersionNode( "child", "child", scope );
|
||||
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
c.setName( "new child name" );
|
||||
VersionedNode p = new VersionedNode( "parent", "parent" );
|
||||
p.addChild( c );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.update( c );
|
||||
session.setReadOnly( c, true );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertInsertCount( 1, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode parent = session.get( VersionedNode.class, p.getId() );
|
||||
VersionedNode child = session.get( VersionedNode.class, c.getId() );
|
||||
assertEquals( child.getName(), "child" );
|
||||
assertNull( child.getParent() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
assertNotNull( parent );
|
||||
assertEquals( 0, parent.getChildren().size() );
|
||||
assertEquals( 0, parent.getVersion() );
|
||||
session.setReadOnly( parent, true );
|
||||
session.setReadOnly( child, true );
|
||||
session.delete( parent );
|
||||
session.delete( child );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 2, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeDetachedChildWithNewParentCommitWithReadOnlyChild(SessionFactoryScope scope) {
|
||||
VersionedNode c = createVersionNode( "child", "child", scope );
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
c.setName( "new child name" );
|
||||
VersionedNode p = new VersionedNode( "parent", "parent" );
|
||||
p.addChild( c );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode child = (VersionedNode) session.merge( c );
|
||||
session.setReadOnly( child, true );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 1, scope );
|
||||
assertInsertCount( 1, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode parent = session.get( VersionedNode.class, p.getId() );
|
||||
VersionedNode child = session.get( VersionedNode.class, c.getId() );
|
||||
assertEquals( child.getName(), "child" );
|
||||
assertNull( child.getParent() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
assertNotNull( parent );
|
||||
assertEquals( 0, parent.getChildren().size() );
|
||||
assertEquals( 1, parent.getVersion() ); // hmmm, why is was version updated?
|
||||
session.setReadOnly( parent, true );
|
||||
session.setReadOnly( child, true );
|
||||
session.delete( parent );
|
||||
session.delete( child );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 2, scope );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetChildMakeReadOnlyThenMergeDetachedChildWithNewParent(SessionFactoryScope scope) {
|
||||
VersionedNode c = createVersionNode( "child", "child", scope );
|
||||
|
||||
clearCounts( scope );
|
||||
|
||||
c.setName( "new child name" );
|
||||
VersionedNode p = new VersionedNode( "parent", "parent" );
|
||||
p.addChild( c );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode childManaged = session.get( VersionedNode.class, c.getId() );
|
||||
session.setReadOnly( childManaged, true );
|
||||
VersionedNode childMerged = (VersionedNode) session.merge( c );
|
||||
assertSame( childManaged, childMerged );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 1, scope );
|
||||
assertInsertCount( 1, scope );
|
||||
clearCounts( scope );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
VersionedNode parent = session.get( VersionedNode.class, p.getId() );
|
||||
VersionedNode child = session.get( VersionedNode.class, c.getId() );
|
||||
assertEquals( child.getName(), "child" );
|
||||
assertNull( child.getParent() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
assertNotNull( parent );
|
||||
assertEquals( 0, parent.getChildren().size() );
|
||||
assertEquals( 1, parent.getVersion() ); // / hmmm, why is was version updated?
|
||||
session.setReadOnly( parent, true );
|
||||
session.setReadOnly( child, true );
|
||||
session.delete( parent );
|
||||
session.delete( child );
|
||||
}
|
||||
);
|
||||
|
||||
assertUpdateCount( 0, scope );
|
||||
assertDeleteCount( 2, scope );
|
||||
}
|
||||
|
||||
protected void cleanupTest(SessionFactoryScope scope) throws Exception {
|
||||
cleanup( scope );
|
||||
}
|
||||
|
||||
private void cleanup(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createQuery( "delete from VersionedNode where parent is not null" ).executeUpdate();
|
||||
session.createQuery( "delete from VersionedNode" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -7,50 +7,54 @@
|
|||
package org.hibernate.test.readonly;
|
||||
|
||||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.cfg.Environment;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.hibernate.testing.orm.junit.SettingProvider;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public abstract class AbstractReadOnlyTest extends BaseCoreFunctionalTestCase {
|
||||
@Override
|
||||
public void configure(Configuration cfg) {
|
||||
cfg.setProperty( Environment.GENERATE_STATISTICS, "true");
|
||||
cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
|
||||
@SessionFactory(
|
||||
generateStatistics = true
|
||||
)
|
||||
@ServiceRegistry(
|
||||
settings = @Setting(name = Environment.STATEMENT_BATCH_SIZE, value = "0"),
|
||||
settingProviders = @SettingProvider(settingName = AvailableSettings.JAKARTA_SHARED_CACHE_RETRIEVE_MODE, provider = AbstractReadOnlyTest.CacheModeProvider.class)
|
||||
)
|
||||
public abstract class AbstractReadOnlyTest {
|
||||
|
||||
public static class CacheModeProvider implements SettingProvider.Provider<CacheMode> {
|
||||
|
||||
@Override
|
||||
public CacheMode getSetting() {
|
||||
return CacheMode.IGNORE;
|
||||
}
|
||||
}
|
||||
|
||||
public Session openSession() {
|
||||
Session s = super.openSession();
|
||||
s.setCacheMode( getSessionCacheMode() );
|
||||
return s;
|
||||
protected void clearCounts(SessionFactoryScope scope) {
|
||||
scope.getSessionFactory().getStatistics().clear();
|
||||
}
|
||||
|
||||
protected CacheMode getSessionCacheMode() {
|
||||
return CacheMode.IGNORE;
|
||||
protected void assertInsertCount(int expected, SessionFactoryScope scope) {
|
||||
int inserts = (int) scope.getSessionFactory().getStatistics().getEntityInsertCount();
|
||||
assertEquals( expected, inserts, "unexpected insert count" );
|
||||
}
|
||||
|
||||
protected void clearCounts() {
|
||||
sessionFactory().getStatistics().clear();
|
||||
protected void assertUpdateCount(int expected, SessionFactoryScope scope) {
|
||||
int updates = (int) scope.getSessionFactory().getStatistics().getEntityUpdateCount();
|
||||
assertEquals( expected, updates, "unexpected update counts" );
|
||||
}
|
||||
|
||||
protected void assertInsertCount(int expected) {
|
||||
int inserts = ( int ) sessionFactory().getStatistics().getEntityInsertCount();
|
||||
assertEquals( "unexpected insert count", expected, inserts );
|
||||
}
|
||||
|
||||
protected void assertUpdateCount(int expected) {
|
||||
int updates = ( int ) sessionFactory().getStatistics().getEntityUpdateCount();
|
||||
assertEquals( "unexpected update counts", expected, updates );
|
||||
}
|
||||
|
||||
protected void assertDeleteCount(int expected) {
|
||||
int deletes = ( int ) sessionFactory().getStatistics().getEntityDeleteCount();
|
||||
assertEquals( "unexpected delete counts", expected, deletes );
|
||||
protected void assertDeleteCount(int expected, SessionFactoryScope scope) {
|
||||
int deletes = (int) scope.getSessionFactory().getStatistics().getEntityDeleteCount();
|
||||
assertEquals( expected, deletes, "unexpected delete counts" );
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,603 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.readonly;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class ReadOnlyTest extends AbstractReadOnlyTest {
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
return new String[] { "readonly/DataPoint.hbm.xml", "readonly/TextHolder.hbm.xml" };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyOnProxies() {
|
||||
clearCounts();
|
||||
|
||||
Session s = openSession();
|
||||
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 );
|
||||
long dpId = dp.getId();
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertInsertCount( 1 );
|
||||
assertUpdateCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
dp = ( DataPoint ) s.load( DataPoint.class, new Long( dpId ) );
|
||||
assertFalse( "was initialized", Hibernate.isInitialized( dp ) );
|
||||
s.setReadOnly( dp, true );
|
||||
assertFalse( "was initialized during setReadOnly", Hibernate.isInitialized( dp ) );
|
||||
dp.setDescription( "changed" );
|
||||
assertTrue( "was not initialized during mod", Hibernate.isInitialized( dp ) );
|
||||
assertEquals( "desc not changed in memory", "changed", dp.getDescription() );
|
||||
s.flush();
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
List list = s.createQuery( "from DataPoint where description = 'changed'" ).list();
|
||||
assertEquals( "change written to database", 0, list.size() );
|
||||
assertEquals( 1, s.createQuery("delete from DataPoint").executeUpdate() );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
//deletes from Query.executeUpdate() are not tracked
|
||||
//assertDeleteCount( 1 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyMode() {
|
||||
clearCounts();
|
||||
|
||||
Session s = openSession();
|
||||
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();
|
||||
|
||||
assertInsertCount( 100 );
|
||||
assertUpdateCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
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();
|
||||
if (++i==50) {
|
||||
s.setReadOnly(dp, false);
|
||||
}
|
||||
dp.setDescription("done!");
|
||||
}
|
||||
t.commit();
|
||||
|
||||
assertUpdateCount( 1 );
|
||||
clearCounts();
|
||||
|
||||
s.clear();
|
||||
t = s.beginTransaction();
|
||||
List single = s.createQuery("from DataPoint where description='done!'").list();
|
||||
assertEquals( single.size(), 1 );
|
||||
assertEquals( 100, s.createQuery("delete from DataPoint").executeUpdate() );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
//deletes from Query.executeUpdate() are not tracked
|
||||
//assertDeleteCount( 100 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyModeAutoFlushOnQuery() {
|
||||
clearCounts();
|
||||
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
DataPoint dpFirst = null;
|
||||
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);
|
||||
}
|
||||
|
||||
assertInsertCount( 0 );
|
||||
assertUpdateCount( 0 );
|
||||
|
||||
ScrollableResults sr = s.createQuery("from DataPoint dp order by dp.x asc")
|
||||
.setReadOnly(true)
|
||||
.scroll(ScrollMode.FORWARD_ONLY);
|
||||
|
||||
assertInsertCount( 100 );
|
||||
assertUpdateCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
while ( sr.next() ) {
|
||||
DataPoint dp = (DataPoint) sr.get();
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
s.delete( dp );
|
||||
}
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 100 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveReadOnlyModifyInSaveTransaction() {
|
||||
clearCounts();
|
||||
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
DataPoint dp = new DataPoint();
|
||||
dp.setDescription( "original" );
|
||||
dp.setX( new BigDecimal(0.1d).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
s.save(dp);
|
||||
s.setReadOnly( dp, true );
|
||||
dp.setDescription( "different" );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertInsertCount( 1 );
|
||||
assertUpdateCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
s.setReadOnly( dp, true );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
t.commit();
|
||||
|
||||
assertInsertCount( 0 );
|
||||
assertUpdateCount( 0 );
|
||||
|
||||
s.clear();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 1 );
|
||||
clearCounts();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyRefresh() {
|
||||
clearCounts();
|
||||
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
DataPoint dp = new DataPoint();
|
||||
dp.setDescription( "original" );
|
||||
dp.setX( new BigDecimal(0.1d).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
s.save(dp);
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertInsertCount( 1 );
|
||||
assertUpdateCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
s.setReadOnly( dp, true );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
t.commit();
|
||||
|
||||
assertInsertCount( 0 );
|
||||
assertUpdateCount( 0 );
|
||||
|
||||
s.clear();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 1 );
|
||||
clearCounts();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyRefreshDetached() {
|
||||
clearCounts();
|
||||
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
DataPoint dp = new DataPoint();
|
||||
dp.setDescription( "original" );
|
||||
dp.setX( new BigDecimal(0.1d).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale(19, BigDecimal.ROUND_DOWN) );
|
||||
s.save(dp);
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertInsertCount( 1 );
|
||||
assertUpdateCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
s.setReadOnly( dp, true );
|
||||
dp.setDescription( "changed" );
|
||||
assertEquals( "changed", dp.getDescription() );
|
||||
s.evict( dp );
|
||||
s.refresh( dp );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
assertFalse( s.isReadOnly( dp ) );
|
||||
t.commit();
|
||||
|
||||
assertInsertCount( 0 );
|
||||
assertUpdateCount( 0 );
|
||||
|
||||
s.clear();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
assertEquals( "original", dp.getDescription() );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 1 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyDelete() {
|
||||
clearCounts();
|
||||
|
||||
Session s = openSession();
|
||||
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();
|
||||
|
||||
assertInsertCount( 1 );
|
||||
assertUpdateCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
s.setReadOnly( dp, true );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 1 );
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
List list = s.createQuery("from DataPoint where description='done!'").list();
|
||||
assertTrue( list.isEmpty() );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyGetModifyAndDelete() {
|
||||
clearCounts();
|
||||
|
||||
Session s = openSession();
|
||||
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();
|
||||
|
||||
assertInsertCount( 1 );
|
||||
assertUpdateCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
dp = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
s.setReadOnly( dp, true );
|
||||
dp.setDescription( "a DataPoint" );
|
||||
s.delete( dp );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 1 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
List list = s.createQuery("from DataPoint where description='done!'").list();
|
||||
assertTrue( list.isEmpty() );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyModeWithExistingModifiableEntity() {
|
||||
clearCounts();
|
||||
|
||||
Session s = openSession();
|
||||
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();
|
||||
|
||||
assertInsertCount( 100 );
|
||||
assertUpdateCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
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();
|
||||
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();
|
||||
|
||||
assertInsertCount( 0 );
|
||||
assertUpdateCount( nExpectedChanges );
|
||||
clearCounts();
|
||||
|
||||
t = s.beginTransaction();
|
||||
List list = s.createQuery("from DataPoint where description='done!'").list();
|
||||
assertEquals( list.size(), nExpectedChanges );
|
||||
assertEquals( 100, s.createQuery("delete from DataPoint").executeUpdate() );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModifiableModeWithExistingReadOnlyEntity() {
|
||||
clearCounts();
|
||||
|
||||
Session s = openSession();
|
||||
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();
|
||||
|
||||
assertInsertCount( 100 );
|
||||
assertUpdateCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
DataPoint dpLast = ( DataPoint ) s.get( DataPoint.class, dp.getId() );
|
||||
assertFalse( s.isReadOnly( dpLast ) );
|
||||
s.setReadOnly( dpLast, true );
|
||||
assertTrue( s.isReadOnly( dpLast ) );
|
||||
dpLast.setDescription( "oy" );
|
||||
int i = 0;
|
||||
|
||||
assertUpdateCount( 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();
|
||||
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();
|
||||
|
||||
assertUpdateCount( nExpectedChanges );
|
||||
clearCounts();
|
||||
|
||||
t = s.beginTransaction();
|
||||
List list = s.createQuery("from DataPoint where description='done!'").list();
|
||||
assertEquals( list.size(), nExpectedChanges );
|
||||
assertEquals( 100, s.createQuery("delete from DataPoint").executeUpdate() );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnlyOnTextType() {
|
||||
final String origText = "some huge text string";
|
||||
final String newText = "some even bigger text string";
|
||||
|
||||
clearCounts();
|
||||
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
TextHolder holder = new TextHolder( origText );
|
||||
s.save( holder );
|
||||
Long id = holder.getId();
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertInsertCount( 1 );
|
||||
assertUpdateCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
holder = ( TextHolder ) s.get( TextHolder.class, id );
|
||||
s.setReadOnly( holder, true );
|
||||
holder.setTheText( newText );
|
||||
s.flush();
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
holder = ( TextHolder ) s.get( TextHolder.class, id );
|
||||
assertEquals( "change written to database", origText, holder.getTheText() );
|
||||
s.delete( holder );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 1 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeWithReadOnlyEntity() {
|
||||
clearCounts();
|
||||
|
||||
Session s = openSession();
|
||||
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();
|
||||
|
||||
assertInsertCount( 1 );
|
||||
assertUpdateCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
dp.setDescription( "description" );
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
DataPoint dpManaged = ( DataPoint ) s.get( DataPoint.class, new Long( dp.getId() ) );
|
||||
s.setReadOnly( dpManaged, true );
|
||||
DataPoint dpMerged = ( DataPoint ) s.merge( dp );
|
||||
assertSame( dpManaged, dpMerged );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
dpManaged = ( DataPoint ) s.get( DataPoint.class, new Long( dp.getId() ) );
|
||||
assertNull( dpManaged.getDescription() );
|
||||
s.delete( dpManaged );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 1 );
|
||||
}
|
||||
}
|
||||
|
|
@ -1,689 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.readonly;
|
||||
|
||||
import org.hibernate.Session;
|
||||
|
||||
import org.hibernate.testing.FailureExpected;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class ReadOnlyVersionedNodesTest extends AbstractReadOnlyTest {
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
return new String[] { "readonly/VersionedNode.hbm.xml" };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetReadOnlyTrueAndFalse() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode node = new VersionedNode( "node", "node" );
|
||||
s.persist( node );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
|
||||
s.beginTransaction();
|
||||
node = ( VersionedNode ) s.get( VersionedNode.class, node.getId() );
|
||||
s.setReadOnly( node, true );
|
||||
node.setName( "node-name" );
|
||||
s.getTransaction().commit();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertInsertCount( 0 );
|
||||
|
||||
// the changed name is still in node
|
||||
assertEquals( "node-name", node.getName() );
|
||||
|
||||
s.beginTransaction();
|
||||
node = ( VersionedNode ) s.get( VersionedNode.class, node.getId() );
|
||||
// the changed name is still in the session
|
||||
assertEquals( "node-name", node.getName() );
|
||||
s.refresh( node );
|
||||
// after refresh, the name reverts to the original value
|
||||
assertEquals( "node", node.getName() );
|
||||
node = ( VersionedNode ) s.get( VersionedNode.class, node.getId() );
|
||||
assertEquals( "node", node.getName() );
|
||||
s.getTransaction().commit();
|
||||
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertInsertCount( 0 );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
node = ( VersionedNode ) s.get( VersionedNode.class, node.getId() );
|
||||
assertEquals( "node", node.getName() );
|
||||
s.setReadOnly( node, true );
|
||||
node.setName( "diff-node-name" );
|
||||
s.flush();
|
||||
assertEquals( "diff-node-name", node.getName() );
|
||||
s.refresh( node );
|
||||
assertEquals( "node", node.getName() );
|
||||
s.setReadOnly( node, false );
|
||||
node.setName( "diff-node-name" );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 1 );
|
||||
assertInsertCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
node = ( VersionedNode ) s.get( VersionedNode.class, node.getId() );
|
||||
assertEquals( "diff-node-name", node.getName() );
|
||||
assertEquals( 1, node.getVersion() );
|
||||
s.setReadOnly( node, true );
|
||||
s.delete( node );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 1 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSetReadOnlyTwice() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode node = new VersionedNode( "node", "node" );
|
||||
s.persist( node );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
|
||||
s.beginTransaction();
|
||||
node = ( VersionedNode ) s.get( VersionedNode.class, node.getId() );
|
||||
node.setName( "node-name" );
|
||||
s.setReadOnly( node, true );
|
||||
s.setReadOnly( node, true );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertInsertCount( 0 );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
node = ( VersionedNode ) s.get( VersionedNode.class, node.getId() );
|
||||
assertEquals( "node", node.getName() );
|
||||
assertEquals( 0, node.getVersion() );
|
||||
s.setReadOnly( node, true );
|
||||
s.delete( node );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 1 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSetModifiable() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode node = new VersionedNode( "node", "node" );
|
||||
s.persist( node );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
|
||||
s.beginTransaction();
|
||||
node = ( VersionedNode ) s.get( VersionedNode.class, node.getId() );
|
||||
node.setName( "node-name" );
|
||||
s.setReadOnly( node, false );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 1 );
|
||||
assertInsertCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
node = ( VersionedNode ) s.get( VersionedNode.class, node.getId() );
|
||||
assertEquals( "node-name", node.getName() );
|
||||
assertEquals( 1, node.getVersion() );
|
||||
s.setReadOnly( node, true );
|
||||
s.delete( node );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 1 );
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected( jiraKey = "unknown" )
|
||||
public void testUpdateSetReadOnlySetModifiable() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode node = new VersionedNode( "node", "node" );
|
||||
s.persist( node );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
|
||||
s.beginTransaction();
|
||||
node = ( VersionedNode ) s.get( VersionedNode.class, node.getId() );
|
||||
node.setName( "node-name" );
|
||||
s.setReadOnly( node, true );
|
||||
s.setReadOnly( node, false );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 1 );
|
||||
assertInsertCount( 0 );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
node = ( VersionedNode ) s.get( VersionedNode.class, node.getId() );
|
||||
assertEquals( "node-name", node.getName() );
|
||||
assertEquals( 1, node.getVersion() );
|
||||
s.delete( node );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected( jiraKey = "unknown" )
|
||||
public void testSetReadOnlyUpdateSetModifiable() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode node = new VersionedNode( "node", "node" );
|
||||
s.persist( node );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
|
||||
s.beginTransaction();
|
||||
node = ( VersionedNode ) s.get( VersionedNode.class, node.getId() );
|
||||
s.setReadOnly( node, true );
|
||||
node.setName( "node-name" );
|
||||
s.setReadOnly( node, false );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 1 );
|
||||
assertInsertCount( 0 );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
node = ( VersionedNode ) s.get( VersionedNode.class, node.getId() );
|
||||
assertEquals( "node-name", node.getName() );
|
||||
assertEquals( 1, node.getVersion() );
|
||||
s.delete( node );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddNewChildToReadOnlyParent() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode parent = new VersionedNode( "parent", "parent" );
|
||||
s.persist( parent );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode parentManaged = ( VersionedNode ) s.get( VersionedNode.class, parent.getId() );
|
||||
s.setReadOnly( parentManaged, true );
|
||||
parentManaged.setName( "new parent name" );
|
||||
VersionedNode child = new VersionedNode( "child", "child");
|
||||
parentManaged.addChild( child );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 1 );
|
||||
assertInsertCount( 1 );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
parent = ( VersionedNode ) s.get( VersionedNode.class, parent.getId() );
|
||||
assertEquals( "parent", parent.getName() );
|
||||
assertEquals( 1, parent.getChildren().size() );
|
||||
assertEquals( 1, parent.getVersion() );
|
||||
child = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
|
||||
assertNotNull( child );
|
||||
s.delete( parent );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateParentWithNewChildCommitWithReadOnlyParent() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode parent = new VersionedNode( "parent", "parent" );
|
||||
s.persist( parent );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
parent.setName( "new parent name" );
|
||||
VersionedNode child = new VersionedNode( "child", "child");
|
||||
parent.addChild( child );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
s.update( parent );
|
||||
s.setReadOnly( parent, true );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 1 );
|
||||
assertInsertCount( 1 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
parent = ( VersionedNode ) s.get( VersionedNode.class, parent.getId() );
|
||||
child = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
|
||||
assertEquals( parent.getName(), "parent" );
|
||||
assertEquals( 1, parent.getChildren().size() );
|
||||
assertEquals( 1, parent.getVersion() );
|
||||
assertSame( parent, child.getParent() );
|
||||
assertSame( child, parent.getChildren().iterator().next() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
s.setReadOnly( parent, true );
|
||||
s.setReadOnly( child, true );
|
||||
s.delete( parent );
|
||||
s.delete( child );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 2 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeDetachedParentWithNewChildCommitWithReadOnlyParent() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode parent = new VersionedNode( "parent", "parent" );
|
||||
s.persist( parent );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
parent.setName( "new parent name" );
|
||||
VersionedNode child = new VersionedNode( "child", "child");
|
||||
parent.addChild( child );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
parent = ( VersionedNode ) s.merge( parent );
|
||||
s.setReadOnly( parent, true );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 1 );
|
||||
assertInsertCount( 1 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
parent = ( VersionedNode ) s.get( VersionedNode.class, parent.getId() );
|
||||
child = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
|
||||
assertEquals( parent.getName(), "parent" );
|
||||
assertEquals( 1, parent.getChildren().size() );
|
||||
assertEquals( 1, parent.getVersion() );
|
||||
assertSame( parent, child.getParent() );
|
||||
assertSame( child, parent.getChildren().iterator().next() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
s.setReadOnly( parent, true );
|
||||
s.setReadOnly( child, true );
|
||||
s.delete( parent );
|
||||
s.delete( child );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 2 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetParentMakeReadOnlyThenMergeDetachedParentWithNewChildC() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode parent = new VersionedNode( "parent", "parent" );
|
||||
s.persist( parent );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
parent.setName( "new parent name" );
|
||||
VersionedNode child = new VersionedNode( "child", "child");
|
||||
parent.addChild( child );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode parentManaged = ( VersionedNode ) s.get( VersionedNode.class, parent.getId() );
|
||||
s.setReadOnly( parentManaged, true );
|
||||
VersionedNode parentMerged = ( VersionedNode ) s.merge( parent );
|
||||
assertSame( parentManaged, parentMerged );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 1 );
|
||||
assertInsertCount( 1 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
parent = ( VersionedNode ) s.get( VersionedNode.class, parent.getId() );
|
||||
child = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
|
||||
assertEquals( parent.getName(), "parent" );
|
||||
assertEquals( 1, parent.getChildren().size() );
|
||||
assertEquals( 1, parent.getVersion() );
|
||||
assertSame( parent, child.getParent() );
|
||||
assertSame( child, parent.getChildren().iterator().next() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
s.delete( parent );
|
||||
s.delete( child );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 2 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeUnchangedDetachedParentChildren() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode parent = new VersionedNode( "parent", "parent" );
|
||||
VersionedNode child = new VersionedNode( "child", "child");
|
||||
parent.addChild( child );
|
||||
s.persist( parent );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
parent = ( VersionedNode ) s.merge( parent );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertInsertCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode parentGet = ( VersionedNode ) s.get( parent.getClass(), parent.getId() );
|
||||
s.merge( parent );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertInsertCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode parentLoad = ( VersionedNode ) s.load( parent.getClass(), parent.getId() );
|
||||
s.merge( parent );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertInsertCount( 0 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
parent = ( VersionedNode ) s.get( VersionedNode.class, parent.getId() );
|
||||
child = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
|
||||
assertEquals( parent.getName(), "parent" );
|
||||
assertEquals( 1, parent.getChildren().size() );
|
||||
assertEquals( 0, parent.getVersion() );
|
||||
assertSame( parent, child.getParent() );
|
||||
assertSame( child, parent.getChildren().iterator().next() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
s.delete( parent );
|
||||
s.delete( child );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 2 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddNewParentToReadOnlyChild() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode child = new VersionedNode( "child", "child" );
|
||||
s.persist( child );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode childManaged = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
|
||||
s.setReadOnly( childManaged, true );
|
||||
childManaged.setName( "new child name" );
|
||||
VersionedNode parent = new VersionedNode( "parent", "parent");
|
||||
parent.addChild( childManaged );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertInsertCount( 1 );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
child = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
|
||||
assertEquals( "child", child.getName() );
|
||||
assertNull( child.getParent() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
parent = ( VersionedNode ) s.get( VersionedNode.class, parent.getId() );
|
||||
assertNotNull( parent );
|
||||
s.setReadOnly( child, true );
|
||||
s.delete( child );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 1 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateChildWithNewParentCommitWithReadOnlyChild() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode child = new VersionedNode( "child", "child" );
|
||||
s.persist( child );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
child.setName( "new child name" );
|
||||
VersionedNode parent = new VersionedNode( "parent", "parent");
|
||||
parent.addChild( child );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
s.update( child );
|
||||
s.setReadOnly( child, true );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertInsertCount( 1 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
parent = ( VersionedNode ) s.get( VersionedNode.class, parent.getId() );
|
||||
child = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
|
||||
assertEquals( child.getName(), "child" );
|
||||
assertNull( child.getParent() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
assertNotNull( parent );
|
||||
assertEquals( 0, parent.getChildren().size() );
|
||||
assertEquals( 0, parent.getVersion() );
|
||||
s.setReadOnly( parent, true );
|
||||
s.setReadOnly( child, true );
|
||||
s.delete( parent );
|
||||
s.delete( child );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 2 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeDetachedChildWithNewParentCommitWithReadOnlyChild() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode child = new VersionedNode( "child", "child" );
|
||||
s.persist( child );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
child.setName( "new child name" );
|
||||
VersionedNode parent = new VersionedNode( "parent", "parent");
|
||||
parent.addChild( child );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
child = ( VersionedNode ) s.merge( child );
|
||||
s.setReadOnly( child, true );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 1 );
|
||||
assertInsertCount( 1 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
parent = ( VersionedNode ) s.get( VersionedNode.class, parent.getId() );
|
||||
child = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
|
||||
assertEquals( child.getName(), "child" );
|
||||
assertNull( child.getParent() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
assertNotNull( parent );
|
||||
assertEquals( 0, parent.getChildren().size() );
|
||||
assertEquals( 1, parent.getVersion() ); // hmmm, why is was version updated?
|
||||
s.setReadOnly( parent, true );
|
||||
s.setReadOnly( child, true );
|
||||
s.delete( parent );
|
||||
s.delete( child );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 2 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetChildMakeReadOnlyThenMergeDetachedChildWithNewParent() throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode child = new VersionedNode( "child", "child" );
|
||||
s.persist( child );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
clearCounts();
|
||||
|
||||
child.setName( "new child name" );
|
||||
VersionedNode parent = new VersionedNode( "parent", "parent");
|
||||
parent.addChild( child );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
VersionedNode childManaged = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
|
||||
s.setReadOnly( childManaged, true );
|
||||
VersionedNode childMerged = ( VersionedNode ) s.merge( child );
|
||||
assertSame( childManaged, childMerged );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 1 );
|
||||
assertInsertCount( 1 );
|
||||
clearCounts();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
parent = ( VersionedNode ) s.get( VersionedNode.class, parent.getId() );
|
||||
child = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
|
||||
assertEquals( child.getName(), "child" );
|
||||
assertNull( child.getParent() );
|
||||
assertEquals( 0, child.getVersion() );
|
||||
assertNotNull( parent );
|
||||
assertEquals( 0, parent.getChildren().size() );
|
||||
assertEquals( 1, parent.getVersion() ); // / hmmm, why is was version updated?
|
||||
s.setReadOnly( parent, true );
|
||||
s.setReadOnly( child, true );
|
||||
s.delete( parent );
|
||||
s.delete( child );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertUpdateCount( 0 );
|
||||
assertDeleteCount( 2 );
|
||||
}
|
||||
|
||||
protected void cleanupTest() throws Exception {
|
||||
cleanup();
|
||||
super.cleanupTest();
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
Session s = sessionFactory().openSession();
|
||||
s.beginTransaction();
|
||||
|
||||
s.createQuery( "delete from VersionedNode where parent is not null" ).executeUpdate();
|
||||
s.createQuery( "delete from VersionedNode" ).executeUpdate();
|
||||
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue