Hibernate SVN: r18004 - in core/trunk/core/src/main/java/org/hibernate: lob and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: smarlow(a)redhat.com
Date: 2009-11-18 11:35:28 -0500 (Wed, 18 Nov 2009)
New Revision: 18004
Added:
core/trunk/core/src/main/java/org/hibernate/lob/
core/trunk/core/src/main/java/org/hibernate/lob/ReaderInputStream.java
Log:
HHH-4588 workaround for JBSEAM-4474
Added: core/trunk/core/src/main/java/org/hibernate/lob/ReaderInputStream.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/lob/ReaderInputStream.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/lob/ReaderInputStream.java 2009-11-18 16:35:28 UTC (rev 18004)
@@ -0,0 +1,45 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.lob;
+
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * Exposes a {@link java.io.Reader} as an {@link java.io.InputStream}.
+ *
+ * @deprecated Should not be used anymore.
+ */
+public class ReaderInputStream extends org.hibernate.engine.jdbc.ReaderInputStream {
+
+ public ReaderInputStream(Reader reader) {
+ super(reader);
+ }
+
+ public int read() throws IOException {
+ return super.read();
+ }
+
+}
\ No newline at end of file
14 years, 7 months
Hibernate SVN: r18003 - validator/trunk/hibernate-validator.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-11-18 09:11:56 -0500 (Wed, 18 Nov 2009)
New Revision: 18003
Modified:
validator/trunk/hibernate-validator/pom.xml
Log:
HV-272 - explicitly foce the jaxb plugin version
Modified: validator/trunk/hibernate-validator/pom.xml
===================================================================
--- validator/trunk/hibernate-validator/pom.xml 2009-11-18 13:27:14 UTC (rev 18002)
+++ validator/trunk/hibernate-validator/pom.xml 2009-11-18 14:11:56 UTC (rev 18003)
@@ -110,6 +110,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
+ <version>1.3</version>
<executions>
<execution>
<goals>
14 years, 7 months
Hibernate SVN: r18002 - validator/trunk/hibernate-validator.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-11-18 08:27:14 -0500 (Wed, 18 Nov 2009)
New Revision: 18002
Modified:
validator/trunk/hibernate-validator/pom.xml
Log:
HV-273
Modified: validator/trunk/hibernate-validator/pom.xml
===================================================================
--- validator/trunk/hibernate-validator/pom.xml 2009-11-18 12:05:34 UTC (rev 18001)
+++ validator/trunk/hibernate-validator/pom.xml 2009-11-18 13:27:14 UTC (rev 18002)
@@ -30,7 +30,7 @@
<dependency>
<groupId>com.googlecode.jtype</groupId>
<artifactId>jtype</artifactId>
- <version>0.1.0</version>
+ <version>0.1.1</version>
</dependency>
<!--
@@ -67,7 +67,7 @@
<dependency>
<groupId>org.hibernate.java-persistence</groupId>
<artifactId>jpa-api</artifactId>
- <version>2.0.Beta-20090815</version>
+ <version>2.0-cr-1</version>
<optional>true</optional>
</dependency>
14 years, 7 months
Hibernate SVN: r18001 - in validator/trunk: hibernate-validator and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-11-18 07:05:34 -0500 (Wed, 18 Nov 2009)
New Revision: 18001
Modified:
validator/trunk/hibernate-validator/pom.xml
validator/trunk/hibernate-validator/readme.txt
validator/trunk/hibernate-validator/src/main/assembly/dist.xml
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/ValidationXmlParser.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/XmlMappingParser.java
validator/trunk/pom.xml
Log:
HV-272
Removed the jaxb profile and made the dependencies provided
Updated the readme and assembly configuration
Added enforcer to parent pom to force JDK
Modified: validator/trunk/hibernate-validator/pom.xml
===================================================================
--- validator/trunk/hibernate-validator/pom.xml 2009-11-18 10:49:30 UTC (rev 18000)
+++ validator/trunk/hibernate-validator/pom.xml 2009-11-18 12:05:34 UTC (rev 18001)
@@ -44,6 +44,24 @@
</dependency>
<!--
+ Provided dependencies.
+ JAXB is needed when running on Java5. In this environment these dependencies have to be added
+ On Java6 jaxb is part of the runtime environment
+ -->
+ <dependency>
+ <groupId>javax.xml.bind</groupId>
+ <artifactId>jaxb-api</artifactId>
+ <version>2.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.xml.bind</groupId>
+ <artifactId>jaxb-impl</artifactId>
+ <version>2.1.12</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <!--
Optional dependencies
-->
<dependency>
@@ -131,7 +149,6 @@
<outputName>test-report</outputName>
</configuration>
</plugin>
-
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
@@ -246,6 +263,13 @@
<artifactId>maven-cli-plugin</artifactId>
<version>0.6.3.CR3</version>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <goals>javadoc:javadoc org.jboss.maven.plugins:maven-jdocbook-plugin:2.2.0:resources org.jboss.maven.plugins:maven-jdocbook-plugin:2.2.0:generate assembly:assembly deploy</goals>
+ </configuration>
+ </plugin>
</plugins>
</build>
<reporting>
@@ -257,24 +281,4 @@
</plugin>
</plugins>
</reporting>
- <profiles>
- <profile>
- <id>jaxb</id>
- <activation>
- <jdk>1.5</jdk>
- </activation>
- <dependencies>
- <dependency>
- <groupId>javax.xml.bind</groupId>
- <artifactId>jaxb-api</artifactId>
- <version>2.1</version>
- </dependency>
- <dependency>
- <groupId>com.sun.xml.bind</groupId>
- <artifactId>jaxb-impl</artifactId>
- <version>2.1.3</version>
- </dependency>
- </dependencies>
- </profile>
- </profiles>
</project>
Modified: validator/trunk/hibernate-validator/readme.txt
===================================================================
--- validator/trunk/hibernate-validator/readme.txt 2009-11-18 10:49:30 UTC (rev 18000)
+++ validator/trunk/hibernate-validator/readme.txt 2009-11-18 12:05:34 UTC (rev 18001)
@@ -16,11 +16,6 @@
is not based on JSR 303. This code can be accessed via
http://anonsvn.jboss.org/repos/hibernate/validator/trunk/hibernate-valida...
- Status
- ------
-
- This is the first GA release of Hibernate Validator 4.
-
Documentation
-------------
@@ -41,9 +36,9 @@
Using Hibernate Validator
-------------------------
- - Copy hibernate-validator-*.jar together will all jar files from lib into the
- classpath of your application. In case you are running on JDK5 you have to also include
- all the jar files from the jdk5 subdirectory.
+ - In case you use the distribution archive from the download sire, copy hibernate-validator-*.jar together
+ with all jar files from lib into the classpath of your application.
+ In case you are using Java 5 you have to also include all the jar files from the jdk5 subdirectory.
or
@@ -55,7 +50,7 @@
<version>${project.version}</version>
</dependency>
- Hibernate Validator can be found in this repository: http://repository.jboss.com/maven2/
+ Hibernate Validator can be found in the JBoss Maven repository: http://repository.jboss.com/maven2/
Licensing
---------
Modified: validator/trunk/hibernate-validator/src/main/assembly/dist.xml
===================================================================
--- validator/trunk/hibernate-validator/src/main/assembly/dist.xml 2009-11-18 10:49:30 UTC (rev 18000)
+++ validator/trunk/hibernate-validator/src/main/assembly/dist.xml 2009-11-18 12:05:34 UTC (rev 18001)
@@ -42,7 +42,7 @@
<dependencySet>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>lib/jdk5</outputDirectory>
- <scope>runtime</scope>
+ <scope>provided</scope>
<includes>
<include>javax.xml.bind:jaxb-api</include>
<include>com.sun.xml.bind:jaxb-impl</include>
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/ValidationXmlParser.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/ValidationXmlParser.java 2009-11-18 10:49:30 UTC (rev 18000)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/ValidationXmlParser.java 2009-11-18 12:05:34 UTC (rev 18001)
@@ -124,15 +124,15 @@
}
private void setMappingStreamsFromXml(ValidationConfigType config, ValidationBootstrapParameters xmlParameters) {
- for ( JAXBElement<String> mappingFileName : config.getConstraintMapping() ) {
+ for ( String mappingFileName : config.getConstraintMapping() ) {
if ( log.isDebugEnabled() ) {
log.debug(
- "Trying to open input stream for {}.", mappingFileName.getValue()
+ "Trying to open input stream for {}.", mappingFileName
);
}
- InputStream in = getInputStreamForPath( mappingFileName.getValue() );
+ InputStream in = getInputStreamForPath( mappingFileName );
if ( in == null ) {
- throw new ValidationException( "Unable to open input stream for mapping file " + mappingFileName.getValue() + "." );
+ throw new ValidationException( "Unable to open input stream for mapping file " + mappingFileName + "." );
}
xmlParameters.mappings.add( in );
}
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/XmlMappingParser.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/XmlMappingParser.java 2009-11-18 10:49:30 UTC (rev 18000)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/XmlMappingParser.java 2009-11-18 12:05:34 UTC (rev 18001)
@@ -168,10 +168,10 @@
if ( validatedByType.isIncludeExistingValidators() != null && validatedByType.isIncludeExistingValidators() ) {
constraintValidatorClasses.addAll( findConstraintValidatorClasses( annotationClass ) );
}
- for ( JAXBElement<String> validatorClassName : validatedByType.getValue() ) {
+ for ( String validatorClassName : validatedByType.getValue() ) {
Class<? extends ConstraintValidator<?, ?>> validatorClass;
validatorClass = ( Class<? extends ConstraintValidator<?, ?>> ) loadClass(
- validatorClassName.getValue(),
+ validatorClassName,
this.getClass()
);
@@ -368,8 +368,8 @@
private List<Class<?>> createGroupSequence(GroupSequenceType groupSequenceType, String defaultPackage) {
List<Class<?>> groupSequence = new ArrayList<Class<?>>();
if ( groupSequenceType != null ) {
- for ( JAXBElement<String> groupName : groupSequenceType.getValue() ) {
- Class<?> group = getClass( groupName.getValue(), defaultPackage );
+ for ( String groupName : groupSequenceType.getValue() ) {
+ Class<?> group = getClass( groupName, defaultPackage );
groupSequence.add( group );
}
}
@@ -601,8 +601,8 @@
}
List<Class<?>> groupList = new ArrayList<Class<?>>();
- for ( JAXBElement<String> groupClass : groupsType.getValue() ) {
- groupList.add( getClass( groupClass.getValue(), defaultPackage ) );
+ for ( String groupClass : groupsType.getValue() ) {
+ groupList.add( getClass( groupClass, defaultPackage ) );
}
return groupList.toArray( new Class[groupList.size()] );
}
@@ -614,8 +614,8 @@
}
List<Class<? extends Payload>> payloadList = new ArrayList<Class<? extends Payload>>();
- for ( JAXBElement<String> groupClass : payloadType.getValue() ) {
- Class<?> payload = getClass( groupClass.getValue(), defaultPackage );
+ for ( String groupClass : payloadType.getValue() ) {
+ Class<?> payload = getClass( groupClass, defaultPackage );
if ( !Payload.class.isAssignableFrom( payload ) ) {
throw new ValidationException( "Specified payload class " + payload.getName() + " does not implement javax.validation.Payload" );
}
Modified: validator/trunk/pom.xml
===================================================================
--- validator/trunk/pom.xml 2009-11-18 10:49:30 UTC (rev 18000)
+++ validator/trunk/pom.xml 2009-11-18 12:05:34 UTC (rev 18001)
@@ -76,6 +76,28 @@
<version>1.0-beta-2</version>
</extension>
</extensions>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>enforce-java</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <rules>
+ <requireJavaVersion>
+ <!-- require JDK 1.6 to run the build -->
+ <version>[1.6,)</version>
+ </requireJavaVersion>
+ </rules>
+ </configuration>
+ </plugin>
+ </plugins>
<pluginManagement>
<plugins>
<plugin>
@@ -143,7 +165,7 @@
<autoVersionSubmodules>true</autoVersionSubmodules>
<allowTimestampedSnapshots>true</allowTimestampedSnapshots>
<remoteTagging>true</remoteTagging>
- <goals>package site assembly:assembly deploy</goals>
+ <goals>deploy</goals>
</configuration>
</plugin>
</plugins>
14 years, 7 months
Hibernate SVN: r18000 - core/branches/Branch_3_2_4_SP1_CP.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2009-11-18 05:49:30 -0500 (Wed, 18 Nov 2009)
New Revision: 18000
Modified:
core/branches/Branch_3_2_4_SP1_CP/build.xml
Log:
JBPAPP-3115 update HREFs for JDK from jdk1.4 to jdk1.5
Modified: core/branches/Branch_3_2_4_SP1_CP/build.xml
===================================================================
--- core/branches/Branch_3_2_4_SP1_CP/build.xml 2009-11-18 10:33:47 UTC (rev 17999)
+++ core/branches/Branch_3_2_4_SP1_CP/build.xml 2009-11-18 10:49:30 UTC (rev 18000)
@@ -59,7 +59,7 @@
<property name="dir.dist" value="${dir.build}/dist" />
<!-- Define various operational options -->
- <property name="javadoc.url.jse" value="http://java.sun.com/j2se/1.4/docs/api"/>
+ <property name="javadoc.url.jse" value="http://java.sun.com/j2se/1.5.0/docs/api"/>
<property name="javac.debug" value="on"/>
<property name="javac.optimize" value="off"/>
<property name="javac.target" value="1.5"/>
14 years, 7 months
Hibernate SVN: r17998 - in core/trunk/testsuite/src/test/java/org/hibernate/test: nonflushedchanges and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: gbadner
Date: 2009-11-17 18:17:25 -0500 (Tue, 17 Nov 2009)
New Revision: 17998
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/AbstractOperationTestCase.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Address.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competitor.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/CreateTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/DeleteTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employee.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/GetLoadTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/MergeTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/NumberedNode.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OneToOne.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OptLockEntity.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Person.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/PersonalDetails.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/SaveOrUpdateTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/TimestampedEntity.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/VersionedEntity.java
Log:
HHH-2762 : new unit tests for SessionImplementor.getNonFlushedChanges()/applyNonFlushedChanges() implementation
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/AbstractOperationTestCase.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/AbstractOperationTestCase.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/AbstractOperationTestCase.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,130 @@
+package org.hibernate.test.nonflushedchanges;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.Session;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.NonFlushedChanges;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.StatefulPersistenceContext;
+import org.hibernate.junit.functional.FunctionalTestCase;
+import org.hibernate.test.tm.ConnectionProviderImpl;
+import org.hibernate.test.tm.TransactionManagerLookupImpl;
+import org.hibernate.transaction.CMTTransactionFactory;
+import org.hibernate.util.SerializationHelper;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
+ */
+public abstract class AbstractOperationTestCase extends FunctionalTestCase {
+ private Map oldToNewEntityRefs = new HashMap();
+
+ public AbstractOperationTestCase(String name) {
+ super( name );
+ }
+
+ public void configure(Configuration cfg) {
+ super.configure( cfg );
+ cfg.setProperty( Environment.CONNECTION_PROVIDER, ConnectionProviderImpl.class.getName() );
+ cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, TransactionManagerLookupImpl.class.getName() );
+ cfg.setProperty( Environment.TRANSACTION_STRATEGY, CMTTransactionFactory.class.getName() );
+ cfg.setProperty( Environment.AUTO_CLOSE_SESSION, "true" );
+ cfg.setProperty( Environment.FLUSH_BEFORE_COMPLETION, "true" );
+ cfg.setProperty( Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.AFTER_STATEMENT.toString() );
+ cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
+ cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
+ }
+
+ public String[] getMappings() {
+ return new String[] {
+ "nonflushedchanges/Node.hbm.xml",
+ "nonflushedchanges/Employer.hbm.xml",
+ "nonflushedchanges/OptLockEntity.hbm.xml",
+ "nonflushedchanges/OneToOne.hbm.xml",
+ "nonflushedchanges/Competition.hbm.xml"
+ };
+ }
+
+ public String getCacheConcurrencyStrategy() {
+ return null;
+ }
+
+ protected void clearCounts() {
+ getSessions().getStatistics().clear();
+ }
+
+ protected void assertInsertCount(int expected) {
+ int inserts = ( int ) getSessions().getStatistics().getEntityInsertCount();
+ assertEquals( "unexpected insert count", expected, inserts );
+ }
+
+ protected void assertUpdateCount(int expected) {
+ int updates = ( int ) getSessions().getStatistics().getEntityUpdateCount();
+ assertEquals( "unexpected update counts", expected, updates );
+ }
+
+ protected void assertDeleteCount(int expected) {
+ int deletes = ( int ) getSessions().getStatistics().getEntityDeleteCount();
+ assertEquals( "unexpected delete counts", expected, deletes );
+ }
+
+ protected void assertFetchCount(int count) {
+ int fetches = ( int ) getSessions().getStatistics().getEntityFetchCount();
+ assertEquals( count, fetches );
+ }
+
+ protected Session applyNonFlushedChangesToNewSessionCloseOldSession(Session oldSession) {
+ NonFlushedChanges nfc = ( ( SessionImplementor ) oldSession ).getNonFlushedChanges();
+ byte[] bytes = SerializationHelper.serialize( nfc );
+ NonFlushedChanges nfc2 = ( NonFlushedChanges ) SerializationHelper.deserialize( bytes );
+ Session newSession = openSession();
+ ( ( SessionImplementor ) newSession ).applyNonFlushedChanges( nfc2 );
+ oldToNewEntityRefs.clear();
+ for ( Iterator it = ( ( SessionImplementor ) oldSession ).getPersistenceContext()
+ .getEntitiesByKey()
+ .entrySet()
+ .iterator(); it.hasNext(); ) {
+ Map.Entry entry = ( Map.Entry ) it.next();
+ EntityKey entityKey = ( EntityKey ) entry.getKey();
+ Object oldEntityRef = entry.getValue();
+ oldToNewEntityRefs.put(
+ oldEntityRef, ( ( SessionImplementor ) newSession ).getPersistenceContext().getEntity( entityKey )
+ );
+ }
+ for ( Iterator it = ( ( StatefulPersistenceContext ) ( ( SessionImplementor ) oldSession ).getPersistenceContext() )
+ .getProxiesByKey()
+ .entrySet()
+ .iterator(); it.hasNext(); ) {
+ Map.Entry entry = ( Map.Entry ) it.next();
+ EntityKey entityKey = ( EntityKey ) entry.getKey();
+ Object oldProxyRef = entry.getValue();
+ oldToNewEntityRefs.put(
+ oldProxyRef, ( ( SessionImplementor ) newSession ).getPersistenceContext().getProxy( entityKey )
+ );
+ }
+
+ oldSession.clear();
+ oldSession.close();
+ return newSession;
+ }
+
+ protected void applyNonFlushedChangesToClearedSession(Session s) {
+ NonFlushedChanges nfc = ( ( SessionImplementor ) s ).getNonFlushedChanges();
+ byte[] bytes = SerializationHelper.serialize( nfc );
+ NonFlushedChanges nfc2 = ( NonFlushedChanges ) SerializationHelper.deserialize( bytes );
+ s.clear();
+ ( ( SessionImplementor ) s ).applyNonFlushedChanges( nfc2 );
+ }
+
+ protected Map getOldToNewEntityRefMap() {
+ return Collections.unmodifiableMap( oldToNewEntityRefs );
+ }
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Address.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Address.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Address.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,67 @@
+package org.hibernate.test.nonflushedchanges;
+
+import java.io.Serializable;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
+ */
+public class Address implements Serializable {
+ private Long id;
+ private String streetAddress;
+ private String city;
+ private String country;
+ private Person resident;
+
+ public Address() {
+ }
+
+ public Address(String streetAddress, String city, String country, Person resident) {
+ this.streetAddress = streetAddress;
+ this.city = city;
+ this.country = country;
+ this.resident = resident;
+ resident.setAddress( this );
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getStreetAddress() {
+ return streetAddress;
+ }
+
+ public void setStreetAddress(String streetAddress) {
+ this.streetAddress = streetAddress;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ public Person getResident() {
+ return resident;
+ }
+
+ public void setResident(Person resident) {
+ this.resident = resident;
+ }
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.hbm.xml 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.nonflushedchanges">
+
+ <class name="Competition">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <list name="competitors" table="COMPET_ION_OR" cascade="persist,merge,delete">
+ <key column="TION_ID"/>
+ <list-index column="INDEX_COL"/>
+ <many-to-many class="Competitor" column="TOR_ID"/>
+ </list>
+ </class>
+
+ <class name="Competitor">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>
+
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,32 @@
+//$Id: $
+package org.hibernate.test.nonflushedchanges;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Emmanuel Bernard, Gail Badner (adapted this from "ops" tests version)
+ */
+public class Competition implements Serializable {
+ private Integer id;
+
+ private List competitors = new ArrayList();
+
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public List getCompetitors() {
+ return competitors;
+ }
+
+ public void setCompetitors(List competitors) {
+ this.competitors = competitors;
+ }
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competitor.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competitor.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competitor.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,36 @@
+//$Id: $
+package org.hibernate.test.nonflushedchanges;
+
+import java.io.Serializable;
+
+/**
+ * @author Emmanuel Bernard, Gail Badner (adapted this from "ops" tests version)
+ */
+public class Competitor implements Serializable {
+ public Integer id;
+ private String name;
+
+
+ public Competitor() {
+ }
+
+ public Competitor(String name) {
+ this.name = name;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/CreateTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/CreateTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/CreateTest.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,250 @@
+//$Id: CreateTest.java 10977 2006-12-12 23:28:04Z steve.ebersole(a)jboss.com $
+package org.hibernate.test.nonflushedchanges;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import junit.framework.Test;
+
+import org.hibernate.Hibernate;
+import org.hibernate.PersistentObjectException;
+import org.hibernate.Session;
+import org.hibernate.exception.ConstraintViolationException;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.tm.SimpleJtaTransactionManagerImpl;
+
+/**
+ * @author Gavin King, Gail Badner (adapted this from "ops" tests version)
+ */
+public class CreateTest extends AbstractOperationTestCase {
+
+ public CreateTest(String str) {
+ super( str );
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( CreateTest.class );
+ }
+
+ public void testNoUpdatesOnCreateVersionedWithCollection() throws Exception {
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ VersionedEntity root = new VersionedEntity( "root", "root" );
+ VersionedEntity child = new VersionedEntity( "c1", "child-1" );
+ root.getChildren().add( child );
+ child.setParent( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ s.save( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( VersionedEntity ) getOldToNewEntityRefMap().get( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( VersionedEntity ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ assertDeleteCount( 0 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.delete( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( VersionedEntity ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testCreateTree() throws Exception {
+
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Node root = new Node( "root" );
+ Node child = new Node( "child" );
+ root.addChild( child );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ s.persist( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ System.out.println( "getting" );
+ root = ( Node ) s.get( Node.class, "root" );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( Node ) getOldToNewEntityRefMap().get( root );
+ Node child2 = new Node( "child2" );
+ root.addChild( child2 );
+ System.out.println( "committing" );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ }
+
+ public void testCreateTreeWithGeneratedId() throws Exception {
+
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ NumberedNode root = new NumberedNode( "root" );
+ NumberedNode child = new NumberedNode( "child" );
+ root.addChild( child );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ s.persist( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) s.get( NumberedNode.class, new Long( root.getId() ) );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ NumberedNode child2 = new NumberedNode( "child2" );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ root.addChild( child2 );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ }
+
+ public void testCreateException() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Node dupe = new Node( "dupe" );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ s.persist( dupe );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ dupe = ( Node ) getOldToNewEntityRefMap().get( dupe );
+ s.persist( dupe );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ s.persist( dupe );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ try {
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ assertFalse( true );
+ }
+ catch ( ConstraintViolationException cve ) {
+ //verify that an exception is thrown!
+ }
+ SimpleJtaTransactionManagerImpl.getInstance().rollback();
+
+ Node nondupe = new Node( "nondupe" );
+ nondupe.addChild( dupe );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ s.persist( nondupe );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ try {
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ assertFalse( true );
+ }
+ catch ( ConstraintViolationException cve ) {
+ //verify that an exception is thrown!
+ }
+ SimpleJtaTransactionManagerImpl.getInstance().rollback();
+ }
+
+ public void testCreateExceptionWithGeneratedId() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ NumberedNode dupe = new NumberedNode( "dupe" );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ s.persist( dupe );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ dupe = ( NumberedNode ) getOldToNewEntityRefMap().get( dupe );
+ s.persist( dupe );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ try {
+ s.persist( dupe );
+ assertFalse( true );
+ }
+ catch ( PersistentObjectException poe ) {
+ //verify that an exception is thrown!
+ }
+ SimpleJtaTransactionManagerImpl.getInstance().rollback();
+
+ NumberedNode nondupe = new NumberedNode( "nondupe" );
+ nondupe.addChild( dupe );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ try {
+ s.persist( nondupe );
+ assertFalse( true );
+ }
+ catch ( PersistentObjectException poe ) {
+ //verify that an exception is thrown!
+ }
+ SimpleJtaTransactionManagerImpl.getInstance().rollback();
+ }
+
+ public void testBasic() throws Exception {
+ Session s;
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ Employer er = new Employer();
+ Employee ee = new Employee();
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ s.persist( ee );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ ee = ( Employee ) getOldToNewEntityRefMap().get( ee );
+ Collection erColl = new ArrayList();
+ Collection eeColl = new ArrayList();
+ erColl.add( ee );
+ eeColl.add( er );
+ er.setEmployees( erColl );
+ ee.setEmployers( eeColl );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ ee = ( Employee ) getOldToNewEntityRefMap().get( ee );
+ er = ( Employer ) ee.getEmployers().iterator().next();
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ er = ( Employer ) s.load( Employer.class, er.getId() );
+ assertNotNull( er );
+ assertFalse( Hibernate.isInitialized( er ) );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ er = ( Employer ) getOldToNewEntityRefMap().get( er );
+ assertNotNull( er );
+ assertFalse( Hibernate.isInitialized( er ) );
+ assertNotNull( er.getEmployees() );
+ assertEquals( 1, er.getEmployees().size() );
+ Employee eeFromDb = ( Employee ) er.getEmployees().iterator().next();
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ eeFromDb = ( Employee ) getOldToNewEntityRefMap().get( eeFromDb );
+ assertEquals( ee.getId(), eeFromDb.getId() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/DeleteTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/DeleteTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/DeleteTest.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,94 @@
+package org.hibernate.test.nonflushedchanges;
+
+import junit.framework.Test;
+
+import org.hibernate.Session;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.tm.SimpleJtaTransactionManagerImpl;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
+ */
+public class DeleteTest extends AbstractOperationTestCase {
+ public DeleteTest(String name) {
+ super( name );
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( DeleteTest.class );
+ }
+
+ public void testDeleteVersionedWithCollectionNoUpdate() throws Exception {
+ // test adapted from HHH-1564...
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ VersionedEntity c = new VersionedEntity( "c1", "child-1" );
+ VersionedEntity p = new VersionedEntity( "root", "root" );
+ p.getChildren().add( c );
+ c.setParent( p );
+ s.save( p );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ VersionedEntity loadedParent = ( VersionedEntity ) s.get( VersionedEntity.class, "root" );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ loadedParent = ( VersionedEntity ) getOldToNewEntityRefMap().get( loadedParent );
+ s.delete( loadedParent );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testNoUpdateOnDelete() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Node node = new Node( "test" );
+ s.persist( node );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ s.delete( node );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertUpdateCount( 0 );
+ assertInsertCount( 0 );
+ }
+
+ public void testNoUpdateOnDeleteWithCollection() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Node parent = new Node( "parent" );
+ Node child = new Node( "child" );
+ parent.getCascadingChildren().add( child );
+ s.persist( parent );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ parent = ( Node ) s.get( Node.class, "parent" );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ parent = ( Node ) getOldToNewEntityRefMap().get( parent );
+ s.delete( parent );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertUpdateCount( 0 );
+ assertInsertCount( 0 );
+ assertDeleteCount( 2 );
+ }
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employee.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employee.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employee.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,35 @@
+//$Id: Employee.java 5686 2005-02-12 07:27:32Z steveebersole $
+package org.hibernate.test.nonflushedchanges;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+
+/**
+ * Employee in an Employer-Employee relationship
+ *
+ * @author Emmanuel Bernard, Gail Badner (adapted this from "ops" tests version)
+ */
+
+public class Employee implements Serializable {
+ private Integer id;
+ private Collection employers;
+
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer integer) {
+ id = integer;
+ }
+
+
+ public Collection getEmployers() {
+ return employers;
+ }
+
+ public void setEmployers(Collection employers) {
+ this.employers = employers;
+ }
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.hbm.xml 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.nonflushedchanges">
+
+ <class name="Employer" polymorphism="explicit">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <version column="vers" name="vers"/>
+ <bag name="employees"
+ cascade="persist,merge"
+ table="EMPLOYER_EMPLOYEE">
+ <key column="EMPER_ID"/>
+ <many-to-many class="Employee" column="EMPEE_ID"/>
+ </bag>
+ </class>
+
+ <class name="Employee" polymorphism="explicit">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <bag name="employers"
+ inverse="true"
+ cascade="persist,merge,save-update"
+ table="EMPLOYER_EMPLOYEE">
+ <key column="EMPEE_ID"/>
+ <many-to-many class="Employer" column="EMPER_ID"/>
+ </bag>
+ </class>
+
+</hibernate-mapping>
+
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,44 @@
+//$Id: Employer.java 8670 2005-11-25 17:36:29Z epbernard $
+package org.hibernate.test.nonflushedchanges;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+
+/**
+ * Employer in a employer-Employee relationship
+ *
+ * @author Emmanuel Bernard, Gail Badner (adapted this from "ops" tests version)
+ */
+
+public class Employer implements Serializable {
+ private Integer id;
+ private Collection employees;
+ private Integer vers;
+
+ public Integer getVers() {
+ return vers;
+ }
+
+ public void setVers(Integer vers) {
+ this.vers = vers;
+ }
+
+
+ public Collection getEmployees() {
+ return employees;
+ }
+
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setEmployees(Collection set) {
+ employees = set;
+ }
+
+ public void setId(Integer integer) {
+ id = integer;
+ }
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/GetLoadTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/GetLoadTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/GetLoadTest.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,126 @@
+//$Id: GetLoadTest.java 10977 2006-12-12 23:28:04Z steve.ebersole(a)jboss.com $
+package org.hibernate.test.nonflushedchanges;
+
+import junit.framework.Test;
+
+import org.hibernate.Hibernate;
+import org.hibernate.Session;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.tm.SimpleJtaTransactionManagerImpl;
+
+
+/**
+ * @author Gavin King, Gail Badner (adapted this from "ops" tests version)
+ */
+public class GetLoadTest extends AbstractOperationTestCase {
+
+ public GetLoadTest(String str) {
+ super( str );
+ }
+
+ public void testGetLoad() throws Exception {
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Employer emp = new Employer();
+ s.persist( emp );
+ Node node = new Node( "foo" );
+ Node parent = new Node( "bar" );
+ parent.addChild( node );
+ s.persist( parent );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ emp = ( Employer ) s.get( Employer.class, emp.getId() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ emp = ( Employer ) getOldToNewEntityRefMap().get( emp );
+ assertTrue( Hibernate.isInitialized( emp ) );
+ assertFalse( Hibernate.isInitialized( emp.getEmployees() ) );
+ node = ( Node ) s.get( Node.class, node.getName() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ node = ( Node ) getOldToNewEntityRefMap().get( node );
+ emp = ( Employer ) getOldToNewEntityRefMap().get( emp );
+ assertTrue( Hibernate.isInitialized( node ) );
+ assertFalse( Hibernate.isInitialized( node.getChildren() ) );
+ assertFalse( Hibernate.isInitialized( node.getParent() ) );
+ assertNull( s.get( Node.class, "xyz" ) );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ emp = ( Employer ) s.load( Employer.class, emp.getId() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ emp = ( Employer ) getOldToNewEntityRefMap().get( emp );
+ emp.getId();
+ assertFalse( Hibernate.isInitialized( emp ) );
+ node = ( Node ) s.load( Node.class, node.getName() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ node = ( Node ) getOldToNewEntityRefMap().get( node );
+ assertEquals( node.getName(), "foo" );
+ assertFalse( Hibernate.isInitialized( node ) );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ emp = ( Employer ) s.get( "org.hibernate.test.nonflushedchanges.Employer", emp.getId() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ emp = ( Employer ) getOldToNewEntityRefMap().get( emp );
+ assertTrue( Hibernate.isInitialized( emp ) );
+ node = ( Node ) s.get( "org.hibernate.test.nonflushedchanges.Node", node.getName() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ node = ( Node ) getOldToNewEntityRefMap().get( node );
+ assertTrue( Hibernate.isInitialized( node ) );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ emp = ( Employer ) s.load( "org.hibernate.test.nonflushedchanges.Employer", emp.getId() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ emp = ( Employer ) getOldToNewEntityRefMap().get( emp );
+ emp.getId();
+ assertFalse( Hibernate.isInitialized( emp ) );
+ node = ( Node ) s.load( "org.hibernate.test.nonflushedchanges.Node", node.getName() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ emp = ( Employer ) getOldToNewEntityRefMap().get( emp );
+ node = ( Node ) getOldToNewEntityRefMap().get( node );
+ assertEquals( node.getName(), "foo" );
+ assertFalse( Hibernate.isInitialized( node ) );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertFetchCount( 0 );
+ }
+
+ public void testGetAfterDelete() throws Exception {
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Employer emp = new Employer();
+ s.persist( emp );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.delete( emp );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ emp = ( Employer ) s.get( Employee.class, emp.getId() );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertNull( "get did not return null after delete", emp );
+ }
+
+ public void configure(Configuration cfg) {
+ super.configure( cfg );
+ cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
+ cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( GetLoadTest.class );
+ }
+}
+
Property changes on: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/GetLoadTest.java
___________________________________________________________________
Name: svn:executable
+ *
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/MergeTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/MergeTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/MergeTest.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,844 @@
+//$Id: MergeTest.java 11037 2007-01-09 16:04:16Z steve.ebersole(a)jboss.com $
+package org.hibernate.test.nonflushedchanges;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import junit.framework.Test;
+
+import org.hibernate.Hibernate;
+import org.hibernate.NonUniqueObjectException;
+import org.hibernate.Session;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.criterion.Projections;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.tm.SimpleJtaTransactionManagerImpl;
+
+/**
+ * @author Gavin King, Gail Badner (adapted this from "ops" tests version)
+ */
+public class MergeTest extends AbstractOperationTestCase {
+
+ public MergeTest(String str) {
+ super( str );
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( MergeTest.class );
+ }
+
+ public void testMergeStaleVersionFails() throws Exception {
+
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ VersionedEntity entity = new VersionedEntity( "entity", "entity" );
+ s.persist( entity );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ // make the detached 'entity' reference stale...
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ VersionedEntity entity2 = ( VersionedEntity ) s.get( VersionedEntity.class, entity.getId() );
+ entity2.setName( "entity-name" );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ // now try to reattch it
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ try {
+ s.merge( entity );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ entity = ( VersionedEntity ) getOldToNewEntityRefMap().get( entity );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ fail( "was expecting staleness error" );
+ }
+ catch ( StaleObjectStateException expected ) {
+ // expected outcome...
+ }
+ finally {
+ SimpleJtaTransactionManagerImpl.getInstance().rollback();
+ }
+ }
+
+ public void testMergeBidiPrimayKeyOneToOne() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Person p = new Person( "steve" );
+ new PersonalDetails( "I have big feet", p );
+ s.persist( p );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ p.getDetails().setSomePersonalDetail( p.getDetails().getSomePersonalDetail() + " and big hands too" );
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ p = ( Person ) s.merge( p );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ p = ( Person ) getOldToNewEntityRefMap().get( p );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( 1 );
+ assertDeleteCount( 0 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.delete( p );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ }
+
+ public void testMergeBidiForeignKeyOneToOne() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Person p = new Person( "steve" );
+ Address a = new Address( "123 Main", "Austin", "US", p );
+ s.persist( a );
+ s.persist( p );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ p.getAddress().setStreetAddress( "321 Main" );
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ p = ( Person ) s.merge( p );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( 0 ); // no cascade
+ assertDeleteCount( 0 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.delete( a );
+ s.delete( p );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ }
+
+ public void testNoExtraUpdatesOnMerge() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Node node = new Node( "test" );
+ s.persist( node );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ // node is now detached, but we have made no changes. so attempt to merge it
+ // into this new session; this should cause no updates...
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ node = ( Node ) s.merge( node );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertUpdateCount( 0 );
+ assertInsertCount( 0 );
+
+ ///////////////////////////////////////////////////////////////////////
+ // as a control measure, now update the node while it is detached and
+ // make sure we get an update as a result...
+ node.setDescription( "new description" );
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ node = ( Node ) s.merge( node );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ assertUpdateCount( 1 );
+ assertInsertCount( 0 );
+ ///////////////////////////////////////////////////////////////////////
+
+ cleanup();
+ }
+
+ public void testNoExtraUpdatesOnMergeWithCollection() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Node parent = new Node( "parent" );
+ Node child = new Node( "child" );
+ parent.getChildren().add( child );
+ child.setParent( parent );
+ s.persist( parent );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ // parent is now detached, but we have made no changes. so attempt to merge it
+ // into this new session; this should cause no updates...
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ parent = ( Node ) s.merge( parent );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertUpdateCount( 0 );
+ assertInsertCount( 0 );
+
+ ///////////////////////////////////////////////////////////////////////
+ // as a control measure, now update the node while it is detached and
+ // make sure we get an update as a result...
+ ( ( Node ) parent.getChildren().iterator().next() ).setDescription( "child's new description" );
+ parent.addChild( new Node( "second child" ) );
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ parent = ( Node ) s.merge( parent );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ assertUpdateCount( 1 );
+ assertInsertCount( 1 );
+ ///////////////////////////////////////////////////////////////////////
+
+ cleanup();
+ }
+
+ public void testNoExtraUpdatesOnMergeVersioned() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ VersionedEntity entity = new VersionedEntity( "entity", "entity" );
+ s.persist( entity );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ // entity is now detached, but we have made no changes. so attempt to merge it
+ // into this new session; this should cause no updates...
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ VersionedEntity mergedEntity = ( VersionedEntity ) s.merge( entity );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ mergedEntity = ( VersionedEntity ) getOldToNewEntityRefMap().get( mergedEntity );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertUpdateCount( 0 );
+ assertInsertCount( 0 );
+ assertEquals( "unexpected version increment", entity.getVersion(), mergedEntity.getVersion() );
+
+
+ ///////////////////////////////////////////////////////////////////////
+ // as a control measure, now update the node while it is detached and
+ // make sure we get an update as a result...
+ entity.setName( "new name" );
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ entity = ( VersionedEntity ) s.merge( entity );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ assertUpdateCount( 1 );
+ assertInsertCount( 0 );
+ ///////////////////////////////////////////////////////////////////////
+
+ cleanup();
+ }
+
+ public void testNoExtraUpdatesOnMergeVersionedWithCollection() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ VersionedEntity parent = new VersionedEntity( "parent", "parent" );
+ VersionedEntity child = new VersionedEntity( "child", "child" );
+ parent.getChildren().add( child );
+ child.setParent( parent );
+ s.persist( parent );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ // parent is now detached, but we have made no changes. so attempt to merge it
+ // into this new session; this should cause no updates...
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ VersionedEntity mergedParent = ( VersionedEntity ) s.merge( parent );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ mergedParent = ( VersionedEntity ) getOldToNewEntityRefMap().get( mergedParent );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertUpdateCount( 0 );
+ assertInsertCount( 0 );
+ assertEquals( "unexpected parent version increment", parent.getVersion(), mergedParent.getVersion() );
+ VersionedEntity mergedChild = ( VersionedEntity ) mergedParent.getChildren().iterator().next();
+ assertEquals( "unexpected child version increment", child.getVersion(), mergedChild.getVersion() );
+
+ ///////////////////////////////////////////////////////////////////////
+ // as a control measure, now update the node while it is detached and
+ // make sure we get an update as a result...
+ mergedParent.setName( "new name" );
+ mergedParent.getChildren().add( new VersionedEntity( "child2", "new child" ) );
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ parent = ( VersionedEntity ) s.merge( mergedParent );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ parent = ( VersionedEntity ) getOldToNewEntityRefMap().get( parent );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ assertUpdateCount( 1 );
+ assertInsertCount( 1 );
+ ///////////////////////////////////////////////////////////////////////
+
+ cleanup();
+ }
+
+ public void testNoExtraUpdatesOnPersistentMergeVersionedWithCollection() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ VersionedEntity parent = new VersionedEntity( "parent", "parent" );
+ VersionedEntity child = new VersionedEntity( "child", "child" );
+ parent.getChildren().add( child );
+ child.setParent( parent );
+ s.persist( parent );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ // parent is now detached, but we have made no changes. so attempt to merge it
+ // into this new session; this should cause no updates...
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ // load parent so that merge will follow entityIsPersistent path
+ VersionedEntity persistentParent = ( VersionedEntity ) s.get( VersionedEntity.class, parent.getId() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ persistentParent = ( VersionedEntity ) getOldToNewEntityRefMap().get( persistentParent );
+ // load children
+ VersionedEntity persistentChild = ( VersionedEntity ) persistentParent.getChildren().iterator().next();
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ persistentParent = ( VersionedEntity ) getOldToNewEntityRefMap().get( persistentParent );
+ VersionedEntity mergedParent = ( VersionedEntity ) s.merge( persistentParent ); // <-- This merge leads to failure
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ mergedParent = ( VersionedEntity ) getOldToNewEntityRefMap().get( mergedParent );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertUpdateCount( 0 );
+ assertInsertCount( 0 );
+ assertEquals( "unexpected parent version increment", parent.getVersion(), mergedParent.getVersion() );
+ VersionedEntity mergedChild = ( VersionedEntity ) mergedParent.getChildren().iterator().next();
+ assertEquals( "unexpected child version increment", child.getVersion(), mergedChild.getVersion() );
+
+ ///////////////////////////////////////////////////////////////////////
+ // as a control measure, now update the node once it is loaded and
+ // make sure we get an update as a result...
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ persistentParent = ( VersionedEntity ) s.get( VersionedEntity.class, parent.getId() );
+ persistentParent.setName( "new name" );
+ persistentParent.getChildren().add( new VersionedEntity( "child2", "new child" ) );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ persistentParent = ( VersionedEntity ) getOldToNewEntityRefMap().get( persistentParent );
+ persistentParent = ( VersionedEntity ) s.merge( persistentParent );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ assertUpdateCount( 1 );
+ assertInsertCount( 1 );
+ ///////////////////////////////////////////////////////////////////////
+
+ // cleanup();
+ }
+
+ public void testPersistThenMergeInSameTxnWithVersion() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ VersionedEntity entity = new VersionedEntity( "test", "test" );
+ s.persist( entity );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ s.merge( new VersionedEntity( "test", "test-2" ) );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+
+ try {
+ // control operation...
+ s.saveOrUpdate( new VersionedEntity( "test", "test-3" ) );
+ fail( "saveOrUpdate() should fail here" );
+ }
+ catch ( NonUniqueObjectException expected ) {
+ // expected behavior
+ }
+
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ cleanup();
+ }
+
+ public void testPersistThenMergeInSameTxnWithTimestamp() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ TimestampedEntity entity = new TimestampedEntity( "test", "test" );
+ s.persist( entity );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ s.merge( new TimestampedEntity( "test", "test-2" ) );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+
+ try {
+ // control operation...
+ s.saveOrUpdate( new TimestampedEntity( "test", "test-3" ) );
+ fail( "saveOrUpdate() should fail here" );
+ }
+ catch ( NonUniqueObjectException expected ) {
+ // expected behavior
+ }
+
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ cleanup();
+ }
+
+ public void testMergeDeepTree() throws Exception {
+
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Node root = new Node( "root" );
+ Node child = new Node( "child" );
+ Node grandchild = new Node( "grandchild" );
+ root.addChild( child );
+ child.addChild( grandchild );
+ s.merge( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ grandchild.setDescription( "the grand child" );
+ Node grandchild2 = new Node( "grandchild2" );
+ child.addChild( grandchild2 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.merge( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 1 );
+ clearCounts();
+
+ Node child2 = new Node( "child2" );
+ Node grandchild3 = new Node( "grandchild3" );
+ child2.addChild( grandchild3 );
+ root.addChild( child2 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.merge( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.delete( grandchild );
+ s.delete( grandchild2 );
+ s.delete( grandchild3 );
+ s.delete( child );
+ s.delete( child2 );
+ s.delete( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ }
+
+ public void testMergeDeepTreeWithGeneratedId() throws Exception {
+
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ NumberedNode root = new NumberedNode( "root" );
+ NumberedNode child = new NumberedNode( "child" );
+ NumberedNode grandchild = new NumberedNode( "grandchild" );
+ root.addChild( child );
+ child.addChild( grandchild );
+ root = ( NumberedNode ) s.merge( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ child = ( NumberedNode ) root.getChildren().iterator().next();
+ grandchild = ( NumberedNode ) child.getChildren().iterator().next();
+ grandchild.setDescription( "the grand child" );
+ NumberedNode grandchild2 = new NumberedNode( "grandchild2" );
+ child.addChild( grandchild2 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ root = ( NumberedNode ) s.merge( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 1 );
+ clearCounts();
+
+ getSessions().evict( NumberedNode.class );
+
+ NumberedNode child2 = new NumberedNode( "child2" );
+ NumberedNode grandchild3 = new NumberedNode( "grandchild3" );
+ child2.addChild( grandchild3 );
+ root.addChild( child2 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ root = ( NumberedNode ) s.merge( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.createQuery( "delete from NumberedNode where name like 'grand%'" ).executeUpdate();
+ s.createQuery( "delete from NumberedNode where name like 'child%'" ).executeUpdate();
+ s.createQuery( "delete from NumberedNode" ).executeUpdate();
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ }
+
+ public void testMergeTree() throws Exception {
+
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Node root = new Node( "root" );
+ Node child = new Node( "child" );
+ root.addChild( child );
+ s.persist( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( Node ) getOldToNewEntityRefMap().get( root );
+ child = ( Node ) root.getChildren().iterator().next();
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 2 );
+ clearCounts();
+
+ root.setDescription( "The root node" );
+ child.setDescription( "The child node" );
+
+ Node secondChild = new Node( "second child" );
+
+ root.addChild( secondChild );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.merge( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 2 );
+
+ cleanup();
+ }
+
+ public void testMergeTreeWithGeneratedId() throws Exception {
+
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ NumberedNode root = new NumberedNode( "root" );
+ NumberedNode child = new NumberedNode( "child" );
+ root.addChild( child );
+ s.persist( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ child = ( NumberedNode ) root.getChildren().iterator().next();
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 2 );
+ clearCounts();
+
+ root.setDescription( "The root node" );
+ child.setDescription( "The child node" );
+
+ NumberedNode secondChild = new NumberedNode( "second child" );
+
+ root.addChild( secondChild );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.merge( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 2 );
+
+ cleanup();
+ }
+
+ public void testMergeManaged() throws Exception {
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ NumberedNode root = new NumberedNode( "root" );
+ s.persist( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ NumberedNode child = new NumberedNode( "child" );
+ root = ( NumberedNode ) s.merge( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ root.addChild( child );
+ assertSame( root, s.merge( root ) );
+ Object mergedChild = root.getChildren().iterator().next();
+ assertNotSame( mergedChild, child );
+ assertTrue( s.contains( mergedChild ) );
+ assertFalse( s.contains( child ) );
+ assertEquals( root.getChildren().size(), 1 );
+ assertTrue( root.getChildren().contains( mergedChild ) );
+ //assertNotSame( mergedChild, s.merge(child) ); //yucky :(
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ mergedChild = root.getChildren().iterator().next();
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 0 );
+
+ assertEquals( root.getChildren().size(), 1 );
+ assertTrue( root.getChildren().contains( mergedChild ) );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ assertEquals(
+ s.createCriteria( NumberedNode.class )
+ .setProjection( Projections.rowCount() )
+ .uniqueResult(),
+ new Long( 2 )
+ );
+
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ cleanup();
+ }
+
+ public void testMergeManagedUninitializedCollection() throws Exception {
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ NumberedNode root = new NumberedNode( "root" );
+ root.addChild( new NumberedNode( "child" ) );
+ s.persist( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ NumberedNode newRoot = new NumberedNode( "root" );
+ newRoot.setId( root.getId() );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ root = ( NumberedNode ) s.get( NumberedNode.class, root.getId() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ Set managedChildren = root.getChildren();
+ assertFalse( Hibernate.isInitialized( managedChildren ) );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ managedChildren = root.getChildren();
+ newRoot.setChildren( managedChildren );
+ assertSame( root, s.merge( newRoot ) );
+ assertSame( managedChildren, root.getChildren() );
+ assertFalse( Hibernate.isInitialized( managedChildren ) );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( 0 );
+ assertDeleteCount( 0 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ assertEquals(
+ s.createCriteria( NumberedNode.class )
+ .setProjection( Projections.rowCount() )
+ .uniqueResult(),
+ new Long( 2 )
+ );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ cleanup();
+ }
+
+ public void testMergeManagedInitializedCollection() throws Exception {
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ NumberedNode root = new NumberedNode( "root" );
+ root.addChild( new NumberedNode( "child" ) );
+ s.persist( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ NumberedNode newRoot = new NumberedNode( "root" );
+ newRoot.setId( root.getId() );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ root = ( NumberedNode ) s.get( NumberedNode.class, root.getId() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ Set managedChildren = root.getChildren();
+ Hibernate.initialize( managedChildren );
+ assertTrue( Hibernate.isInitialized( managedChildren ) );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ managedChildren = root.getChildren();
+ newRoot.setChildren( managedChildren );
+ assertSame( root, s.merge( newRoot ) );
+ assertSame( managedChildren, root.getChildren() );
+ assertTrue( Hibernate.isInitialized( managedChildren ) );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( 0 );
+ assertDeleteCount( 0 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ assertEquals(
+ s.createCriteria( NumberedNode.class )
+ .setProjection( Projections.rowCount() )
+ .uniqueResult(),
+ new Long( 2 )
+ );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ cleanup();
+ }
+
+ public void testRecursiveMergeTransient() throws Exception {
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Employer jboss = new Employer();
+ Employee gavin = new Employee();
+ jboss.setEmployees( new ArrayList() );
+ jboss.getEmployees().add( gavin );
+ s.merge( jboss );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ s.flush();
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ jboss = ( Employer ) s.createQuery( "from Employer e join fetch e.employees" ).uniqueResult();
+ assertTrue( Hibernate.isInitialized( jboss.getEmployees() ) );
+ assertEquals( 1, jboss.getEmployees().size() );
+ s.clear();
+ s.merge( jboss.getEmployees().iterator().next() );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ cleanup();
+ }
+
+ public void testDeleteAndMerge() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Employer jboss = new Employer();
+ s.persist( jboss );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ Employer otherJboss;
+ otherJboss = ( Employer ) s.get( Employer.class, jboss.getId() );
+ s.delete( otherJboss );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ jboss.setVers( new Integer( 1 ) );
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.merge( jboss );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ cleanup();
+ }
+
+ public void testMergeManyToManyWithCollectionDeference() throws Exception {
+ // setup base data...
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Competition competition = new Competition();
+ competition.getCompetitors().add( new Competitor( "Name" ) );
+ competition.getCompetitors().add( new Competitor() );
+ competition.getCompetitors().add( new Competitor() );
+ s.persist( competition );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ // the competition graph is now detached:
+ // 1) create a new List reference to represent the competitors
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ List newComp = new ArrayList();
+ Competitor originalCompetitor = ( Competitor ) competition.getCompetitors().get( 0 );
+ originalCompetitor.setName( "Name2" );
+ newComp.add( originalCompetitor );
+ newComp.add( new Competitor() );
+ // 2) set that new List reference unto the Competition reference
+ competition.setCompetitors( newComp );
+ // 3) attempt the merge
+ Competition competition2 = ( Competition ) s.merge( competition );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ Competition competition2copy = ( Competition ) getOldToNewEntityRefMap().get( competition2 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertFalse( competition == competition2 );
+ assertFalse( competition2 == competition2copy );
+ assertFalse( competition.getCompetitors() == competition2.getCompetitors() );
+ assertEquals( 2, competition2.getCompetitors().size() );
+ assertEquals( 2, competition2copy.getCompetitors().size() );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ competition = ( Competition ) s.get( Competition.class, competition.getId() );
+ assertEquals( 2, competition.getCompetitors().size() );
+ s.delete( competition );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ cleanup();
+ }
+
+ private void cleanup() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ s.createQuery( "delete from NumberedNode where parent is not null" ).executeUpdate();
+ s.createQuery( "delete from NumberedNode" ).executeUpdate();
+
+ s.createQuery( "delete from Node where parent is not null" ).executeUpdate();
+ s.createQuery( "delete from Node" ).executeUpdate();
+
+ s.createQuery( "delete from VersionedEntity where parent is not null" ).executeUpdate();
+ s.createQuery( "delete from VersionedEntity" ).executeUpdate();
+ s.createQuery( "delete from TimestampedEntity" ).executeUpdate();
+
+ s.createQuery( "delete from Competitor" ).executeUpdate();
+ s.createQuery( "delete from Competition" ).executeUpdate();
+
+ Iterator itr = s.createQuery( "from Employer" ).list().iterator();
+ while ( itr.hasNext() ) {
+ final Employer employer = ( Employer ) itr.next();
+ s.delete( employer );
+ }
+
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ }
+}
+
Property changes on: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/MergeTest.java
___________________________________________________________________
Name: svn:executable
+ *
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.hbm.xml 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.nonflushedchanges">
+
+ <class name="Node" polymorphism="explicit">
+ <id name="name">
+ <generator class="assigned"/>
+ </id>
+ <property name="description"/>
+ <many-to-one name="parent"/>
+ <property name="created" not-null="true"/>
+ <set name="children"
+ inverse="true"
+ cascade="persist,merge,save-update,evict">
+ <key column="parent"/>
+ <one-to-many class="Node"/>
+ </set>
+ <set name="cascadingChildren" inverse="false" cascade="persist,merge,save-update,evict,delete">
+ <key column="CASC_PARENT"/>
+ <one-to-many class="Node"/>
+ </set>
+ </class>
+
+ <class name="NumberedNode" polymorphism="explicit">
+ <id name="id" unsaved-value="0">
+ <generator class="native"/>
+ </id>
+ <property name="name">
+ <column name="name" index="iname" not-null="true"/>
+ </property>
+ <property name="description"/>
+ <property name="created" not-null="true"
+ type="imm_date"/>
+ <many-to-one name="parent" class="NumberedNode"/>
+ <set name="children"
+ inverse="true"
+ cascade="persist,merge,save-update">
+ <key column="parent"/>
+ <one-to-many class="NumberedNode"/>
+ </set>
+ </class>
+
+</hibernate-mapping>
+
Property changes on: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.hbm.xml
___________________________________________________________________
Name: svn:executable
+ *
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,89 @@
+//$Id: Node.java 10759 2006-11-08 00:00:53Z steve.ebersole(a)jboss.com $
+package org.hibernate.test.nonflushedchanges;
+
+import java.io.Serializable;
+import java.sql.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Gavin King, Gail Badner (adapted this from "ops" tests version)
+ */
+public class Node implements Serializable {
+
+ private String name;
+ private String description;
+ private Date created;
+ private Node parent;
+ private Set children = new HashSet();
+ private Set cascadingChildren = new HashSet();
+
+ public Node() {
+ }
+
+ public Node(String name) {
+ this.name = name;
+ created = generateCurrentDate();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Date getCreated() {
+ return created;
+ }
+
+ public void setCreated(Date created) {
+ this.created = created;
+ }
+
+ public Node getParent() {
+ return parent;
+ }
+
+ public void setParent(Node parent) {
+ this.parent = parent;
+ }
+
+ public Set getChildren() {
+ return children;
+ }
+
+ public void setChildren(Set children) {
+ this.children = children;
+ }
+
+ public Node addChild(Node child) {
+ children.add( child );
+ child.setParent( this );
+ return this;
+ }
+
+ public Set getCascadingChildren() {
+ return cascadingChildren;
+ }
+
+ public void setCascadingChildren(Set cascadingChildren) {
+ this.cascadingChildren = cascadingChildren;
+ }
+
+ private Date generateCurrentDate() {
+ // Note : done as java.sql.Date mainly to work around issue with
+ // MySQL and its lack of milli-second precision on its DATETIME
+ // and TIMESTAMP datatypes.
+ return new Date( new java.util.Date().getTime() );
+ }
+}
Property changes on: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.java
___________________________________________________________________
Name: svn:executable
+ *
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/NumberedNode.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/NumberedNode.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/NumberedNode.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,83 @@
+//$Id: NumberedNode.java 7236 2005-06-20 03:19:34Z oneovthafew $
+package org.hibernate.test.nonflushedchanges;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Gavin King, Gail Badner (adapted this from "ops" tests version)
+ */
+public class NumberedNode implements Serializable {
+
+ private long id;
+ private String name;
+ private NumberedNode parent;
+ private Set children = new HashSet();
+ private String description;
+ private Date created;
+
+ public NumberedNode() {
+ super();
+ }
+
+ public NumberedNode(String name) {
+ this.name = name;
+ created = new Date();
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public Set getChildren() {
+ return children;
+ }
+
+ public void setChildren(Set children) {
+ this.children = children;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public NumberedNode getParent() {
+ return parent;
+ }
+
+ public void setParent(NumberedNode parent) {
+ this.parent = parent;
+ }
+
+ public NumberedNode addChild(NumberedNode child) {
+ children.add( child );
+ child.setParent( this );
+ return this;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Date getCreated() {
+ return created;
+ }
+
+ public void setCreated(Date created) {
+ this.created = created;
+ }
+}
Property changes on: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/NumberedNode.java
___________________________________________________________________
Name: svn:executable
+ *
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OneToOne.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OneToOne.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OneToOne.hbm.xml 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+ Mappings demonstrating bidirectional one-to-one mappings for testing
+ with various operations.
+
+ Person -> Address is modeled as a bidirectional one to one based on FK.
+ Person -> Details is modeled as a bidirectional one to one based on PK.
+-->
+
+<hibernate-mapping package="org.hibernate.test.nonflushedchanges">
+
+ <class name="Person" table="OPS_PERSON">
+ <id name="id" column="ID" type="long">
+ <generator class="increment"/>
+ </id>
+ <property name="name" column="NAME" type="string"/>
+ <one-to-one name="address" class="Address" property-ref="resident"/>
+ <one-to-one name="details" class="PersonalDetails" cascade="all"/>
+ </class>
+
+ <class name="Address" table="OPS_ADDRESS">
+ <id name="id" column="ID" type="long">
+ <generator class="increment"/>
+ </id>
+ <property name="streetAddress" column="STREET" type="string"/>
+ <property name="city" column="CITY" type="string"/>
+ <property name="country" column="CTRY" type="string"/>
+ <many-to-one name="resident" column="RESIDENT" class="Person"/>
+ </class>
+
+ <class name="PersonalDetails" table="OPS_PERS_DETAIL">
+ <id name="id" column="ID" type="long">
+ <generator class="increment"/>
+ </id>
+ <property name="somePersonalDetail" column="SOME_DETAIL" type="string"/>
+ <one-to-one name="person" class="Person" cascade="none" constrained="true"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OptLockEntity.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OptLockEntity.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OptLockEntity.hbm.xml 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.nonflushedchanges">
+
+ <class name="VersionedEntity" table="V_ENTITY">
+ <id name="id" column="ID" type="string">
+ <generator class="assigned"/>
+ </id>
+ <version name="version" column="VERS" type="long"/>
+ <property name="name" column="NAME" type="string"/>
+ <many-to-one name="parent" class="VersionedEntity"/>
+ <set name="children"
+ inverse="true"
+ cascade="persist,merge,save-update,evict,delete">
+ <key column="parent"/>
+ <one-to-many class="VersionedEntity"/>
+ </set>
+ </class>
+
+ <class name="TimestampedEntity" table="T_ENTITY">
+ <id name="id" column="ID" type="string">
+ <generator class="assigned"/>
+ </id>
+ <timestamp name="timestamp" column="TS"/>
+ <property name="name" column="NAME" type="string"/>
+ </class>
+
+</hibernate-mapping>
+
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Person.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Person.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Person.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,54 @@
+package org.hibernate.test.nonflushedchanges;
+
+import java.io.Serializable;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
+ */
+public class Person implements Serializable {
+ private Long id;
+ private String name;
+ private Address address;
+ private PersonalDetails details;
+
+ public Person() {
+ }
+
+ public Person(String name) {
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+
+ public PersonalDetails getDetails() {
+ return details;
+ }
+
+ public void setDetails(PersonalDetails details) {
+ this.details = details;
+ }
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/PersonalDetails.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/PersonalDetails.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/PersonalDetails.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,47 @@
+package org.hibernate.test.nonflushedchanges;
+
+import java.io.Serializable;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
+ */
+public class PersonalDetails implements Serializable {
+ private Long id;
+ private String somePersonalDetail;
+ private Person person;
+
+ public PersonalDetails() {
+ }
+
+ public PersonalDetails(String somePersonalDetail, Person person) {
+ this.somePersonalDetail = somePersonalDetail;
+ this.person = person;
+ person.setDetails( this );
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getSomePersonalDetail() {
+ return somePersonalDetail;
+ }
+
+ public void setSomePersonalDetail(String somePersonalDetail) {
+ this.somePersonalDetail = somePersonalDetail;
+ }
+
+ public Person getPerson() {
+ return person;
+ }
+
+ public void setPerson(Person person) {
+ this.person = person;
+ }
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/SaveOrUpdateTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/SaveOrUpdateTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/SaveOrUpdateTest.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,492 @@
+//$Id: SaveOrUpdateTest.java 10977 2006-12-12 23:28:04Z steve.ebersole(a)jboss.com $
+package org.hibernate.test.nonflushedchanges;
+
+import junit.framework.Test;
+
+import org.hibernate.Hibernate;
+import org.hibernate.Session;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.criterion.Projections;
+import org.hibernate.intercept.FieldInterceptionHelper;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.test.tm.SimpleJtaTransactionManagerImpl;
+
+/**
+ * @author Gavin King, Gail Badner (adapted this from "ops" tests version)
+ */
+public class SaveOrUpdateTest extends AbstractOperationTestCase {
+
+ public SaveOrUpdateTest(String str) {
+ super( str );
+ }
+
+ public void testSaveOrUpdateDeepTree() throws Exception {
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Node root = new Node( "root" );
+ Node child = new Node( "child" );
+ Node grandchild = new Node( "grandchild" );
+ root.addChild( child );
+ child.addChild( grandchild );
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( Node ) getOldToNewEntityRefMap().get( root );
+ child = ( Node ) getOldToNewEntityRefMap().get( child );
+ grandchild = ( Node ) getOldToNewEntityRefMap().get( grandchild );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ grandchild.setDescription( "the grand child" );
+ Node grandchild2 = new Node( "grandchild2" );
+ child.addChild( grandchild2 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( Node ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 1 );
+ clearCounts();
+
+ Node child2 = new Node( "child2" );
+ Node grandchild3 = new Node( "grandchild3" );
+ child2.addChild( grandchild3 );
+ root.addChild( child2 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.delete( grandchild );
+ s.delete( grandchild2 );
+ s.delete( grandchild3 );
+ s.delete( child );
+ s.delete( child2 );
+ s.delete( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ }
+
+ public void testSaveOrUpdateDeepTreeWithGeneratedId() throws Exception {
+ boolean instrumented = FieldInterceptionHelper.isInstrumented( new NumberedNode() );
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ NumberedNode root = new NumberedNode( "root" );
+ NumberedNode child = new NumberedNode( "child" );
+ NumberedNode grandchild = new NumberedNode( "grandchild" );
+ root.addChild( child );
+ child.addChild( grandchild );
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ child = ( NumberedNode ) getOldToNewEntityRefMap().get( child );
+ grandchild = ( NumberedNode ) getOldToNewEntityRefMap().get( grandchild );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ child = ( NumberedNode ) root.getChildren().iterator().next();
+ grandchild = ( NumberedNode ) child.getChildren().iterator().next();
+ grandchild.setDescription( "the grand child" );
+ NumberedNode grandchild2 = new NumberedNode( "grandchild2" );
+ child.addChild( grandchild2 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( instrumented ? 1 : 3 );
+ clearCounts();
+
+ NumberedNode child2 = new NumberedNode( "child2" );
+ NumberedNode grandchild3 = new NumberedNode( "grandchild3" );
+ child2.addChild( grandchild3 );
+ root.addChild( child2 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( instrumented ? 0 : 4 );
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.createQuery( "delete from NumberedNode where name like 'grand%'" ).executeUpdate();
+ s.createQuery( "delete from NumberedNode where name like 'child%'" ).executeUpdate();
+ s.createQuery( "delete from NumberedNode" ).executeUpdate();
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ }
+
+ public void testSaveOrUpdateTree() throws Exception {
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Node root = new Node( "root" );
+ Node child = new Node( "child" );
+ root.addChild( child );
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( Node ) getOldToNewEntityRefMap().get( root );
+ child = ( Node ) getOldToNewEntityRefMap().get( child );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 2 );
+ clearCounts();
+
+ root.setDescription( "The root node" );
+ child.setDescription( "The child node" );
+
+ Node secondChild = new Node( "second child" );
+
+ root.addChild( secondChild );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 2 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.createQuery( "delete from Node where parent is not null" ).executeUpdate();
+ s.createQuery( "delete from Node" ).executeUpdate();
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ }
+
+ public void testSaveOrUpdateTreeWithGeneratedId() throws Exception {
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ NumberedNode root = new NumberedNode( "root" );
+ NumberedNode child = new NumberedNode( "child" );
+ root.addChild( child );
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ child = ( NumberedNode ) getOldToNewEntityRefMap().get( child );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 2 );
+ clearCounts();
+
+ root.setDescription( "The root node" );
+ child.setDescription( "The child node" );
+
+ NumberedNode secondChild = new NumberedNode( "second child" );
+
+ root.addChild( secondChild );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 2 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.createQuery( "delete from NumberedNode where parent is not null" ).executeUpdate();
+ s.createQuery( "delete from NumberedNode" ).executeUpdate();
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ }
+
+ public void testSaveOrUpdateManaged() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ NumberedNode root = new NumberedNode( "root" );
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ root = ( NumberedNode ) s.get( NumberedNode.class, root.getId() );
+ NumberedNode child = new NumberedNode( "child" );
+ root.addChild( child );
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ assertNull( getOldToNewEntityRefMap().get( child ) );
+ s.flush();
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ child = ( NumberedNode ) getOldToNewEntityRefMap().get( child );
+ child = ( NumberedNode ) root.getChildren().iterator().next();
+ assertTrue( s.contains( child ) );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ child = ( NumberedNode ) getOldToNewEntityRefMap().get( child );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertTrue( root.getChildren().contains( child ) );
+ assertEquals( root.getChildren().size(), 1 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ assertEquals(
+ s.createCriteria( NumberedNode.class )
+ .setProjection( Projections.rowCount() )
+ .uniqueResult(),
+ new Long( 2 )
+ );
+ s.delete( root );
+ s.delete( child );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ }
+
+
+ public void testSaveOrUpdateGot() throws Exception {
+ boolean instrumented = FieldInterceptionHelper.isInstrumented( new NumberedNode() );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ NumberedNode root = new NumberedNode( "root" );
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( instrumented ? 0 : 1 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ root = ( NumberedNode ) s.get( NumberedNode.class, new Long( root.getId() ) );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ Hibernate.initialize( root.getChildren() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ NumberedNode child = new NumberedNode( "child" );
+ root.addChild( child );
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
+ assertTrue( Hibernate.isInitialized( root.getChildren() ) );
+ child = ( NumberedNode ) root.getChildren().iterator().next();
+ assertTrue( s.contains( child ) );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( instrumented ? 0 : 1 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ assertEquals(
+ s.createCriteria( NumberedNode.class )
+ .setProjection( Projections.rowCount() )
+ .uniqueResult(),
+ new Long( 2 )
+ );
+ s.delete( root );
+ s.delete( child );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ }
+
+ public void testSaveOrUpdateGotWithMutableProp() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Node root = new Node( "root" );
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( Node ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( Node ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( 0 );
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ root = ( Node ) s.get( Node.class, "root" );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( Node ) getOldToNewEntityRefMap().get( root );
+ Hibernate.initialize( root.getChildren() );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( Node ) getOldToNewEntityRefMap().get( root );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ clearCounts();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ Node child = new Node( "child" );
+ root.addChild( child );
+ s.saveOrUpdate( root );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( Node ) getOldToNewEntityRefMap().get( root );
+ child = ( Node ) root.getChildren().iterator().next();
+ assertTrue( s.contains( child ) );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ root = ( Node ) getOldToNewEntityRefMap().get( root );
+ child = ( Node ) getOldToNewEntityRefMap().get( child );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ assertInsertCount( 1 );
+ //assertUpdateCount( 1 ); //note: will fail here if no second-level cache
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ assertEquals(
+ s.createCriteria( Node.class )
+ .setProjection( Projections.rowCount() )
+ .uniqueResult(),
+ new Long( 2 )
+ );
+ s.delete( root );
+ s.delete( child );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ }
+
+ public void testEvictThenSaveOrUpdate() throws Exception {
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s = openSession();
+ Node parent = new Node( "1:parent" );
+ Node child = new Node( "2:child" );
+ Node grandchild = new Node( "3:grandchild" );
+ parent.addChild( child );
+ child.addChild( grandchild );
+ s.saveOrUpdate( parent );
+ s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s1 = openSession();
+ child = ( Node ) s1.load( Node.class, "2:child" );
+ s1 = applyNonFlushedChangesToNewSessionCloseOldSession( s1 );
+ child = ( Node ) getOldToNewEntityRefMap().get( child );
+ assertTrue( s1.contains( child ) );
+ assertFalse( Hibernate.isInitialized( child ) );
+ assertTrue( s1.contains( child.getParent() ) );
+ assertTrue( Hibernate.isInitialized( child ) );
+ assertFalse( Hibernate.isInitialized( child.getChildren() ) );
+ assertFalse( Hibernate.isInitialized( child.getParent() ) );
+ assertTrue( s1.contains( child ) );
+ s1 = applyNonFlushedChangesToNewSessionCloseOldSession( s1 );
+ // child is an initialized proxy; after serialization, it is
+ // the proxy is replaced by its implementation
+ // TODO: find out if this is how this should work...
+ child = ( Node ) getOldToNewEntityRefMap().get(
+ ( ( HibernateProxy ) child ).getHibernateLazyInitializer().getImplementation()
+ );
+ s1.evict( child );
+ assertFalse( s1.contains( child ) );
+ assertTrue( s1.contains( child.getParent() ) );
+
+ javax.transaction.Transaction tx1 = SimpleJtaTransactionManagerImpl.getInstance().suspend();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ Session s2 = openSession();
+ s2.saveOrUpdate( child );
+ s2 = applyNonFlushedChangesToNewSessionCloseOldSession( s2 );
+ child = ( Node ) getOldToNewEntityRefMap().get( child );
+ assertTrue( s2.contains( child ) );
+ assertFalse( s1.contains( child ) );
+ assertTrue( s2.contains( child.getParent() ) );
+ assertFalse( s1.contains( child.getParent() ) );
+ assertFalse( Hibernate.isInitialized( child.getChildren() ) );
+ assertFalse( Hibernate.isInitialized( child.getParent() ) );
+ assertEquals( 1, child.getChildren().size() );
+ assertEquals( "1:parent", child.getParent().getName() );
+ assertTrue( Hibernate.isInitialized( child.getChildren() ) );
+ assertFalse( Hibernate.isInitialized( child.getParent() ) );
+ assertNull( child.getParent().getDescription() );
+ assertTrue( Hibernate.isInitialized( child.getParent() ) );
+ s1 = applyNonFlushedChangesToNewSessionCloseOldSession( s1 );
+ s2 = applyNonFlushedChangesToNewSessionCloseOldSession( s2 );
+
+ javax.transaction.Transaction tx2 = SimpleJtaTransactionManagerImpl.getInstance().suspend();
+ SimpleJtaTransactionManagerImpl.getInstance().resume( tx1 );
+ tx1.commit();
+
+ SimpleJtaTransactionManagerImpl.getInstance().resume( tx2 );
+ tx2.commit();
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ s = openSession();
+ s.delete( s.get( Node.class, "3:grandchild" ) );
+ s.delete( s.get( Node.class, "2:child" ) );
+ s.delete( s.get( Node.class, "1:parent" ) );
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ }
+
+ public void configure(Configuration cfg) {
+ super.configure( cfg );
+ cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
+ cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "nonflushedchanges/Node.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( SaveOrUpdateTest.class );
+ }
+
+}
+
Property changes on: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/SaveOrUpdateTest.java
___________________________________________________________________
Name: svn:executable
+ *
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/TimestampedEntity.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/TimestampedEntity.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/TimestampedEntity.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,48 @@
+package org.hibernate.test.nonflushedchanges;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * todo: describe TimestampedEntity
+ *
+ * @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
+ */
+public class TimestampedEntity implements Serializable {
+ private String id;
+ private String name;
+ private Date timestamp;
+
+ public TimestampedEntity() {
+ }
+
+ public TimestampedEntity(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Date getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(Date timestamp) {
+ this.timestamp = timestamp;
+ }
+}
+
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/VersionedEntity.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/VersionedEntity.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/VersionedEntity.java 2009-11-17 23:17:25 UTC (rev 17998)
@@ -0,0 +1,67 @@
+package org.hibernate.test.nonflushedchanges;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * VersionedEntity
+ *
+ * @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
+ */
+public class VersionedEntity implements Serializable {
+ private String id;
+ private String name;
+ private long version;
+
+ private VersionedEntity parent;
+ private Set children = new HashSet();
+
+ public VersionedEntity() {
+ }
+
+ public VersionedEntity(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+
+ public VersionedEntity getParent() {
+ return parent;
+ }
+
+ public void setParent(VersionedEntity parent) {
+ this.parent = parent;
+ }
+
+ public Set getChildren() {
+ return children;
+ }
+
+ public void setChildren(Set children) {
+ this.children = children;
+ }
+}
14 years, 7 months
Hibernate SVN: r17997 - core/trunk/core/src/main/java/org/hibernate/engine.
by hibernate-commits@lists.jboss.org
Author: gbadner
Date: 2009-11-17 18:12:09 -0500 (Tue, 17 Nov 2009)
New Revision: 17997
Modified:
core/trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java
Log:
HHH-2762 : Added StatefulPersistenceContext.getProxiesByKey() (needed for testing non-flushed changes)
Modified: core/trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java 2009-11-17 18:00:05 UTC (rev 17996)
+++ core/trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java 2009-11-17 23:12:09 UTC (rev 17997)
@@ -997,6 +997,10 @@
return entitiesByKey;
}
+ public Map getProxiesByKey() {
+ return proxiesByKey;
+ }
+
public Map getEntityEntries() {
return entityEntries;
}
14 years, 7 months
Hibernate SVN: r17996 - in search/trunk/src/main: java/org/hibernate/search/backend/impl/jgroups and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2009-11-17 13:00:05 -0500 (Tue, 17 Nov 2009)
New Revision: 17996
Modified:
search/trunk/src/main/docbook/en-US/modules/architecture.xml
search/trunk/src/main/docbook/en-US/modules/configuration.xml
search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessorFactory.java
Log:
HSEARCH-409 Write documentation for JGroups based configuration (Lukasz Moren)
Modified: search/trunk/src/main/docbook/en-US/modules/architecture.xml
===================================================================
--- search/trunk/src/main/docbook/en-US/modules/architecture.xml 2009-11-17 09:07:29 UTC (rev 17995)
+++ search/trunk/src/main/docbook/en-US/modules/architecture.xml 2009-11-17 18:00:05 UTC (rev 17996)
@@ -174,6 +174,15 @@
local copy of the index.</para>
</section>
+ <section>
+ <title>JGroups</title>
+
+ <para>The JGroups based back end works similarly as the JMS one. Designed on the same
+ master/slave pattern, instead of JMS the JGroups toolkit is used as a replication mechanism.
+ This back end can be used as an alternative to JMS one when response time is still critical,
+ but i.e. JNDI service is not available.</para>
+ </section>
+
<note>Hibernate Search is an extensible architecture. Feel free to drop
ideas for other third party back ends to
<literal>hibernate-dev(a)lists.jboss.org</literal>.</note>
Modified: search/trunk/src/main/docbook/en-US/modules/configuration.xml
===================================================================
--- search/trunk/src/main/docbook/en-US/modules/configuration.xml 2009-11-17 09:07:29 UTC (rev 17995)
+++ search/trunk/src/main/docbook/en-US/modules/configuration.xml 2009-11-17 18:00:05 UTC (rev 17996)
@@ -390,8 +390,8 @@
<entry>Out of the box support for the Apache Lucene back end and
the JMS back end. Default to <literal>lucene</literal>. Supports
- also <literal>jms</literal> and
- <literal>blackhole</literal>.</entry>
+ also <literal>jms</literal>, <literal>blackhole</literal>,
+ <literal>jgroupsMaster</literal> and <literal>jgroupsSlave</literal>.</entry>
</row>
<row>
@@ -442,6 +442,34 @@
lookup the JMS queue from. The queue will be used to post work
messages.</entry>
</row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.jgroups.clusterName</literal></entry>
+
+ <entry>Optional for JGroups back end. Defines the name of JGroups channel.</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.jgroups.configurationFile</literal></entry>
+
+ <entry>Optional JGroups network stack configuration. Defines the name of a JGroups
+ configuration file, which must exist on classpath.</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.jgroups.configurationXml</literal></entry>
+
+ <entry>Optional JGroups network stack configuration.
+ Defines a String representing JGroups configuration as XML.</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.jgroups.configurationString</literal></entry>
+
+ <entry>Optional JGroups network stack configuration.
+ Provides JGroups configuration in plain text.</entry>
+ </row>
+
</tbody>
</tgroup>
</table>
@@ -578,6 +606,102 @@
</section>
</section>
+ <section id="jgroups-backend">
+ <title>JGroups Master/Slave configuration</title>
+ <para>Describes how to configure JGroups Master/Slave back end.
+ Configuration examples illustrated in JMS Master/Slave configuration
+ section (<xref linkend="jms-backend" />) also apply here, only
+ a different backend needs to be set.
+ </para>
+ <section>
+ <title>Slave nodes</title>
+ <para>Every index update operation is sent through a JGroups channel to the master node. Index
+ querying operations are executed on a local index copy.
+ </para>
+ <example><title>JGroups Slave configuration</title>
+ <programlisting>
+### slave configuration
+## Backend configuration
+hibernate.search.worker.backend = jgroupsSlave
+ </programlisting>
+ </example>
+ </section>
+
+ <section>
+ <title>Master node</title>
+ <para>Every index update operation is taken from a JGroups channel and
+ executed. The master index is copied on a regular basis.
+ </para>
+ <example><title>JGroups Master configuration</title>
+ <programlisting>
+### master configuration
+## Backend configuration
+hibernate.search.worker.backend = jgroupsMaster
+ </programlisting>
+ </example>
+ </section>
+ <section>
+ <title>JGroups channel configuration</title>
+ <para>Optionally configuration for JGroups transport protocols
+ (UDP, TCP) and channel name can be defined. It can be applied to both master and slave nodes.
+ There are several ways to configure JGroups transport details.
+ If it is not defined explicity, configuration found in the <literal>
+ flush-udp.xml</literal> file is used.</para>
+ <example><title>JGroups transport protocols configuration</title>
+ <programlisting>
+## configuration
+#udp.xml file needs to be located in the classpath
+hibernate.search.worker.backend.jgroups.configurationFile = udp.xml
+
+#protocol stack configuration provided in XML format
+hibernate.search.worker.backend.jgroups.configurationXml =
+
+<config xmlns="urn:org:jgroups"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="urn:org:jgroups file:schema/JGroups-2.8.xsd">
+<UDP
+mcast_addr="${jgroups.udp.mcast_addr:228.10.10.10}"
+mcast_port="${jgroups.udp.mcast_port:45588}"
+tos="8"
+thread_naming_pattern="pl"
+thread_pool.enabled="true"
+thread_pool.min_threads="2"
+thread_pool.max_threads="8"
+thread_pool.keep_alive_time="5000"
+thread_pool.queue_enabled="false"
+thread_pool.queue_max_size="100"
+thread_pool.rejection_policy="Run"/>
+<PING timeout="1000" num_initial_members="3"/>
+<MERGE2 max_interval="30000" min_interval="10000"/>
+<FD_SOCK/>
+<FD timeout="3000" max_tries="3"/>
+<VERIFY_SUSPECT timeout="1500"/>
+<pbcast.STREAMING_STATE_TRANSFER/>
+<pbcast.FLUSH timeout="0"/>
+</config>
+
+#protocol stack configuration provided in "old style" jgroups format
+hibernate.search.worker.backend.jgroups.configurationString =
+
+UDP(mcast_addr=228.1.2.3;mcast_port=45566;ip_ttl=32):PING(timeout=3000;
+num_initial_members=6):FD(timeout=5000):VERIFY_SUSPECT(timeout=1500):
+pbcast.NAKACK(gc_lag=10;retransmit_timeout=3000):UNICAST(timeout=5000):
+FRAG:pbcast.GMS(join_timeout=3000;shun=false;print_local_addr=true)
+
+ </programlisting>
+ </example>
+ <para>Master and slave nodes communicate over JGroups channel
+ that is identified by this same name. Name of the channel can be defined
+ explicity, if not default <literal>HSearchCluster</literal> is used.</para>
+ <example><title>JGroups channel name configuration</title>
+ <programlisting>
+## Backend configuration
+hibernate.search.worker.backend.jgroups.clusterName = Hibernate-Search-Cluster
+ </programlisting>
+ </example>
+ </section>
+ </section>
+
<section id="configuration-reader-strategy">
<title>Reader strategy configuration</title>
Modified: search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessorFactory.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessorFactory.java 2009-11-17 09:07:29 UTC (rev 17995)
+++ search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessorFactory.java 2009-11-17 18:00:05 UTC (rev 17996)
@@ -97,11 +97,11 @@
}
/**
- * Reads congiguration and builds channnel with its base.
+ * Reads configuration and builds channnel with its base.
* In order of preference - we first look for an external JGroups file, then a set of XML properties, and
* finally the legacy JGroups String properties.
*
- * @param props configuratuion file
+ * @param props configuration file
*/
private void buildChannel(Properties props) {
String cfg;
14 years, 7 months