Hibernate SVN: r18960 - in jpamodelgen/trunk: src/main/docbook/en-US and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2010-03-10 09:37:41 -0500 (Wed, 10 Mar 2010)
New Revision: 18960
Modified:
jpamodelgen/trunk/pom.xml
jpamodelgen/trunk/readme.txt
jpamodelgen/trunk/src/main/docbook/en-US/master.xml
Log:
METAGEN-26 Updated readme and docbook sources
Modified: jpamodelgen/trunk/pom.xml
===================================================================
--- jpamodelgen/trunk/pom.xml 2010-03-10 14:28:56 UTC (rev 18959)
+++ jpamodelgen/trunk/pom.xml 2010-03-10 14:37:41 UTC (rev 18960)
@@ -6,7 +6,7 @@
<artifactId>hibernate-jpamodelgen</artifactId>
<version>1.0.0-SNAPSHOT</version>
- <name>JPA 2 Static-Metamodel Generator</name>
+ <name>Hibernate JPA 2 Metamodel Generator</name>
<description>Annotation Processor to generate JPA 2 static metamodel classes</description>
<inceptionYear>2009</inceptionYear>
Modified: jpamodelgen/trunk/readme.txt
===================================================================
--- jpamodelgen/trunk/readme.txt 2010-03-10 14:28:56 UTC (rev 18959)
+++ jpamodelgen/trunk/readme.txt 2010-03-10 14:37:41 UTC (rev 18960)
@@ -1,4 +1,4 @@
- Hibernate JPA2 Metamodel Generator
+ Hibernate JPA 2 Metamodel Generator
What is it?
-----------
Modified: jpamodelgen/trunk/src/main/docbook/en-US/master.xml
===================================================================
--- jpamodelgen/trunk/src/main/docbook/en-US/master.xml 2010-03-10 14:28:56 UTC (rev 18959)
+++ jpamodelgen/trunk/src/main/docbook/en-US/master.xml 2010-03-10 14:37:41 UTC (rev 18960)
@@ -27,7 +27,7 @@
]>
<book lang="en">
<bookinfo>
- <title>Hibernate JPA2 Metamodel Generator</title>
+ <title>Hibernate JPA 2 Metamodel Generator</title>
<subtitle>Reference Guide</subtitle>
<releaseinfo>&version;</releaseinfo>
<pubdate>&today;</pubdate>
14 years, 9 months
Hibernate SVN: r18959 - in jpamodelgen/trunk: src/main/docbook/en-US and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2010-03-10 09:28:56 -0500 (Wed, 10 Mar 2010)
New Revision: 18959
Modified:
jpamodelgen/trunk/readme.txt
jpamodelgen/trunk/src/main/docbook/en-US/master.xml
Log:
METAGEN-26 Updated readme and docbook sources
Modified: jpamodelgen/trunk/readme.txt
===================================================================
--- jpamodelgen/trunk/readme.txt 2010-03-10 13:21:46 UTC (rev 18958)
+++ jpamodelgen/trunk/readme.txt 2010-03-10 14:28:56 UTC (rev 18959)
@@ -1,65 +1,45 @@
- JPA Model Generator
+ Hibernate JPA2 Metamodel Generator
What is it?
-----------
This is a Java 6 annotation processor generating meta model classes for the JPA 2 criteria queries.
- The processor (JPAMetaModelEntityProcessor) processes all classes annotated with @Entity, as well as
- entities mapped in /META-INF/orm.xml and mapping files specified in persistence.xml.
+ The processor (JPAMetaModelEntityProcessor) processes all classes annotated with @Entity, @MappedSuperclass
+ or @Embeddable, as well as entities mapped in /META-INF/orm.xml and mapping files specified in persistence.xml.
- Status
- ------
-
- This is an alpha release of the annotation processor. The implemented functionality includes:
- - full support for annotations honoring the access type (v2.0)
- - support for persistence.xml, orm.xml and <mapping-file>
- - tests (both via compilation failure and regular assertion failure)
-
-
System Requirements
-------------------
JDK 1.6 or above.
+
+
+ Documentation
+ -------------
+ http://docs.jboss.org/hibernate/stable/jpamodelgen/reference/en-US/
- Issues
- ------
- See issues.txt
+ Licensing
+ ---------
+ Please see the file called license.txt
- Using JPA Model Generator
- -------------------------
- - Copy jpamodelgen-*.jar together will all jar files from lib into the classpath of your application.
- The jpamodelgen jar file contains a service file (/META-INF/services/javax.annotation.processing.Processor)
- so that the annotation processor will automatically be executed during compilation.
- You can also explicitly specify the processor using the -processor flag:
- > javac -cp <myclasspath> -d <target> -sourcepath <sources> -processor org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
+ Resources
+ ---------
+ Home Page: http://www.hibernate.org/
+ Mailing Lists: http://www.hibernate.org/20.html
+ Source Code: http://anonsvn.jboss.org/repos/hibernate/jpamodelgen/trunk/
+ Issue Tracking: http://opensource.atlassian.com/projects/hibernate/browse/METAGEN
+
- * Maven
- This distribution contains a pom.xml file showing one of three possible ways to integrate the processor in a maven project.
- You can just add <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor> to the maven-compiler-plugin.
- This approach has, however, the shortcoming that messages from the annotation processor are not displayed. This is a known
- issue. See also - http://weblogs.java.net/blog/ss141213/archive/2007/11/my_maven_experi.html
- The second alternative is the maven-annotation-plugin (http://code.google.com/p/maven-annotation-plugin/). This approach
- hasn't been tested yet.
- Last but not least, you can use the maven-antrun-plugin to just run the annotation processor and ignore the processor in
- in the maven-compiler-plugin via '-proc:none'. This is the approach chosen in the POM for this project.
- * Ant
- Make sure the annotation processor and its dependencies are in the classpath. Due the service file the processor will be
- automatically executed when the javac task executes.
- If not try adding <compilerarg value="-processor org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor"/>
- * Idea
- Again, if in the classpath the JPAMetaModelEntityProcessor should execute automatically. If not add the following under
- 'Compiler->Java Compiler': -target 1.6 -processor org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
- You can also turn of annotation processing via: -target 1.6 -proc:none
+
-
+
Modified: jpamodelgen/trunk/src/main/docbook/en-US/master.xml
===================================================================
--- jpamodelgen/trunk/src/main/docbook/en-US/master.xml 2010-03-10 13:21:46 UTC (rev 18958)
+++ jpamodelgen/trunk/src/main/docbook/en-US/master.xml 2010-03-10 14:28:56 UTC (rev 18959)
@@ -19,6 +19,7 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY version "WORKING">
+<!ENTITY today "TODAY">
<!ENTITY copyrightYear "2010">
<!ENTITY copyrightHolder "Red Hat Inc.">
<!ENTITY jpa2Ref '<citation><xref linkend="JPA2"/></citation>'>
@@ -26,20 +27,26 @@
]>
<book lang="en">
<bookinfo>
- <title>Hibernate Metamodel Generator</title>
- <subtitle>JPA 2 Static Metamodel Annotation Processor</subtitle>
+ <title>Hibernate JPA2 Metamodel Generator</title>
<subtitle>Reference Guide</subtitle>
<releaseinfo>&version;</releaseinfo>
+ <pubdate>&today;</pubdate>
<productnumber>&version;</productnumber>
<copyright>
<year>©rightYear;</year>
<holder>©rightHolder;</holder>
</copyright>
+ <authorgroup>
+ <author>
+ <firstname>Hardy</firstname>
+ <surname>Ferentschik</surname>
+ </author>
+ </authorgroup>
</bookinfo>
<toc/>
<chapter id="introduction">
<title>Introduction</title>
- <section id="whatisit" revision="1">
+ <section id="whatisit">
<title>What is it about?</title>
<para>JPA 2 defines a new typesafe <classname>Criteria</classname> API which allows criteria
queries to be constructed in a strongly-typed manner, using metamodel objects to provide
@@ -51,7 +58,7 @@
<example id="jpa2-entity-example">
<title>JPA 2 annotated entities <classname>Order</classname> and
<classname>Item</classname></title>
- <programlisting>
+ <programlisting role="JAVA" language="JAVA">
@Entity
public class Order {
@Id
@@ -87,7 +94,7 @@
</example>
<example id="metamodel-class-example">
<title>Metamodel class <classname>Order_</classname></title>
- <programlisting>
+ <programlisting role="JAVA" language="JAVA">
@StaticMetamodel(Order.class)
public class Order_ {
public static volatile SingularAttribute<Order, Integer> id;
@@ -99,11 +106,12 @@
</example>
<example id="criteria-example">
<title>Typesafe citeria query</title>
- <programlisting>
+ <programlisting role="JAVA" language="JAVA">
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
SetJoin<Order, Item> itemNode = cq.from(Order.class).join(Order_.items);
cq.where( cb.equal(itemNode.get(Item_.id), 5 ) ).distinct(true);
+
</programlisting>
</example>
</section>
@@ -139,23 +147,24 @@
<para>For every persistent non-collection-valued attribute y declared by class
<classname>X</classname>, where the type of y is <classname>Y</classname>, the
metamodel class must contain a declaration as follows:
- <programlisting>public static volatile SingularAttribute<X, Y> y;</programlisting></para>
+ </para>
+ <programlisting>public static volatile SingularAttribute<X, Y> y;</programlisting>
</listitem>
<listitem>
<para>For every persistent collection-valued attribute z declared by class
<classname>X</classname>, where the element type of z is <classname>Z</classname>,
the metamodel class must contain a declaration as follows:<itemizedlist>
<listitem>
- <para>if the collection type of z is java.util.Collection, then
- <programlisting>public static volatile CollectionAttribute<X, Z> z;</programlisting></para>
+ <para>if the collection type of z is java.util.Collection, then</para>
+ <programlisting>public static volatile CollectionAttribute<X, Z> z;</programlisting>
</listitem>
<listitem>
- <para>if the collection type of z is java.util.Set, then
- <programlisting>public static volatile SetAttribute<X, Z> z;</programlisting></para>
+ <para>if the collection type of z is java.util.Set, then</para>
+ <programlisting>public static volatile SetAttribute<X, Z> z;</programlisting>
</listitem>
<listitem>
- <para>if the collection type of z is java.util.List, then
- <programlisting>public static volatile ListAttribute<X, Z> z;</programlisting></para>
+ <para>if the collection type of z is java.util.List, then</para>
+ <programlisting>public static volatile ListAttribute<X, Z> z;</programlisting>
</listitem>
<listitem>
<para>if the collection type of z is java.util.Map, then
@@ -177,14 +186,14 @@
linkend="maven-dependency"/>.</para>
<example id="maven-dependency">
<title>Maven dependency </title>
- <programlisting><dependency>
+ <programlisting role="XML" language="XML"><dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>1.0.0</version>
</dependency></programlisting>
</example>
<para>Alternatively, a full distribution package can be downloaded from <ulink
- url="http://sourceforge.net/projects/hibernate">SourceForge</ulink>.</para>
+ url="http://sourceforge.net/projects/hibernate/files/hibernate-jpamodelgen">SourceForge</ulink>.</para>
<para>In most cases the annotation processor will automatically run provided
the processor jar is added to the classpath and a JDK 6 is used. This happens due to <ulink
url="http://java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html#Service%20Provider">Java's
@@ -197,7 +206,7 @@
</note></para>
<section>
<title>Usage from the command line</title>
- <section id="usage-ant" revision="1">
+ <section id="usage-ant">
<title>Usage with Ant</title>
<para>As mentioned before, the annotation processor will run automatically each time the
Java compiler is called, provided the jar file is on the classpath. Sometimes, however, it is
@@ -208,12 +217,12 @@
configured to just run annotation processing.</para>
<example id="javac-task-example">
<title>Javac Task configuration</title>
- <programlisting><javac srcdir="${src.dir}"
+ <programlisting role="XML" language="XML"><javac srcdir="${src.dir}"
destdir="${target.dir}"
failonerror="false"
fork="true"
classpath="${classpath}">
- <emphasis role="bold"><compilerarg value="-proc:only"/></emphasis>
+ <compilerarg value="-proc:only"/>
</javac></programlisting>
</example>
<para>The option <emphasis>-proc:only</emphasis> instructs the compiler to just run the
@@ -224,27 +233,25 @@
relevant options can be specified.</para>
</tip>
</section>
- <section revision="1">
+ <section>
<title>Usage with Maven</title>
<para>There are several ways of running the annotation processor as part of a Maven build.
Again, it will automatically run if you are using a JDK 6 compiler and the annotation
processor jar is on the classpath. In case you have more than one annotation processors on
your classpath you can explicitly pass the processor option to the compiler plugin:</para>
- <para>
<example>
<title>Maven compiler plugin configuration - direct execution</title>
- <programlisting><plugin>
+ <programlisting role="XML" language="XML"><plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArguments>
- <emphasis role="bold"><processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor></emphasis>
+ <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</compilerArguments>
</configuration>
</plugin></programlisting>
</example>
- </para>
<para>The maven-compiler-plugin approach has the disadvantage that the maven compiler plugin
does currently not allow to specify multiple compiler arguments (<ulink
url="http://jira.codehaus.org/browse/MCOMPILER-62">MCOMPILER-62</ulink>) and that
@@ -254,12 +261,12 @@
linkend="disable-processing-maven-compiler-plugin"/>.</para>
<example id="disable-processing-maven-compiler-plugin">
<title>Maven compiler plugin configuration - indirect execution</title>
- <programlisting><plugin>
+ <programlisting role="XML" language="XML"><plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
- <emphasis role="bold"><compilerArgument>-proc:none</compilerArgument></emphasis>
+ <compilerArgument>-proc:none</compilerArgument>
</configuration>
</plugin></programlisting>
</example>
@@ -271,8 +278,8 @@
url="http://www.jfrog.org/artifactory/plugins-releases">jfrog</ulink>) can be used. The
configuration can be seen in <xref linkend="maven-processor-plugin"/>.</para>
<example id="maven-processor-plugin">
- <title>Maven compiler plugin configuration with maven-annotation-plugin</title>
- <programlisting><plugin>
+ <title>Configuration with maven-annotation-plugin</title>
+ <programlisting role="XML" language="XML"><plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<executions>
14 years, 9 months
Hibernate SVN: r18958 - core/trunk/annotations/src/main/docbook/en.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-03-10 08:21:46 -0500 (Wed, 10 Mar 2010)
New Revision: 18958
Modified:
core/trunk/annotations/src/main/docbook/en/master.xml
Log:
HHH-4933 clean the preface of Hibernate Annotations docs
Modified: core/trunk/annotations/src/main/docbook/en/master.xml
===================================================================
--- core/trunk/annotations/src/main/docbook/en/master.xml 2010-03-10 11:03:08 UTC (rev 18957)
+++ core/trunk/annotations/src/main/docbook/en/master.xml 2010-03-10 13:21:46 UTC (rev 18958)
@@ -61,39 +61,29 @@
<para>Hibernate, like all other object/relational mapping tools, requires
metadata that governs the transformation of data from one representation
- to the other. In Hibernate 2.x mapping metadata is most of the time
- declared in XML text files. Alternatively XDoclet can be used utilizing
- Javadoc source code annotations together with a compile time preprocessor.
+ to the other. Hibernate Annotations provides annotation-based mapping metadata.
</para>
- <para>The same kind of annotation support is now available in the standard
- JDK, although more powerful and with better tools support. IntelliJ IDEA
- and Eclipse for example, support auto-completion and syntax highlighting
- of JDK 5.0 annotations which are compiled into the bytecode and read at
- runtime using reflection. No external XML files are needed.</para>
-
- <para>The EJB3 specification recognizes the interest and the success of
+ <para>The JPA specification recognizes the interest and the success of
the transparent object/relational mapping paradigm. It standardizes the
basic APIs and the metadata needed for any object/relational persistence
- mechanism. <emphasis>Hibernate EntityManager</emphasis> implements the
- programming interfaces and lifecycle rules as defined by the EJB3
+ mechanism.
+ <emphasis>Hibernate EntityManager</emphasis> implements the
+ programming interfaces and lifecycle rules as defined by the JPA
persistence specification and together with <emphasis>Hibernate
- Annotations</emphasis> offers a complete (and standalone) EJB3 persistence
- solution on top of the mature Hibernate core. You may use a combination of
- all three together, annotations without EJB3 programming interfaces and
- lifecycle, or even pure native Hibernate, depending on the business and
- technical needs of your project. At all times you cann fall back to
+ Annotations</emphasis> offers a complete (and standalone) JPA persistence
+ solution on top of the mature Hibernate Core. You may use a combination of
+ all three together, annotations without JPA programming interfaces and
+ lifecycle, or even pure native Hibernate Core, depending on the business and
+ technical needs of your project. At all time you can fall back to
Hibernate native APIs, or if required, even to native JDBC and SQL.</para>
<para>This release of <emphasis>Hibernate Annotations</emphasis> is based
- on the final release of the EJB 3.0 / JPA specification (aka <ulink
- url="http://jcp.org/en/jsr/detail?id=220">JSR-220</ulink>) and
+ on the final release of the JPA 2 specification (aka <ulink
+ url="http://jcp.org/en/jsr/detail?id=317">JSR-317</ulink>) and
supports all its features (including the optional ones). Hibernate
specific features and extensions are also available through
- unstandardized, Hibernate specific annotations. While the Hibernate
- feature coverage is high, some can not yet be expressed via annotations.
- The eventual goal is to cover all of them. See the JIRA road map section
- for more informations.</para>
+ unstandardized, Hibernate specific annotations.</para>
<para>If you are moving from previous Hibernate Annotations versions,
please have a look at <ulink url="http://www.hibernate.org/398.html">Java
14 years, 9 months
Hibernate SVN: r18957 - in core/trunk/testsuite/src/test/java/org/hibernate/test: immutable/entitywithmutablecollection and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: gbadner
Date: 2010-03-10 06:03:08 -0500 (Wed, 10 Mar 2010)
New Revision: 18957
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/AbstractEntityWithManyToManyTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/AbstractEntityWithOneToManyTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Contract.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/ContractVariation.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Info.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Owner.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Party.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Plan.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariation.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariationOneToManyJoin.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariationVersioned.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariationVersionedOneToManyJoin.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/EntityWithInverseManyToManyTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/EntityWithInverseOneToManyJoinTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/EntityWithInverseOneToManyTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseManyToManyTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyFailureExpectedTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyJoinFailureExpectedTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyJoinTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariation.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationOneToManyJoin.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationUnidir.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationVersioned.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationVersionedOneToManyJoin.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseManyToManyTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseManyToManyUnidirTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseOneToManyJoinTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseOneToManyTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseOneToManyUnidirTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/VersionedEntityWithNonInverseManyToManyTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/VersionedEntityWithNonInverseOneToManyJoinTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/VersionedEntityWithNonInverseOneToManyTest.java
Modified:
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Contract.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ContractVariation.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ImmutableTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Info.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Party.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Plan.java
core/trunk/testsuite/src/test/java/org/hibernate/test/readonly/ReadOnlyVersionedNodesTest.java
Log:
HHH-4993 : Updates to read-only entity associations made while in persistent state are ignored by flush (tests only)
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Contract.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Contract.java 2010-03-10 10:56:16 UTC (rev 18956)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Contract.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -11,6 +11,7 @@
public class Contract implements Serializable {
private long id;
+ private long version;
private String customerName;
private String type;
private List variations;
@@ -26,8 +27,8 @@
public Contract(Plan plan, String customerName, String type) {
plans = new HashSet();
- plans.add( plan );
if ( plan != null ) {
+ plans.add( plan );
plan.getContracts().add( this );
}
this.customerName = customerName;
@@ -38,6 +39,14 @@
infos = new HashSet();
}
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+
public Set getPlans() {
return plans;
}
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ContractVariation.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ContractVariation.hbm.xml 2010-03-10 10:56:16 UTC (rev 18956)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ContractVariation.hbm.xml 2010-03-10 11:03:08 UTC (rev 18957)
@@ -37,7 +37,7 @@
<generator class="increment"/>
</id>
<!-- <many-to-one name="contract" update="false" insert="false"/> -->
- <many-to-one name="contract" not-null="true"/>
+ <many-to-one name="contract" not-null="false"/>
<property name="name" not-null="true"/>
<set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
<key column="party"/>
@@ -85,7 +85,7 @@
<property name="text" type="text"/>
<set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
<key>
- <column name="contract"/>
+ <column name="contractvariation"/>
<column name="version"/>
</key>
<one-to-many class="Info"/>
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ImmutableTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ImmutableTest.java 2010-03-10 10:56:16 UTC (rev 18956)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ImmutableTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -1222,6 +1222,234 @@
assertDeleteCount( 4 );
}
+ public void testImmutableEntityAddImmutableToInverseMutableCollection() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gavin", "phone");
+ ContractVariation cv1 = new ContractVariation(1, c);
+ cv1.setText("expensive");
+ ContractVariation cv2 = new ContractVariation(2, c);
+ cv2.setText("more expensive");
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ Party party = new Party( "a party" );
+ s.persist( party );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 4 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c.addParty( new Party( "a new party" ) );
+ s.update( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c.addParty( party );
+ s.update( c );
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ assertEquals( c.getCustomerName(), "gavin" );
+ assertEquals( c.getVariations().size(), 2 );
+ Iterator it = c.getVariations().iterator();
+ cv1 = (ContractVariation) it.next();
+ assertEquals( cv1.getText(), "expensive" );
+ cv2 = (ContractVariation) it.next();
+ assertEquals( cv2.getText(), "more expensive" );
+ //assertEquals( 2, c.getParties().size() );
+ s.delete(c);
+ assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Long(0) );
+ assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Long(0) );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 4 );
+ }
+
+ public void testImmutableEntityRemoveImmutableFromInverseMutableCollection() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gavin", "phone");
+ ContractVariation cv1 = new ContractVariation(1, c);
+ cv1.setText("expensive");
+ ContractVariation cv2 = new ContractVariation(2, c);
+ cv2.setText("more expensive");
+ Party party = new Party( "party1" );
+ c.addParty( party );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 4 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ party = ( Party ) c.getParties().iterator().next();
+ c.removeParty( party );
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( c );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ assertEquals( c.getCustomerName(), "gavin" );
+ assertEquals( c.getVariations().size(), 2 );
+ Iterator it = c.getVariations().iterator();
+ cv1 = (ContractVariation) it.next();
+ assertEquals( cv1.getText(), "expensive" );
+ cv2 = (ContractVariation) it.next();
+ assertEquals( cv2.getText(), "more expensive" );
+ //assertEquals( 0, c.getParties().size() );
+ s.delete(c);
+ assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Long(0) );
+ assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Long(0) );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 4 );
+ }
+
+ public void testImmutableEntityRemoveImmutableFromInverseMutableCollectionByDelete() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gavin", "phone");
+ ContractVariation cv1 = new ContractVariation(1, c);
+ cv1.setText("expensive");
+ ContractVariation cv2 = new ContractVariation(2, c);
+ cv2.setText("more expensive");
+ Party party = new Party( "party1" );
+ c.addParty( party );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 4 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ party = ( Party ) c.getParties().iterator().next();
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.delete( party );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 1 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ assertEquals( c.getCustomerName(), "gavin" );
+ assertEquals( c.getVariations().size(), 2 );
+ Iterator it = c.getVariations().iterator();
+ cv1 = (ContractVariation) it.next();
+ assertEquals( cv1.getText(), "expensive" );
+ cv2 = (ContractVariation) it.next();
+ assertEquals( cv2.getText(), "more expensive" );
+ assertEquals( 0, c.getParties().size() );
+ s.delete(c);
+ assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Long(0) );
+ assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Long(0) );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 3 );
+ }
+
+ public void testImmutableEntityRemoveImmutableFromInverseMutableCollectionByDeref() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gavin", "phone");
+ ContractVariation cv1 = new ContractVariation(1, c);
+ cv1.setText("expensive");
+ ContractVariation cv2 = new ContractVariation(2, c);
+ cv2.setText("more expensive");
+ Party party = new Party( "party1" );
+ c.addParty( party );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 4 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ party = ( Party ) c.getParties().iterator().next();
+ party.setContract( null );
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( party );
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ party = ( Party ) s.get( Party.class, party.getId() );
+ assertNotNull( party.getContract() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ assertEquals( c.getCustomerName(), "gavin" );
+ assertEquals( c.getVariations().size(), 2 );
+ Iterator it = c.getVariations().iterator();
+ cv1 = (ContractVariation) it.next();
+ assertEquals( cv1.getText(), "expensive" );
+ cv2 = (ContractVariation) it.next();
+ assertEquals( cv2.getText(), "more expensive" );
+ assertEquals( 1, c.getParties().size() );
+ party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party1", party.getName() );
+ assertSame( c, party.getContract() );
+ s.delete(c);
+ assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Long(0) );
+ assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Long(0) );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 4 );
+ }
+
protected void clearCounts() {
getSessions().getStatistics().clear();
}
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Info.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Info.java 2010-03-10 10:56:16 UTC (rev 18956)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Info.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -7,6 +7,7 @@
private long id;
private String text;
+ private long version;
public Info() {
super();
@@ -16,6 +17,14 @@
this.text = text;
}
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+
public String getText() {
return text;
}
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Party.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Party.java 2010-03-10 10:56:16 UTC (rev 18956)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Party.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -10,6 +10,7 @@
public class Party implements Serializable {
private long id;
+ private long version;
private Contract contract;
private String name;
private Set infos = new HashSet();
@@ -22,6 +23,14 @@
this.name = name;
}
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+
public String getName() {
return name;
}
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Plan.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Plan.java 2010-03-10 10:56:16 UTC (rev 18956)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Plan.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -9,6 +9,7 @@
public class Plan implements Serializable {
private long id;
+ private long version;
private String description;
private Set contracts;
private Set infos;
@@ -23,6 +24,14 @@
infos = new HashSet();
}
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+
public long getId() {
return id;
}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/AbstractEntityWithManyToManyTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/AbstractEntityWithManyToManyTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/AbstractEntityWithManyToManyTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,1103 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection;
+
+import java.util.Iterator;
+
+import org.hibernate.MappingException;
+import org.hibernate.Session;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.criterion.Projections;
+import org.hibernate.criterion.Restrictions;
+import org.hibernate.impl.SessionFactoryImpl;
+import org.hibernate.junit.functional.FunctionalTestCase;
+
+/**
+ * @author Gail Badner
+ */
+public abstract class AbstractEntityWithManyToManyTest extends FunctionalTestCase {
+ private boolean isPlanContractsInverse;
+ private boolean isPlanContractsBidirectional;
+ private boolean isPlanVersioned;
+ private boolean isContractVersioned;
+
+ public AbstractEntityWithManyToManyTest(String str) {
+ super(str);
+ }
+
+ public void configure(Configuration cfg) {
+ cfg.setProperty( Environment.GENERATE_STATISTICS, "true");
+ cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
+ }
+
+ public abstract String[] getMappings();
+
+ protected void prepareTest() throws Exception {
+ super.prepareTest();
+ isPlanContractsInverse = ( ( SessionFactoryImpl ) getSessions() ).getCollectionPersister( Plan.class.getName() + ".contracts" ).isInverse();
+ try {
+ ( ( SessionFactoryImpl ) getSessions() ).getCollectionPersister( Contract.class.getName() + ".plans" );
+ isPlanContractsBidirectional = true;
+ }
+ catch ( MappingException ex) {
+ isPlanContractsBidirectional = false;
+ }
+ isPlanVersioned = ( ( SessionFactoryImpl ) getSessions() ).getEntityPersister( Plan.class.getName() ).isVersioned();
+ isContractVersioned = ( ( SessionFactoryImpl ) getSessions() ).getEntityPersister( Contract.class.getName() ).isVersioned();
+ }
+
+ public void testUpdateProperty() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ p.addContract( new Contract( null, "gail", "phone") );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(p);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = (Plan) s.createCriteria( Plan.class ).uniqueResult();
+ p.setDescription( "new plan" );
+ assertEquals( 1, p.getContracts().size() );
+ Contract c = ( Contract ) p.getContracts().iterator().next();
+ c.setCustomerName( "yogi" );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = (Plan) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 1, p.getContracts().size() );
+ c = ( Contract ) p.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 1, c.getPlans().size() );
+ assertSame( p, c.getPlans().iterator().next() );
+ }
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Plan.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testCreateWithNonEmptyManyToManyCollectionOfNew() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ p.addContract( new Contract( null, "gail", "phone") );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(p);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 1, p.getContracts().size() );
+ Contract c = ( Contract ) p.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 1, c.getPlans().size() );
+ assertSame( p, c.getPlans().iterator().next() );
+ }
+ s.delete(p);
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Plan.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testCreateWithNonEmptyManyToManyCollectionOfExisting() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ p.addContract( c );
+ s = openSession();
+ t = s.beginTransaction();
+ s.save(p);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 1, p.getContracts().size() );
+ c = ( Contract ) p.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 1, c.getPlans().size() );
+ assertSame( p, c.getPlans().iterator().next() );
+ }
+ s.delete(p);
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Plan.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testAddNewManyToManyElementToPersistentEntity() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( p );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.get( Plan.class, p.getId() );
+ assertEquals( 0, p.getContracts().size() );
+ p.addContract( new Contract( null, "gail", "phone") );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 1, p.getContracts().size() );
+ Contract c = ( Contract ) p.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 1, c.getPlans().size() );
+ assertSame( p, c.getPlans().iterator().next() );
+ }
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Plan.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testAddExistingManyToManyElementToPersistentEntity() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ Contract c = new Contract( null, "gail", "phone" );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( p );
+ s.persist( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.get( Plan.class, p.getId() );
+ assertEquals( 0, p.getContracts().size() );
+ c = ( Contract ) s.get( Contract.class, c.getId() );
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 0, c.getPlans().size() );
+ }
+ p.addContract( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( isContractVersioned && isPlanVersioned ? 2 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 1, p.getContracts().size() );
+ c = ( Contract ) p.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ if ( isPlanContractsBidirectional ) {
+ assertSame( p, c.getPlans().iterator().next() );
+ }
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria( Plan.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testCreateWithEmptyManyToManyCollectionUpdateWithExistingElement() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ Contract c = new Contract( null, "gail", "phone");
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( p );
+ s.persist( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ p.addContract( c );
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( p );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( isContractVersioned && isPlanVersioned ? 2 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 1, p.getContracts().size() );
+ c = ( Contract ) p.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ if ( isPlanContractsBidirectional ) {
+ assertSame( p, c.getPlans().iterator().next() );
+ }
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Plan.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testCreateWithNonEmptyManyToManyCollectionUpdateWithNewElement() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ Contract c = new Contract( null, "gail", "phone");
+ p.addContract( c );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(p);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ Contract newC = new Contract( null, "sherman", "telepathy" );
+ p.addContract( newC );
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( p );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 2, p.getContracts().size() );
+ for ( Iterator it=p.getContracts().iterator(); it.hasNext(); ) {
+ Contract aContract = ( Contract ) it.next();
+ if ( aContract.getId() == c.getId() ) {
+ assertEquals( "gail", aContract.getCustomerName() );
+ }
+ else if ( aContract.getId() == newC.getId() ) {
+ assertEquals( "sherman", aContract.getCustomerName() );
+ }
+ else {
+ fail( "unknown contract" );
+ }
+ if ( isPlanContractsBidirectional ) {
+ assertSame( p, aContract.getPlans().iterator().next() );
+ }
+ }
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Plan.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 3 );
+ }
+
+ public void testCreateWithEmptyManyToManyCollectionMergeWithExistingElement() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ Contract c = new Contract( null, "gail", "phone");
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( p );
+ s.persist( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ p.addContract( c );
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.merge( p );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( isContractVersioned && isPlanVersioned ? 2 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 1, p.getContracts().size() );
+ c = ( Contract ) p.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ if ( isPlanContractsBidirectional ) {
+ assertSame( p, c.getPlans().iterator().next() );
+ }
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria(Plan.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testCreateWithNonEmptyManyToManyCollectionMergeWithNewElement() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ Contract c = new Contract( null, "gail", "phone");
+ p.addContract( c );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( p );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ Contract newC = new Contract( null, "yogi", "mail" );
+ p.addContract( newC );
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.merge( p );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( isContractVersioned && isPlanVersioned ? 2 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 2, p.getContracts().size() );
+ for ( Iterator it=p.getContracts().iterator(); it.hasNext(); ) {
+ Contract aContract = ( Contract ) it.next();
+ if ( aContract.getId() == c.getId() ) {
+ assertEquals( "gail", aContract.getCustomerName() );
+ }
+ else if ( ! aContract.getCustomerName().equals( newC.getCustomerName() ) ) {
+ fail( "unknown contract:" + aContract.getCustomerName() );
+ }
+ if ( isPlanContractsBidirectional ) {
+ assertSame( p, aContract.getPlans().iterator().next() );
+ }
+ }
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria( Plan.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 3 );
+ }
+
+ public void testRemoveManyToManyElementUsingUpdate() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ Contract c = new Contract( null, "gail", "phone");
+ p.addContract( c );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( p );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ p.removeContract( c );
+ assertEquals( 0, p.getContracts().size() );
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 0, c.getPlans().size() );
+ }
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( p );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ assertDeleteCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ if ( isPlanContractsInverse ) {
+ assertEquals( 1, p.getContracts().size() );
+ c = ( Contract ) p.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ assertSame( p, c.getPlans().iterator().next() );
+ }
+ else {
+ assertEquals( 0, p.getContracts().size() );
+ c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 0, c.getPlans().size() );
+ }
+ s.delete( c );
+ }
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria(Plan.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testRemoveManyToManyElementUsingUpdateBothSides() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ Contract c = new Contract( null, "gail", "phone");
+ p.addContract( c );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( p );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ p.removeContract( c );
+ assertEquals( 0, p.getContracts().size() );
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 0, c.getPlans().size() );
+ }
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( p );
+ s.update( c );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( isContractVersioned && isPlanVersioned ? 2 : 0 );
+ assertDeleteCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 0, p.getContracts().size() );
+ c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 0, c.getPlans().size() );
+ }
+ s.delete( c );
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria(Plan.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testRemoveManyToManyElementUsingMerge() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ Contract c = new Contract( null, "gail", "phone");
+ p.addContract( c );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( p );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ p.removeContract( c );
+ assertEquals( 0, p.getContracts().size() );
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 0, c.getPlans().size() );
+ }
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.merge( p );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ assertDeleteCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ if ( isPlanContractsInverse ) {
+ assertEquals( 1, p.getContracts().size() );
+ c = ( Contract ) p.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ assertSame( p, c.getPlans().iterator().next() );
+ }
+ else {
+ assertEquals( 0, p.getContracts().size() );
+ c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 0, c.getPlans().size() );
+ }
+ s.delete( c );
+ }
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria(Plan.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testRemoveManyToManyElementUsingMergeBothSides() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ Contract c = new Contract( null, "gail", "phone");
+ p.addContract( c );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( p );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ p.removeContract( c );
+ assertEquals( 0, p.getContracts().size() );
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 0, c.getPlans().size() );
+ }
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.merge( p );
+ c = ( Contract ) s.merge( c );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( isContractVersioned && isPlanVersioned ? 2 : 0 );
+ assertDeleteCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 0, p.getContracts().size() );
+ c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 0, c.getPlans().size() );
+ }
+ s.delete( c );
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria(Plan.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testDeleteManyToManyElement() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ Contract c = new Contract( null, "gail", "phone");
+ p.addContract( c );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( p );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( p );
+ p.removeContract( c );
+ s.delete( c );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ assertDeleteCount( 1 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 0, p.getContracts().size() );
+ c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
+ assertNull( c );
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria(Plan.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 1 );
+ }
+
+ public void testRemoveManyToManyElementByDelete() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ Contract c = new Contract( null, "gail", "phone");
+ p.addContract( c );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( p );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ p.removeContract( c );
+ assertEquals( 0, p.getContracts().size() );
+ if ( isPlanContractsBidirectional ) {
+ assertEquals( 0, c.getPlans().size() );
+ }
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( p );
+ s.delete( c );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( isPlanVersioned ? 1 : 0 );
+ assertDeleteCount( 1 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 0, p.getContracts().size() );
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria(Plan.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 1 );
+ }
+
+ public void testManyToManyCollectionOptimisticLockingWithMerge() {
+ clearCounts();
+
+ Plan pOrig = new Plan( "plan" );
+ Contract cOrig = new Contract( null, "gail", "phone");
+ pOrig.addContract( cOrig );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( pOrig );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ Plan p = ( Plan ) s.get( Plan.class, pOrig.getId() );
+ Contract newC = new Contract( null, "sherman", "note" );
+ p.addContract( newC );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ pOrig.removeContract( cOrig );
+ try {
+ s.merge( pOrig );
+ assertFalse( isContractVersioned );
+ }
+ catch (StaleObjectStateException ex) {
+ assertTrue( isContractVersioned);
+ }
+ finally {
+ t.rollback();
+ }
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ s.delete( p );
+ assertEquals( new Long( 0 ), s.createCriteria(Plan.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 3 );
+ }
+
+ public void testManyToManyCollectionOptimisticLockingWithUpdate() {
+ clearCounts();
+
+ Plan pOrig = new Plan( "plan" );
+ Contract cOrig = new Contract( null, "gail", "phone");
+ pOrig.addContract( cOrig );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(pOrig);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ Plan p = ( Plan ) s.get( Plan.class, pOrig.getId() );
+ Contract newC = new Contract( null, "yogi", "pawprint" );
+ p.addContract( newC );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ pOrig.removeContract( cOrig );
+ s.update( pOrig );
+ try {
+ t.commit();
+ assertFalse( isContractVersioned );
+ }
+ catch (StaleObjectStateException ex) {
+ assertTrue( isContractVersioned);
+ t.rollback();
+ }
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = ( Plan ) s.createCriteria( Plan.class ).uniqueResult();
+ s.delete( p );
+ s.createQuery( "delete from Contract" ).executeUpdate();
+ assertEquals( new Long( 0 ), s.createCriteria(Plan.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+ }
+
+ public void testMoveManyToManyElementToNewEntityCollection() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ p.addContract( new Contract( null, "gail", "phone" ) );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( p );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = (Plan) s.createCriteria( Plan.class ).uniqueResult();
+ assertEquals( 1, p.getContracts().size() );
+ Contract c = ( Contract ) p.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ if ( isPlanContractsBidirectional ) {
+ assertSame( p, c.getPlans().iterator().next() );
+ }
+ p.removeContract( c );
+ Plan p2 = new Plan( "new plan" );
+ p2.addContract( c );
+ s.save( p2 );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( isPlanVersioned && isContractVersioned ? 2 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = (Plan) s.createCriteria( Plan.class ).add( Restrictions.idEq( new Long( p.getId() ) )).uniqueResult();
+ p2 = (Plan) s.createCriteria( Plan.class ).add( Restrictions.idEq( new Long( p2.getId() ) )).uniqueResult();
+ /*
+ if ( isPlanContractsInverse ) {
+ assertEquals( 1, p.getContracts().size() );
+ c = ( Contract ) p.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ if ( isPlanContractsBidirectional ) {
+ assertSame( p, c.getPlans().iterator().next() );
+ }
+ assertEquals( 0, p2.getContracts().size() );
+ }
+ else {
+ */
+ assertEquals( 0, p.getContracts().size() );
+ assertEquals( 1, p2.getContracts().size() );
+ c = ( Contract ) p2.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ if ( isPlanContractsBidirectional ) {
+ assertSame( p2, c.getPlans().iterator().next() );
+ }
+ //}
+ s.delete( p );
+ s.delete( p2 );
+ assertEquals( new Long( 0 ), s.createCriteria( Plan.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 3 );
+ }
+
+ public void testMoveManyToManyElementToExistingEntityCollection() {
+ clearCounts();
+
+ Plan p = new Plan( "plan" );
+ p.addContract( new Contract( null, "gail", "phone" ) );
+ Plan p2 = new Plan( "plan2" );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( p );
+ s.persist( p2 );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = (Plan) s.createCriteria( Plan.class ).add( Restrictions.idEq( new Long( p.getId() ) )).uniqueResult();
+ assertEquals( 1, p.getContracts().size() );
+ Contract c = ( Contract ) p.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ if ( isPlanContractsBidirectional ) {
+ assertSame( p, c.getPlans().iterator().next() );
+ }
+ p.removeContract( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( isPlanVersioned && isContractVersioned ? 2 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p2 = (Plan) s.createCriteria( Plan.class ).add( Restrictions.idEq( new Long( p2.getId() ) )).uniqueResult();
+ c = (Contract) s.createCriteria( Contract.class ).add( Restrictions.idEq( new Long( c.getId() ) )).uniqueResult();
+ p2.addContract( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( isPlanVersioned && isContractVersioned ? 2 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ p = (Plan) s.createCriteria( Plan.class ).add( Restrictions.idEq( new Long( p.getId() ) )).uniqueResult();
+ p2 = (Plan) s.createCriteria( Plan.class ).add( Restrictions.idEq( new Long( p2.getId() ) )).uniqueResult();
+ /*
+ if ( isPlanContractsInverse ) {
+ assertEquals( 1, p.getContracts().size() );
+ c = ( Contract ) p.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ if ( isPlanContractsBidirectional ) {
+ assertSame( p, c.getPlans().iterator().next() );
+ }
+ assertEquals( 0, p2.getContracts().size() );
+ }
+ else {
+ */
+ assertEquals( 0, p.getContracts().size() );
+ assertEquals( 1, p2.getContracts().size() );
+ c = ( Contract ) p2.getContracts().iterator().next();
+ assertEquals( "gail", c.getCustomerName() );
+ if ( isPlanContractsBidirectional ) {
+ assertSame( p2, c.getPlans().iterator().next() );
+ }
+ //}
+ s.delete( p );
+ s.delete( p2 );
+ assertEquals( new Long( 0 ), s.createCriteria( Plan.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 3 );
+ }
+
+ 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 );
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/AbstractEntityWithOneToManyTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/AbstractEntityWithOneToManyTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/AbstractEntityWithOneToManyTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,1180 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection;
+
+import java.util.Iterator;
+
+import org.hibernate.QueryException;
+import org.hibernate.Session;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.criterion.Projections;
+import org.hibernate.criterion.Restrictions;
+import org.hibernate.impl.SessionFactoryImpl;
+import org.hibernate.junit.functional.FunctionalTestCase;
+
+/**
+ * @author Gail Badner
+ */
+public abstract class AbstractEntityWithOneToManyTest extends FunctionalTestCase {
+ private boolean isContractPartiesInverse;
+ private boolean isContractPartiesBidirectional;
+ private boolean isContractVariationsBidirectional;
+ private boolean isContractVersioned;
+
+ public AbstractEntityWithOneToManyTest(String str) {
+ super(str);
+ }
+
+ public void configure(Configuration cfg) {
+ cfg.setProperty( Environment.GENERATE_STATISTICS, "true");
+ cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
+ }
+
+ public abstract String[] getMappings();
+
+ protected boolean checkUpdateCountsAfterAddingExistingElement() {
+ return true;
+ }
+
+ protected boolean checkUpdateCountsAfterRemovingElementWithoutDelete() {
+ return true;
+ }
+
+ protected void prepareTest() throws Exception {
+ super.prepareTest();
+ isContractPartiesInverse = ( ( SessionFactoryImpl ) getSessions() ).getCollectionPersister( Contract.class.getName() + ".parties" ).isInverse();
+ try {
+ ( ( SessionFactoryImpl ) getSessions() ).getEntityPersister( Party.class.getName() ).getPropertyType( "contract" );
+ isContractPartiesBidirectional = true;
+ }
+ catch ( QueryException ex) {
+ isContractPartiesBidirectional = false;
+ }
+ try {
+ ( ( SessionFactoryImpl ) getSessions() ).getEntityPersister( ContractVariation.class.getName() ).getPropertyType( "contract" );
+ isContractVariationsBidirectional = true;
+ }
+ catch ( QueryException ex) {
+ isContractVariationsBidirectional = false;
+ }
+
+ isContractVersioned = ( ( SessionFactoryImpl ) getSessions() ).getEntityPersister( Contract.class.getName() ).isVersioned();
+ }
+
+ public void testUpdateProperty() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ c.addParty( new Party( "party" ) );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
+ c.setCustomerName( "yogi" );
+ assertEquals( 1, c.getParties().size() );
+ Party party = ( Party ) c.getParties().iterator().next();
+ party.setName( "new party" );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
+ assertEquals( 1, c.getParties().size() );
+ party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c, party.getContract() );
+ }
+ s.delete(c);
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testCreateWithNonEmptyOneToManyCollectionOfNew() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ c.addParty( new Party( "party" ) );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
+ assertEquals( 1, c.getParties().size() );
+ Party party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c, party.getContract() );
+ }
+ s.delete(c);
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testCreateWithNonEmptyOneToManyCollectionOfExisting() {
+ clearCounts();
+
+ Party party = new Party( "party" );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( party );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ c.addParty( party );
+ s = openSession();
+ t = s.beginTransaction();
+ s.save( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ // BUG, should be assertUpdateCount( ! isContractPartiesInverse && isPartyVersioned ? 1 : 0 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
+ if ( isContractPartiesInverse ) {
+ assertEquals( 0 , c.getParties().size() );
+ party = ( Party ) s.createCriteria( Party.class ).uniqueResult();
+ assertNull( party.getContract() );
+ s.delete( party );
+ }
+ else {
+ assertEquals( 1 , c.getParties().size() );
+ party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c, party.getContract() );
+ }
+ }
+ s.delete(c);
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testAddNewOneToManyElementToPersistentEntity() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone" );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = ( Contract ) s.get( Contract.class, c.getId() );
+ assertEquals( 0, c.getParties().size() );
+ c.addParty( new Party( "party" ) );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
+ assertEquals( 1, c.getParties().size() );
+ Party party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c, party.getContract() );
+ }
+ s.delete(c);
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testAddExistingOneToManyElementToPersistentEntity() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone" );
+ Party party = new Party( "party" );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( c );
+ s.persist( party );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = ( Contract ) s.get( Contract.class, c.getId() );
+ assertEquals( 0, c.getParties().size() );
+ party = ( Party ) s.get( Party.class, party.getId() );
+ if ( isContractPartiesBidirectional ) {
+ assertNull( party.getContract() );
+ }
+ c.addParty( party );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 0 );
+ if ( checkUpdateCountsAfterAddingExistingElement() ) {
+ assertUpdateCount( isContractVersioned && ! isContractPartiesInverse ? 1 : 0 );
+ }
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
+ if ( isContractPartiesInverse ) {
+ assertEquals( 0, c.getParties().size() );
+ s.delete( party );
+ }
+ else {
+ assertEquals( 1, c.getParties().size() );
+ party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c, party.getContract() );
+ }
+ }
+ s.delete(c);
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testCreateWithEmptyOneToManyCollectionUpdateWithExistingElement() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ Party party = new Party( "party" );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( c );
+ s.persist( party );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ c.addParty( party );
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 0 );
+ if ( checkUpdateCountsAfterAddingExistingElement() ) {
+ assertUpdateCount( isContractVersioned && ! isContractPartiesInverse ? 1 : 0 );
+ }
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ if ( isContractPartiesInverse ) {
+ assertEquals( 0, c.getParties().size() );
+ s.delete( party );
+ }
+ else {
+ assertEquals( 1, c.getParties().size() );
+ party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c, party.getContract() );
+ }
+ }
+ s.delete(c);
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testCreateWithNonEmptyOneToManyCollectionUpdateWithNewElement() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ Party party = new Party( "party" );
+ c.addParty( party );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ Party newParty = new Party( "new party" );
+ c.addParty( newParty );
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ assertEquals( 2, c.getParties().size() );
+ for ( Iterator it=c.getParties().iterator(); it.hasNext(); ) {
+ Party aParty = ( Party ) it.next();
+ if ( aParty.getId() == party.getId() ) {
+ assertEquals( "party", aParty.getName() );
+ }
+ else if ( aParty.getId() == newParty.getId() ) {
+ assertEquals( "new party", aParty.getName() );
+ }
+ else {
+ fail( "unknown party" );
+ }
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c, aParty.getContract() );
+ }
+ }
+ s.delete(c);
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 3 );
+ }
+
+ public void testCreateWithEmptyOneToManyCollectionMergeWithExistingElement() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ Party party = new Party( "party" );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( c );
+ s.persist( party );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ c.addParty( party );
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = ( Contract ) s.merge( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 0 );
+ if ( checkUpdateCountsAfterAddingExistingElement() ) {
+ assertUpdateCount( isContractVersioned && ! isContractPartiesInverse ? 1 : 0 );
+ }
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
+ if ( isContractPartiesInverse ) {
+ assertEquals( 0, c.getParties().size() );
+ s.delete( party );
+ }
+ else {
+ assertEquals( 1, c.getParties().size() );
+ party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c, party.getContract() );
+ }
+ }
+ s.delete(c);
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testCreateWithNonEmptyOneToManyCollectionMergeWithNewElement() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ Party party = new Party( "party" );
+ c.addParty( party );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ Party newParty = new Party( "new party" );
+ c.addParty( newParty );
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = ( Contract ) s.merge( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ assertEquals( 2, c.getParties().size() );
+ for ( Iterator it=c.getParties().iterator(); it.hasNext(); ) {
+ Party aParty = ( Party ) it.next();
+ if ( aParty.getId() == party.getId() ) {
+ assertEquals( "party", aParty.getName() );
+ }
+ else if ( ! aParty.getName().equals( newParty.getName() ) ) {
+ fail( "unknown party:" + aParty.getName() );
+ }
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c, aParty.getContract() );
+ }
+ }
+ s.delete(c);
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 3 );
+ }
+
+ public void testMoveOneToManyElementToNewEntityCollection() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ c.addParty( new Party( "party" ) );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
+ assertEquals( 1, c.getParties().size() );
+ Party party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c, party.getContract() );
+ }
+ c.removeParty( party );
+ Contract c2 = new Contract(null, "david", "phone" );
+ c2.addParty( party );
+ s.save( c2 );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria( Contract.class ).add( Restrictions.idEq( new Long( c.getId() ) )).uniqueResult();
+ c2 = (Contract) s.createCriteria( Contract.class ).add( Restrictions.idEq( new Long( c2.getId() ) )).uniqueResult();
+ if ( isContractPartiesInverse ) {
+ assertEquals( 1, c.getParties().size() );
+ party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c, party.getContract() );
+ }
+ assertEquals( 0, c2.getParties().size() );
+ }
+ else {
+ assertEquals( 0, c.getParties().size() );
+ assertEquals( 1, c2.getParties().size() );
+ party = ( Party ) c2.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c2, party.getContract() );
+ }
+ }
+ s.delete(c);
+ s.delete( c2 );
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 3 );
+ }
+
+ public void testMoveOneToManyElementToExistingEntityCollection() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ c.addParty( new Party( "party" ) );
+ Contract c2 = new Contract(null, "david", "phone" );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( c );
+ s.persist( c2 );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria( Contract.class ).add( Restrictions.idEq( new Long( c.getId() ) )).uniqueResult();
+ assertEquals( 1, c.getParties().size() );
+ Party party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c, party.getContract() );
+ }
+ c.removeParty( party );
+ c2 = (Contract) s.createCriteria( Contract.class ).add( Restrictions.idEq( new Long( c2.getId() ) )).uniqueResult();
+ c2.addParty( party );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( isContractVersioned ? 2 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria( Contract.class ).add( Restrictions.idEq( new Long( c.getId() ) )).uniqueResult();
+ c2 = (Contract) s.createCriteria( Contract.class ).add( Restrictions.idEq( new Long( c2.getId() ) )).uniqueResult();
+ if ( isContractPartiesInverse ) {
+ assertEquals( 1, c.getParties().size() );
+ party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c, party.getContract() );
+ }
+ assertEquals( 0, c2.getParties().size() );
+ }
+ else {
+ assertEquals( 0, c.getParties().size() );
+ assertEquals( 1, c2.getParties().size() );
+ party = ( Party ) c2.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ if ( isContractPartiesBidirectional ) {
+ assertSame( c2, party.getContract() );
+ }
+ }
+ s.delete(c);
+ s.delete( c2 );
+ assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 3 );
+ }
+
+ public void testRemoveOneToManyElementUsingUpdate() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ Party party = new Party( "party" );
+ c.addParty( party );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ c.removeParty( party );
+ assertEquals( 0, c.getParties().size() );
+ if ( isContractPartiesBidirectional ) {
+ assertNull( party.getContract() );
+ }
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( c );
+ s.update( party );
+ t.commit();
+ s.close();
+
+ if ( checkUpdateCountsAfterRemovingElementWithoutDelete() ) {
+ assertUpdateCount( isContractVersioned && ! isContractPartiesInverse ? 1 : 0 );
+ }
+ assertDeleteCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
+ if ( isContractPartiesInverse ) {
+ assertEquals( 1, c.getParties().size() );
+ party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ assertSame( c, party.getContract() );
+ }
+ else {
+ assertEquals( 0, c.getParties().size() );
+ party = ( Party ) s.createCriteria( Party.class ).uniqueResult();
+ if ( isContractPartiesBidirectional ) {
+ assertNull( party.getContract() );
+ }
+ s.delete( party );
+ }
+ s.delete( c );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testRemoveOneToManyElementUsingMerge() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ Party party = new Party( "party" );
+ c.addParty( party );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ c.removeParty( party );
+ assertEquals( 0, c.getParties().size() );
+ if ( isContractPartiesBidirectional ) {
+ assertNull( party.getContract() );
+ }
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = ( Contract ) s.merge( c );
+ party = ( Party ) s.merge( party );
+ t.commit();
+ s.close();
+
+ if ( checkUpdateCountsAfterRemovingElementWithoutDelete() ) {
+ assertUpdateCount( isContractVersioned && ! isContractPartiesInverse ? 1 : 0 );
+ }
+ assertDeleteCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
+ if ( isContractPartiesInverse ) {
+ assertEquals( 1, c.getParties().size() );
+ party = ( Party ) c.getParties().iterator().next();
+ assertEquals( "party", party.getName() );
+ assertSame( c, party.getContract() );
+ }
+ else {
+ assertEquals( 0, c.getParties().size() );
+ party = ( Party ) s.createCriteria( Party.class ).uniqueResult();
+ if ( isContractPartiesBidirectional ) {
+ assertNull( party.getContract() );
+ }
+ s.delete( party );
+ }
+ s.delete( c );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testDeleteOneToManyElement() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ Party party = new Party( "party" );
+ c.addParty( party );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( c );
+ c.removeParty( party );
+ s.delete( party );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ assertDeleteCount( 1 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
+ assertEquals( 0, c.getParties().size() );
+ party = ( Party ) s.createCriteria( Party.class ).uniqueResult();
+ assertNull( party );
+ s.delete( c );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 1 );
+ }
+
+ public void testRemoveOneToManyElementByDelete() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ Party party = new Party( "party" );
+ c.addParty( party );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ c.removeParty( party );
+ assertEquals( 0, c.getParties().size() );
+ if ( isContractPartiesBidirectional ) {
+ assertNull( party.getContract() );
+ }
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( c );
+ s.delete( party );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ assertDeleteCount( 1 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
+ assertEquals( 0, c.getParties().size() );
+ s.delete( c );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 1 );
+ }
+
+ public void testRemoveOneToManyOrphanUsingUpdate() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ ContractVariation cv = new ContractVariation( 1, c );
+ cv.setText( "cv1" );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ c.getVariations().remove( cv );
+ cv.setContract( null );
+ assertEquals( 0, c.getVariations().size() );
+ if ( isContractVariationsBidirectional ) {
+ assertNull( cv.getContract() );
+ }
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( c );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ assertDeleteCount( 1 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
+ assertEquals( 0, c.getVariations().size() );
+ cv = ( ContractVariation ) s.createCriteria( ContractVariation.class ).uniqueResult();
+ assertNull( cv );
+ s.delete( c );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 1 );
+ }
+
+ public void testRemoveOneToManyOrphanUsingMerge() {
+ Contract c = new Contract( null, "gail", "phone");
+ ContractVariation cv = new ContractVariation( 1, c );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ c.getVariations().remove( cv );
+ cv.setContract( null );
+ assertEquals( 0, c.getVariations().size() );
+ if ( isContractVariationsBidirectional ) {
+ assertNull( cv.getContract() );
+ }
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = ( Contract ) s.merge( c );
+ cv = ( ContractVariation ) s.merge( cv );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ assertDeleteCount( 1 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
+ assertEquals( 0, c.getVariations().size() );
+ cv = ( ContractVariation ) s.createCriteria( ContractVariation.class ).uniqueResult();
+ assertNull( cv );
+ s.delete( c );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 1 );
+ }
+
+ public void testDeleteOneToManyOrphan() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gail", "phone");
+ ContractVariation cv = new ContractVariation( 1, c );
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.update( c );
+ c.getVariations().remove( cv );
+ cv.setContract( null );
+ assertEquals( 0, c.getVariations().size() );
+ s.delete( cv );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ assertDeleteCount( 1 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
+ assertEquals( 0, c.getVariations().size() );
+ cv = ( ContractVariation ) s.createCriteria( ContractVariation.class ).uniqueResult();
+ assertNull( cv );
+ s.delete( c );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 1 );
+ }
+
+ public void testOneToManyCollectionOptimisticLockingWithMerge() {
+ clearCounts();
+
+ Contract cOrig = new Contract( null, "gail", "phone");
+ Party partyOrig = new Party( "party" );
+ cOrig.addParty( partyOrig );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(cOrig);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ Contract c = ( Contract ) s.get( Contract.class, cOrig.getId() );
+ Party newParty = new Party( "new party" );
+ c.addParty( newParty );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ cOrig.removeParty( partyOrig );
+ try {
+ s.merge( cOrig );
+ assertFalse( isContractVersioned );
+ }
+ catch (StaleObjectStateException ex) {
+ assertTrue( isContractVersioned);
+ }
+ finally {
+ t.rollback();
+ }
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ s.delete(c);
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 3 );
+ }
+
+ public void testOneToManyCollectionOptimisticLockingWithUpdate() {
+ clearCounts();
+
+ Contract cOrig = new Contract( null, "gail", "phone");
+ Party partyOrig = new Party( "party" );
+ cOrig.addParty( partyOrig );
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(cOrig);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ Contract c = ( Contract ) s.get( Contract.class, cOrig.getId() );
+ Party newParty = new Party( "new party" );
+ c.addParty( newParty );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( isContractVersioned ? 1 : 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ cOrig.removeParty( partyOrig );
+ s.update( cOrig );
+ try {
+ t.commit();
+ assertFalse( isContractVersioned );
+ }
+ catch (StaleObjectStateException ex) {
+ assertTrue( isContractVersioned);
+ t.rollback();
+ }
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ s.createQuery( "delete from Party" ).executeUpdate();
+ s.delete( c );
+ assertEquals( new Long( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ assertEquals( new Long( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
+ t.commit();
+ s.close();
+ }
+
+ 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 );
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Contract.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Contract.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Contract.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,158 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class Contract implements Serializable {
+
+ private long id;
+ private long version;
+ private String customerName;
+ private String type;
+ private List variations;
+ private Contract parent;
+ private Set subcontracts;
+ private Set plans = new HashSet();
+ private Set parties;
+ private Set infos;
+
+ public Contract() {
+ super();
+ }
+
+ public Contract(Plan plan, String customerName, String type) {
+ plans = new HashSet();
+ if ( plan != null ) {
+ plans.add( plan );
+ plan.getContracts().add( this );
+ }
+ this.customerName = customerName;
+ this.type = type;
+ variations = new ArrayList();
+ subcontracts = new HashSet();
+ parties = new HashSet();
+ infos = new HashSet();
+ }
+
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+
+ public Set getPlans() {
+ return plans;
+ }
+
+ public void setPlans(Set plans) {
+ this.plans = plans;
+ }
+
+ public String getCustomerName() {
+ return customerName;
+ }
+
+ public void setCustomerName(String customerName) {
+ this.customerName = customerName;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public List getVariations() {
+ return variations;
+ }
+
+ public void setVariations(List variations) {
+ this.variations = variations;
+ }
+
+ public Contract getParent() {
+ return parent;
+ }
+
+ public void setParent(Contract parent) {
+ this.parent = parent;
+ }
+
+ public Set getSubcontracts() {
+ return subcontracts;
+ }
+
+ public void setSubcontracts(Set subcontracts) {
+ this.subcontracts = subcontracts;
+ }
+
+ public void addSubcontract(Contract subcontract) {
+ subcontracts.add( subcontract );
+ subcontract.setParent( this );
+ }
+
+ public Set getParties() {
+ return parties;
+ }
+
+ public void setParties(Set parties) {
+ this.parties = parties;
+ }
+
+ public void addParty(Party party) {
+ parties.add( party );
+ party.setContract( this );
+ }
+
+ public void removeParty(Party party) {
+ parties.remove( party );
+ party.setContract( null );
+ }
+
+ public Set getInfos() {
+ return infos;
+ }
+
+ public void setInfos(Set infos) {
+ this.infos = infos;
+ }
+}
Property changes on: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Contract.java
___________________________________________________________________
Name: svn:executable
+ *
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/ContractVariation.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/ContractVariation.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/ContractVariation.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,79 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ContractVariation implements Serializable {
+
+ private int id;
+ private Contract contract;
+ private String text;
+ private Set infos = new HashSet();
+
+ public Contract getContract() {
+ return contract;
+ }
+
+ public void setContract(Contract contract) {
+ this.contract = contract;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public ContractVariation() {
+ super();
+ }
+
+ public ContractVariation(int version, Contract contract) {
+ this.contract = contract;
+ this.id = id;
+ contract.getVariations().add(this);
+ }
+
+ public Set getInfos() {
+ return infos;
+ }
+
+ public void setInfos(Set infos) {
+ this.infos = infos;
+ }
+}
Property changes on: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/ContractVariation.java
___________________________________________________________________
Name: svn:executable
+ *
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Info.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Info.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Info.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,66 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection;
+
+import java.io.Serializable;
+
+public class Info implements Serializable {
+
+ private long id;
+ private String text;
+ private long version;
+
+ public Info() {
+ super();
+ }
+
+ public Info(String text) {
+ this.text = text;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Owner.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Owner.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Owner.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,76 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection;
+
+import java.io.Serializable;
+
+public class Owner implements Serializable {
+
+ private long id;
+ private long version;
+ private Plan plan;
+ private String name;
+
+ public Owner() {
+ super();
+ }
+
+ public Owner(String name) {
+ this.name = name;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public Plan getPlan() {
+ return plan;
+ }
+
+ public void setPlan(Plan plan) {
+ this.plan = plan;
+ }
+
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Party.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Party.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Party.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,88 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class Party implements Serializable {
+
+ private long id;
+ private long version;
+ private Contract contract;
+ private String name;
+ private Set infos = new HashSet();
+
+ public Party() {
+ super();
+ }
+
+ public Party(String name) {
+ this.name = name;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public Contract getContract() {
+ return contract;
+ }
+
+ public void setContract(Contract contract) {
+ this.contract = contract;
+ }
+
+ public Set getInfos() {
+ return infos;
+ }
+
+ public void setInfos(Set infos) {
+ this.infos = infos;
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Plan.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Plan.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/Plan.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,131 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public class Plan implements Serializable {
+
+ private long id;
+ private long version;
+ private String description;
+ private Set contracts;
+ private Set infos;
+ private Owner owner;
+
+ public Plan() {
+ this( null );
+ }
+
+ public Plan(String description) {
+ this.description = description;
+ contracts = new HashSet();
+ infos = new HashSet();
+ }
+
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Set getContracts() {
+ return contracts;
+ }
+
+ public void setContracts(Set contracts) {
+ this.contracts = contracts;
+ }
+
+ public void addContract(Contract contract) {
+ if ( ! contracts.add( contract ) ) {
+ return;
+ }
+ if ( contract.getParent() != null ) {
+ addContract( contract.getParent() );
+ }
+ contract.getPlans().add( this );
+ for ( Iterator it=contract.getSubcontracts().iterator(); it.hasNext(); ) {
+ Contract sub = ( Contract ) it.next();
+ addContract( sub );
+ }
+ }
+
+ public void removeContract(Contract contract) {
+ if ( contract.getParent() != null ) {
+ contract.getParent().getSubcontracts().remove( contract );
+ contract.setParent( null );
+ }
+ removeSubcontracts( contract );
+ contract.getPlans().remove( this );
+ contracts.remove( contract );
+ }
+
+ public void removeSubcontracts(Contract contract) {
+ for ( Iterator it=contract.getSubcontracts().iterator(); it.hasNext(); ) {
+ Contract sub = ( Contract ) it.next();
+ removeSubcontracts( sub );
+ sub.getPlans().remove( this );
+ contracts.remove( sub );
+ }
+ }
+
+ public Set getInfos() {
+ return infos;
+ }
+
+ public void setInfos(Set infos) {
+ this.infos = infos;
+ }
+
+ public Owner getOwner() {
+ return owner;
+ }
+
+ public void setOwner(Owner owner) {
+ this.owner = owner;
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariation.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariation.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariation.hbm.xml 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,90 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+ Test for immutable classes/collections.
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.immutable.entitywithmutablecollection">
+ <class name="Info" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text"/>
+ </class>
+
+ <class name="Plan" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="description" not-null="true"/>
+ <set name="contracts" table="plan_contract" inverse="true" mutable="true" cascade="all" fetch="join">
+ <key column="plan"/>
+ <many-to-many column="contract" class="Contract"/>
+ </set>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="plan"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Party" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <many-to-one name="contract" not-null="false"/>
+ <property name="name" not-null="true"/>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="party"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Contract" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="customerName" not-null="true"/>
+ <property name="type" not-null="true"/>
+ <bag name="variations" inverse="true" order-by="id asc"
+ mutable="true" cascade="all-delete-orphan" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="ContractVariation"/>
+ </bag>
+ <many-to-one name="parent" />
+ <set name="subcontracts" inverse="true"
+ mutable="true" cascade="all" fetch="join">
+ <key column="parent"/>
+ <one-to-many class="Contract"/>
+ </set>
+ <set name="plans" table="plan_contract" inverse="false" mutable="true" cascade="none">
+ <key column="contract"/>
+ <many-to-many column="plan" class="Plan"/>
+ </set>
+ <set name="parties" inverse="true" mutable="true" cascade="all" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="Party"/>
+ </set>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="contract"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="ContractVariation" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text" type="text"/>
+ <many-to-one name="contract" not-null="false"/>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="contractvariation"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+</hibernate-mapping>
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariationOneToManyJoin.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariationOneToManyJoin.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariationOneToManyJoin.hbm.xml 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,97 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+ Test for immutable classes/collections.
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.immutable.entitywithmutablecollection">
+ <class name="Info" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text"/>
+ </class>
+
+ <class name="Plan" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="description" not-null="true"/>
+ <set name="contracts" table="plan_contract" inverse="true" mutable="true" cascade="all" fetch="join">
+ <key column="plan"/>
+ <many-to-many column="contract" class="Contract"/>
+ </set>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="plan"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Party" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="party"/>
+ <one-to-many class="Info"/>
+ </set>
+ <join table="contract_party"
+ inverse="false"
+ optional="true">
+ <key column="party"/>
+ <many-to-one name="contract"
+ column="contract"
+ not-null="true"/>
+ </join>
+ </class>
+
+ <class name="Contract" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="customerName" not-null="true"/>
+ <property name="type" not-null="true"/>
+ <bag name="variations" inverse="true" order-by="id asc"
+ mutable="true" cascade="all-delete-orphan" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="ContractVariation"/>
+ </bag>
+ <many-to-one name="parent" />
+ <set name="subcontracts" inverse="true"
+ mutable="true" cascade="all" fetch="join">
+ <key column="parent"/>
+ <one-to-many class="Contract"/>
+ </set>
+ <set name="plans" table="plan_contract" inverse="false" mutable="true" cascade="none">
+ <key column="contract"/>
+ <many-to-many column="plan" class="Plan"/>
+ </set>
+ <set name="parties" table="contract_party" inverse="true" mutable="true" cascade="all">
+ <key column="contract"/>
+ <many-to-many column="party" unique="true" class="Party"/>
+ </set>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="contract"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="ContractVariation" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text" type="text"/>
+ <many-to-one name="contract" not-null="false"/>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="contractvariation"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+</hibernate-mapping>
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariationVersioned.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariationVersioned.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariationVersioned.hbm.xml 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,94 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+ Test for readonly.entitywithmutablecollection classes/collections.
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.immutable.entitywithmutablecollection">
+ <class name="Info" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="text"/>
+ </class>
+
+ <class name="Plan" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="description" not-null="true"/>
+ <set name="contracts" table="plan_contract" inverse="true" mutable="true" cascade="all" fetch="join">
+ <key column="plan"/>
+ <many-to-many column="contract" class="Contract"/>
+ </set>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="plan"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Party" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <many-to-one name="contract" not-null="false"/>
+ <property name="name" not-null="true"/>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="party"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Contract" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="customerName" not-null="true"/>
+ <property name="type" not-null="true"/>
+ <bag name="variations" inverse="true" order-by="id asc"
+ mutable="true" cascade="all-delete-orphan" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="ContractVariation"/>
+ </bag>
+ <many-to-one name="parent" />
+ <set name="subcontracts" inverse="true"
+ mutable="true" cascade="all" fetch="join">
+ <key column="parent"/>
+ <one-to-many class="Contract"/>
+ </set>
+ <set name="plans" table="plan_contract" inverse="false" mutable="true" cascade="none">
+ <key column="contract"/>
+ <many-to-many column="plan" class="Plan"/>
+ </set>
+ <set name="parties" inverse="true" mutable="true" cascade="all" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="Party"/>
+ </set>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="contract"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="ContractVariation" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text" type="text"/>
+ <many-to-one name="contract" not-null="false"/>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="contractvariation"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+</hibernate-mapping>
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariationVersionedOneToManyJoin.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariationVersionedOneToManyJoin.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariationVersionedOneToManyJoin.hbm.xml 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,101 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+ Test for readonly.entitywithmutablecollection classes/collections.
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.immutable.entitywithmutablecollection">
+ <class name="Info" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="text"/>
+ </class>
+
+ <class name="Plan" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="description" not-null="true"/>
+ <set name="contracts" table="plan_contract" inverse="true" mutable="true" cascade="all" fetch="join">
+ <key column="plan"/>
+ <many-to-many column="contract" class="Contract"/>
+ </set>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="plan"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Party" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="name" not-null="true"/>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="party"/>
+ <one-to-many class="Info"/>
+ </set>
+ <join table="contract_party"
+ inverse="false"
+ optional="true">
+ <key column="party"/>
+ <many-to-one name="contract"
+ column="contract"
+ not-null="true"/>
+ </join>
+ </class>
+
+ <class name="Contract" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="customerName" not-null="true"/>
+ <property name="type" not-null="true"/>
+ <bag name="variations" inverse="true" order-by="id asc"
+ mutable="true" cascade="all-delete-orphan" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="ContractVariation"/>
+ </bag>
+ <many-to-one name="parent" />
+ <set name="subcontracts" inverse="true"
+ mutable="true" cascade="all" fetch="join">
+ <key column="parent"/>
+ <one-to-many class="Contract"/>
+ </set>
+ <set name="plans" table="plan_contract" inverse="false" mutable="true" cascade="none">
+ <key column="contract"/>
+ <many-to-many column="plan" class="Plan"/>
+ </set>
+ <set name="parties" table="contract_party" inverse="true" mutable="true" cascade="all">
+ <key column="contract"/>
+ <many-to-many column="party" unique="true" class="Party"/>
+ </set>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="contract"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="ContractVariation" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text" type="text"/>
+ <many-to-one name="contract" not-null="false"/>
+ <set name="infos" inverse="true" mutable="true" cascade="all-delete-orphan">
+ <key column="contractvariation"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+</hibernate-mapping>
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/EntityWithInverseManyToManyTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/EntityWithInverseManyToManyTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/EntityWithInverseManyToManyTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,49 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.inverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithManyToManyTest;
+
+/**
+ * @author Gail Badner
+ */
+public class EntityWithInverseManyToManyTest extends AbstractEntityWithManyToManyTest {
+
+ public EntityWithInverseManyToManyTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/inverse/ContractVariation.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( EntityWithInverseManyToManyTest.class );
+ }
+
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/EntityWithInverseOneToManyJoinTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/EntityWithInverseOneToManyJoinTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/EntityWithInverseOneToManyJoinTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.inverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithOneToManyTest;
+
+
+/**
+ * @author Gail Badner
+ */
+public class EntityWithInverseOneToManyJoinTest extends AbstractEntityWithOneToManyTest {
+
+ public EntityWithInverseOneToManyJoinTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/inverse/ContractVariationOneToManyJoin.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( EntityWithInverseOneToManyJoinTest.class );
+ }
+
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/EntityWithInverseOneToManyTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/EntityWithInverseOneToManyTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/EntityWithInverseOneToManyTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.inverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithOneToManyTest;
+
+
+/**
+ * @author Gail Badner
+ */
+public class EntityWithInverseOneToManyTest extends AbstractEntityWithOneToManyTest {
+
+ public EntityWithInverseOneToManyTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/inverse/ContractVariation.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( EntityWithInverseOneToManyTest.class );
+ }
+
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseManyToManyTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseManyToManyTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseManyToManyTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,49 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.inverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithManyToManyTest;
+
+
+/**
+ * @author Gail Badner
+ */
+public class VersionedEntityWithInverseManyToManyTest extends AbstractEntityWithManyToManyTest {
+
+ public VersionedEntityWithInverseManyToManyTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/inverse/ContractVariationVersioned.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( VersionedEntityWithInverseManyToManyTest.class );
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyFailureExpectedTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyFailureExpectedTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyFailureExpectedTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,105 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.inverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithOneToManyTest;
+
+/**
+ * @author Gail Badner
+ *
+ * These tests reproduce HHH-4992.
+ */
+public class VersionedEntityWithInverseOneToManyFailureExpectedTest extends AbstractEntityWithOneToManyTest {
+
+ public VersionedEntityWithInverseOneToManyFailureExpectedTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/inverse/ContractVariationVersioned.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( VersionedEntityWithInverseOneToManyFailureExpectedTest.class );
+ }
+
+ public void testAddExistingOneToManyElementToPersistentEntity() {
+ reportSkip(
+ "known to fail with versioned entity with inverse collection",
+ "AddExistingOneToManyElementToPersistentEntity"
+ );
+ }
+
+ public void testAddExistingOneToManyElementToPersistentEntityFailureExpected() {
+ super.testAddExistingOneToManyElementToPersistentEntity();
+ }
+
+ public void testCreateWithEmptyOneToManyCollectionUpdateWithExistingElement() {
+ reportSkip(
+ "known to fail with versioned entity with inverse collection",
+ "CreateWithEmptyOneToManyCollectionUpdateWithExistingElement"
+ );
+ }
+
+ public void testCreateWithEmptyOneToManyCollectionUpdateWithExistingElementFailureExpected() {
+ super.testCreateWithEmptyOneToManyCollectionUpdateWithExistingElement();
+ }
+
+ public void testCreateWithEmptyOneToManyCollectionMergeWithExistingElement() {
+ reportSkip(
+ "known to fail with versioned entity with inverse collection",
+ "CreateWithEmptyOneToManyCollectionMergeWithExistingElement"
+ );
+ }
+
+ public void testCreateWithEmptyOneToManyCollectionMergeWithExistingElementFailureExpected() {
+ super.testCreateWithEmptyOneToManyCollectionMergeWithExistingElement();
+ }
+
+ public void testRemoveOneToManyElementUsingUpdate() {
+ reportSkip(
+ "known to fail with versioned entity with inverse collection",
+ "RemoveOneToManyElementUsingUpdate"
+ );
+ }
+
+ public void testRemoveOneToManyElementUsingUpdateFailureExpected() {
+ super.testRemoveOneToManyElementUsingUpdate();
+ }
+
+ public void testRemoveOneToManyElementUsingMerge() {
+ reportSkip(
+ "known to fail with versioned entity with inverse collection",
+ "RemoveOneToManyElementUsingMerge"
+ );
+ }
+
+ public void testRemoveOneToManyElementUsingMergeFailureExpected() {
+ super.testRemoveOneToManyElementUsingMerge();
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyJoinFailureExpectedTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyJoinFailureExpectedTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyJoinFailureExpectedTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,104 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.inverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithOneToManyTest;
+
+
+/**
+ * @author Gail Badner
+ */
+public class VersionedEntityWithInverseOneToManyJoinFailureExpectedTest extends AbstractEntityWithOneToManyTest {
+
+ public VersionedEntityWithInverseOneToManyJoinFailureExpectedTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/inverse/ContractVariationVersionedOneToManyJoin.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( VersionedEntityWithInverseOneToManyJoinFailureExpectedTest.class );
+ }
+
+ public void testAddExistingOneToManyElementToPersistentEntity() {
+ reportSkip(
+ "known to fail with inverse collection",
+ "AddExistingOneToManyElementToPersistentEntity"
+ );
+ }
+
+ public void testAddExistingOneToManyElementToPersistentEntityFailureExpected() {
+ super.testAddExistingOneToManyElementToPersistentEntity();
+ }
+
+ public void testCreateWithEmptyOneToManyCollectionUpdateWithExistingElement() {
+ reportSkip(
+ "known to fail with inverse collection",
+ "CreateWithEmptyOneToManyCollectionUpdateWithExistingElement"
+ );
+ }
+
+ public void testCreateWithEmptyOneToManyCollectionUpdateWithExistingElementFailureExpected() {
+ super.testCreateWithEmptyOneToManyCollectionUpdateWithExistingElement();
+ }
+
+ public void testCreateWithEmptyOneToManyCollectionMergeWithExistingElement() {
+ reportSkip(
+ "known to fail with versioned entity with inverse one-to-many collection",
+ "CreateWithEmptyOneToManyCollectionMergeWithExistingElement"
+ );
+ }
+
+ public void testCreateWithEmptyOneToManyCollectionMergeWithExistingElementFailureExpected() {
+ super.testCreateWithEmptyOneToManyCollectionMergeWithExistingElement();
+ }
+
+ public void testRemoveOneToManyElementUsingUpdate() {
+ reportSkip(
+ "known to fail with versioned entity with inverse collection",
+ "RemoveOneToManyElementUsingUpdate"
+ );
+ }
+
+ public void testRemoveOneToManyElementUsingUpdateFailureExpected() {
+ super.testRemoveOneToManyElementUsingUpdate();
+ }
+
+ public void testRemoveOneToManyElementUsingMerge() {
+ reportSkip(
+ "known to fail with versioned entity with inverse collection",
+ "RemoveOneToManyElementUsingMerge"
+ );
+ }
+
+ public void testRemoveOneToManyElementUsingMergeFailureExpected() {
+ super.testRemoveOneToManyElementUsingMerge();
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyJoinTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyJoinTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyJoinTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,59 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.inverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithOneToManyTest;
+
+
+/**
+ * @author Gail Badner
+ *
+ * These tests reproduce HHH-4992.
+ */
+public class VersionedEntityWithInverseOneToManyJoinTest extends AbstractEntityWithOneToManyTest {
+
+ public VersionedEntityWithInverseOneToManyJoinTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/inverse/ContractVariationVersionedOneToManyJoin.hbm.xml" };
+ }
+
+ protected boolean checkUpdateCountsAfterAddingExistingElement() {
+ return false;
+ }
+
+ protected boolean checkUpdateCountsAfterRemovingElementWithoutDelete() {
+ return false;
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( VersionedEntityWithInverseOneToManyJoinTest.class );
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/inverse/VersionedEntityWithInverseOneToManyTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,55 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.inverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithOneToManyTest;
+
+/**
+ * @author Gail Badner
+ */
+public class VersionedEntityWithInverseOneToManyTest extends AbstractEntityWithOneToManyTest {
+
+ public VersionedEntityWithInverseOneToManyTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/inverse/ContractVariationVersioned.hbm.xml" };
+ }
+
+ protected boolean checkUpdateCountsAfterAddingExistingElement() {
+ return false;
+ }
+
+ protected boolean checkUpdateCountsAfterRemovingElementWithoutDelete() {
+ return false;
+ }
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( VersionedEntityWithInverseOneToManyTest.class );
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariation.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariation.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariation.hbm.xml 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,90 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+ Test for immutable classes/collections.
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.immutable.entitywithmutablecollection">
+ <class name="Info" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text"/>
+ </class>
+
+ <class name="Plan" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="description" not-null="true"/>
+ <set name="contracts" table="plan_contract" inverse="false" mutable="true" cascade="all" fetch="join">
+ <key column="plan"/>
+ <many-to-many column="contract" class="Contract"/>
+ </set>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="plan"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Party" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <many-to-one name="contract" update="false" insert="false" not-null="false"/>
+ <property name="name" not-null="true"/>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="party"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Contract" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="customerName" not-null="true"/>
+ <property name="type" not-null="true"/>
+ <bag name="variations" inverse="false" order-by="id asc"
+ mutable="true" cascade="all-delete-orphan" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="ContractVariation"/>
+ </bag>
+ <many-to-one name="parent" update="false" insert="false"/>
+ <set name="subcontracts" inverse="false"
+ mutable="true" cascade="all" fetch="join">
+ <key column="parent"/>
+ <one-to-many class="Contract"/>
+ </set>
+ <set name="plans" table="plan_contract" inverse="true" mutable="true" cascade="none">
+ <key column="contract"/>
+ <many-to-many column="plan" class="Plan"/>
+ </set>
+ <set name="parties" inverse="false" mutable="true" cascade="all" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="Party"/>
+ </set>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="contract"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="ContractVariation" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text" type="text"/>
+ <many-to-one name="contract" insert="false" update="false" not-null="false"/>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="contractvariation"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+</hibernate-mapping>
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationOneToManyJoin.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationOneToManyJoin.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationOneToManyJoin.hbm.xml 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,97 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+ Test for immutable classes/collections.
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.immutable.entitywithmutablecollection">
+ <class name="Info" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text"/>
+ </class>
+
+ <class name="Plan" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="description" not-null="true"/>
+ <set name="contracts" table="plan_contract" inverse="false" mutable="true" cascade="all" fetch="join">
+ <key column="plan"/>
+ <many-to-many column="contract" class="Contract"/>
+ </set>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="plan"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Party" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="party"/>
+ <one-to-many class="Info"/>
+ </set>
+ <join table="contract_party"
+ inverse="true"
+ optional="true">
+ <key column="party"/>
+ <many-to-one name="contract"
+ column="contract"
+ not-null="true"/>
+ </join>
+ </class>
+
+ <class name="Contract" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="customerName" not-null="true"/>
+ <property name="type" not-null="true"/>
+ <bag name="variations" inverse="false" order-by="id asc"
+ mutable="true" cascade="all-delete-orphan" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="ContractVariation"/>
+ </bag>
+ <many-to-one name="parent" update="false" insert="false"/>
+ <set name="subcontracts" inverse="false"
+ mutable="true" cascade="all" fetch="join">
+ <key column="parent"/>
+ <one-to-many class="Contract"/>
+ </set>
+ <set name="plans" table="plan_contract" inverse="true" mutable="true" cascade="none">
+ <key column="contract"/>
+ <many-to-many column="plan" class="Plan"/>
+ </set>
+ <set name="parties" table="contract_party" inverse="false" mutable="true" cascade="all">
+ <key column="contract"/>
+ <many-to-many column="party" unique="true" class="Party"/>
+ </set>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="contract"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="ContractVariation" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text" type="text"/>
+ <many-to-one name="contract" insert="false" update="false" not-null="false"/>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="contractvariation"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+</hibernate-mapping>
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationUnidir.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationUnidir.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationUnidir.hbm.xml 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,85 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+ Test for immutable classes/collections.
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.immutable.entitywithmutablecollection">
+ <class name="Info" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text"/>
+ </class>
+
+ <class name="Plan" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="description" not-null="true"/>
+ <set name="contracts" table="plan_contract" inverse="false" mutable="true" cascade="all" fetch="join">
+ <key column="plan"/>
+ <many-to-many column="contract" class="Contract"/>
+ </set>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="plan"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Party" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="party"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Contract" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="customerName" not-null="true"/>
+ <property name="type" not-null="true"/>
+ <bag name="variations" inverse="false" order-by="id asc"
+ mutable="true" cascade="all-delete-orphan" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="ContractVariation"/>
+ </bag>
+ <many-to-one name="parent" update="false" insert="false"/>
+ <set name="subcontracts" inverse="false"
+ mutable="true" cascade="all" fetch="join">
+ <key column="parent"/>
+ <one-to-many class="Contract"/>
+ </set>
+ <set name="parties" inverse="false" mutable="true" cascade="all" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="Party"/>
+ </set>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="contract"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="ContractVariation" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text" type="text"/>
+ <many-to-one name="contract" insert="false" update="false" not-null="false"/>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="contractvariation"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+</hibernate-mapping>
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationVersioned.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationVersioned.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationVersioned.hbm.xml 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,94 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+ Test for immutable classes/collections.
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.immutable.entitywithmutablecollection">
+ <class name="Info" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="text"/>
+ </class>
+
+ <class name="Plan" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="description" not-null="true"/>
+ <set name="contracts" table="plan_contract" inverse="false" mutable="true" cascade="all" fetch="join">
+ <key column="plan"/>
+ <many-to-many column="contract" class="Contract"/>
+ </set>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="plan"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Party" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <many-to-one name="contract" update="false" insert="false" not-null="false"/>
+ <property name="name" not-null="true"/>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="party"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Contract" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="customerName" not-null="true"/>
+ <property name="type" not-null="true"/>
+ <bag name="variations" inverse="false" order-by="id asc"
+ mutable="true" cascade="all-delete-orphan" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="ContractVariation"/>
+ </bag>
+ <many-to-one name="parent" update="false" insert="false"/>
+ <set name="subcontracts" inverse="false"
+ mutable="true" cascade="all" fetch="join">
+ <key column="parent"/>
+ <one-to-many class="Contract"/>
+ </set>
+ <set name="plans" table="plan_contract" inverse="true" mutable="true" cascade="none">
+ <key column="contract"/>
+ <many-to-many column="plan" class="Plan"/>
+ </set>
+ <set name="parties" inverse="false" mutable="true" cascade="all" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="Party"/>
+ </set>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="contract"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="ContractVariation" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text" type="text"/>
+ <many-to-one name="contract" insert="false" update="false" not-null="false"/>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="contractvariation"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+</hibernate-mapping>
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationVersionedOneToManyJoin.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationVersionedOneToManyJoin.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/ContractVariationVersionedOneToManyJoin.hbm.xml 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,101 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+ Test for immutable classes/collections.
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.immutable.entitywithmutablecollection">
+ <class name="Info" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="text"/>
+ </class>
+
+ <class name="Plan" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="description" not-null="true"/>
+ <set name="contracts" table="plan_contract" inverse="false" mutable="true" cascade="all" fetch="join">
+ <key column="plan"/>
+ <many-to-many column="contract" class="Contract"/>
+ </set>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="plan"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="Party" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="name" not-null="true"/>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="party"/>
+ <one-to-many class="Info"/>
+ </set>
+ <join table="contract_party"
+ inverse="true"
+ optional="true">
+ <key column="party"/>
+ <many-to-one name="contract"
+ column="contract"
+ not-null="true"/>
+ </join>
+ </class>
+
+ <class name="Contract" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="customerName" not-null="true"/>
+ <property name="type" not-null="true"/>
+ <bag name="variations" inverse="false" order-by="id asc"
+ mutable="true" cascade="all-delete-orphan" fetch="join">
+ <key column="contract"/>
+ <one-to-many class="ContractVariation"/>
+ </bag>
+ <many-to-one name="parent" update="false" insert="false"/>
+ <set name="subcontracts" inverse="false"
+ mutable="true" cascade="all" fetch="join">
+ <key column="parent"/>
+ <one-to-many class="Contract"/>
+ </set>
+ <set name="plans" table="plan_contract" inverse="true" mutable="true" cascade="none">
+ <key column="contract"/>
+ <many-to-many column="plan" class="Plan"/>
+ </set>
+ <set name="parties" table="contract_party" inverse="false" mutable="true" cascade="all">
+ <key column="contract"/>
+ <many-to-many column="party" unique="true" class="Party"/>
+ </set>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="contract"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+ <class name="ContractVariation" mutable="false">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="text" type="text"/>
+ <many-to-one name="contract" insert="false" update="false" not-null="false"/>
+ <set name="infos" inverse="false" mutable="true" cascade="all-delete-orphan">
+ <key column="contractvariation"/>
+ <one-to-many class="Info"/>
+ </set>
+ </class>
+
+</hibernate-mapping>
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseManyToManyTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseManyToManyTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseManyToManyTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.noninverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithManyToManyTest;
+
+
+/**
+ * @author Gail Badner
+ */
+public class EntityWithNonInverseManyToManyTest extends AbstractEntityWithManyToManyTest {
+
+ public EntityWithNonInverseManyToManyTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/noninverse/ContractVariation.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( EntityWithNonInverseManyToManyTest.class );
+ }
+
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseManyToManyUnidirTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseManyToManyUnidirTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseManyToManyUnidirTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.noninverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithManyToManyTest;
+
+
+/**
+ * @author Gail Badner
+ */
+public class EntityWithNonInverseManyToManyUnidirTest extends AbstractEntityWithManyToManyTest {
+
+ public EntityWithNonInverseManyToManyUnidirTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/noninverse/ContractVariationUnidir.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( EntityWithNonInverseManyToManyUnidirTest.class );
+ }
+
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseOneToManyJoinTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseOneToManyJoinTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseOneToManyJoinTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.noninverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithOneToManyTest;
+
+
+/**
+ * @author Gail Badner
+ */
+public class EntityWithNonInverseOneToManyJoinTest extends AbstractEntityWithOneToManyTest {
+
+ public EntityWithNonInverseOneToManyJoinTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/noninverse/ContractVariationOneToManyJoin.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( EntityWithNonInverseOneToManyJoinTest.class );
+ }
+
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseOneToManyTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseOneToManyTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseOneToManyTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.noninverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithOneToManyTest;
+
+
+/**
+ * @author Gail Badner
+ */
+public class EntityWithNonInverseOneToManyTest extends AbstractEntityWithOneToManyTest {
+
+ public EntityWithNonInverseOneToManyTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/noninverse/ContractVariation.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( EntityWithNonInverseOneToManyTest.class );
+ }
+
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseOneToManyUnidirTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseOneToManyUnidirTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/EntityWithNonInverseOneToManyUnidirTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.noninverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithOneToManyTest;
+
+
+/**
+ * @author Gail Badner
+ */
+public class EntityWithNonInverseOneToManyUnidirTest extends AbstractEntityWithOneToManyTest {
+
+ public EntityWithNonInverseOneToManyUnidirTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/noninverse/ContractVariationUnidir.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( EntityWithNonInverseOneToManyUnidirTest.class );
+ }
+
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/VersionedEntityWithNonInverseManyToManyTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/VersionedEntityWithNonInverseManyToManyTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/VersionedEntityWithNonInverseManyToManyTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.noninverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithManyToManyTest;
+
+
+/**
+ * @author Gail Badner
+ */
+public class VersionedEntityWithNonInverseManyToManyTest extends AbstractEntityWithManyToManyTest {
+
+ public VersionedEntityWithNonInverseManyToManyTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/noninverse/ContractVariationVersioned.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( VersionedEntityWithNonInverseManyToManyTest.class );
+ }
+
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/VersionedEntityWithNonInverseOneToManyJoinTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/VersionedEntityWithNonInverseOneToManyJoinTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/VersionedEntityWithNonInverseOneToManyJoinTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.noninverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithOneToManyTest;
+
+
+/**
+ * @author Gail Badner
+ */
+public class VersionedEntityWithNonInverseOneToManyJoinTest extends AbstractEntityWithOneToManyTest {
+
+ public VersionedEntityWithNonInverseOneToManyJoinTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/noninverse/ContractVariationVersionedOneToManyJoin.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( VersionedEntityWithNonInverseOneToManyJoinTest.class );
+ }
+
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/VersionedEntityWithNonInverseOneToManyTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/VersionedEntityWithNonInverseOneToManyTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/entitywithmutablecollection/noninverse/VersionedEntityWithNonInverseOneToManyTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.immutable.entitywithmutablecollection.noninverse;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.immutable.entitywithmutablecollection.AbstractEntityWithOneToManyTest;
+
+
+/**
+ * @author Gail Badner
+ */
+public class VersionedEntityWithNonInverseOneToManyTest extends AbstractEntityWithOneToManyTest {
+
+ public VersionedEntityWithNonInverseOneToManyTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "immutable/entitywithmutablecollection/noninverse/ContractVariationVersioned.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( VersionedEntityWithNonInverseOneToManyTest.class );
+ }
+
+}
\ No newline at end of file
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/readonly/ReadOnlyVersionedNodesTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/readonly/ReadOnlyVersionedNodesTest.java 2010-03-10 10:56:16 UTC (rev 18956)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/readonly/ReadOnlyVersionedNodesTest.java 2010-03-10 11:03:08 UTC (rev 18957)
@@ -283,17 +283,17 @@
s.getTransaction().commit();
s.close();
- assertUpdateCount( 0 );
- assertInsertCount( 0 );
+ assertUpdateCount( 1 );
+ assertInsertCount( 1 );
s = openSession();
s.beginTransaction();
parent = ( VersionedNode ) s.get( VersionedNode.class, parent.getId() );
assertEquals( "parent", parent.getName() );
- assertEquals( 0, parent.getChildren().size() );
- assertEquals( 0, parent.getVersion() );
+ assertEquals( 1, parent.getChildren().size() );
+ assertEquals( 1, parent.getVersion() );
child = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
- assertNull( child );
+ assertNotNull( child );
s.delete( parent );
s.getTransaction().commit();
s.close();
@@ -320,7 +320,7 @@
s.getTransaction().commit();
s.close();
- assertUpdateCount( 0 );
+ assertUpdateCount( 1 );
assertInsertCount( 1 );
clearCounts();
@@ -330,7 +330,7 @@
child = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
assertEquals( parent.getName(), "parent" );
assertEquals( 1, parent.getChildren().size() );
- assertEquals( 0, parent.getVersion() );
+ assertEquals( 1, parent.getVersion() );
assertSame( parent, child.getParent() );
assertSame( child, parent.getChildren().iterator().next() );
assertEquals( 0, child.getVersion() );
@@ -366,7 +366,7 @@
s.getTransaction().commit();
s.close();
- assertUpdateCount( 0 );
+ assertUpdateCount( 1 );
assertInsertCount( 1 );
clearCounts();
@@ -376,7 +376,7 @@
child = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
assertEquals( parent.getName(), "parent" );
assertEquals( 1, parent.getChildren().size() );
- assertEquals( 0, parent.getVersion() );
+ assertEquals( 1, parent.getVersion() );
assertSame( parent, child.getParent() );
assertSame( child, parent.getChildren().iterator().next() );
assertEquals( 0, child.getVersion() );
@@ -414,7 +414,7 @@
s.getTransaction().commit();
s.close();
- assertUpdateCount( 0 );
+ assertUpdateCount( 1 );
assertInsertCount( 1 );
clearCounts();
@@ -424,7 +424,7 @@
child = ( VersionedNode ) s.get( VersionedNode.class, child.getId() );
assertEquals( parent.getName(), "parent" );
assertEquals( 1, parent.getChildren().size() );
- assertEquals( 0, parent.getVersion() );
+ assertEquals( 1, parent.getVersion() );
assertSame( parent, child.getParent() );
assertSame( child, parent.getChildren().iterator().next() );
assertEquals( 0, child.getVersion() );
@@ -521,7 +521,7 @@
s.close();
assertUpdateCount( 0 );
- assertInsertCount( 0 );
+ assertInsertCount( 1 );
s = openSession();
s.beginTransaction();
@@ -530,7 +530,7 @@
assertNull( child.getParent() );
assertEquals( 0, child.getVersion() );
parent = ( VersionedNode ) s.get( VersionedNode.class, parent.getId() );
- assertNull( parent );
+ assertNotNull( parent );
s.setReadOnly( child, true );
s.delete( child );
s.getTransaction().commit();
14 years, 9 months
Hibernate SVN: r18956 - in core/trunk/entitymanager/src/main/docbook/en: modules and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-03-10 05:56:16 -0500 (Wed, 10 Mar 2010)
New Revision: 18956
Modified:
core/trunk/entitymanager/src/main/docbook/en/master.xml
core/trunk/entitymanager/src/main/docbook/en/modules/batch.xml
core/trunk/entitymanager/src/main/docbook/en/modules/configuration.xml
core/trunk/entitymanager/src/main/docbook/en/modules/entitymanagerapi.xml
core/trunk/entitymanager/src/main/docbook/en/modules/listeners.xml
core/trunk/entitymanager/src/main/docbook/en/modules/query_criteria.xml
core/trunk/entitymanager/src/main/docbook/en/modules/query_ejbql.xml
core/trunk/entitymanager/src/main/docbook/en/modules/query_native.xml
core/trunk/entitymanager/src/main/docbook/en/modules/transactions.xml
Log:
HHH-4933 finish documentation on JPA 2 and EntityManager, migrate to jHighlight
Modified: core/trunk/entitymanager/src/main/docbook/en/master.xml
===================================================================
--- core/trunk/entitymanager/src/main/docbook/en/master.xml 2010-03-10 10:37:27 UTC (rev 18955)
+++ core/trunk/entitymanager/src/main/docbook/en/master.xml 2010-03-10 10:56:16 UTC (rev 18956)
@@ -70,6 +70,12 @@
<surname>Ebersole</surname>
</author>
+ <author>
+ <firstname>Gavin</firstname>
+
+ <surname>King</surname>
+ </author>
+
<!--TODO add translators like core did -->
</authorgroup>
</bookinfo>
Modified: core/trunk/entitymanager/src/main/docbook/en/modules/batch.xml
===================================================================
--- core/trunk/entitymanager/src/main/docbook/en/modules/batch.xml 2010-03-10 10:37:27 UTC (rev 18955)
+++ core/trunk/entitymanager/src/main/docbook/en/modules/batch.xml 2010-03-10 10:56:16 UTC (rev 18956)
@@ -1,4 +1,4 @@
-<?xml version='1.0' encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
@@ -22,8 +22,8 @@
~ 51 Franklin Street, Fifth Floor
~ Boston, MA 02110-1301 USA
-->
-
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="batch">
<title>Batch processing</title>
@@ -34,7 +34,7 @@
Hibernate reference guide, however, EJB3 persistence differs
slightly.</para>
- <sect1 id="batch-direct">
+ <section id="batch-direct">
<title>Bulk update/delete</title>
<para>As already discussed, automatic and transparent object/relational
@@ -44,7 +44,7 @@
directly in the database will not affect in-memory state. However,
Hibernate provides methods for bulk SQL-style <literal>UPDATE</literal>
and <literal>DELETE</literal> statement execution which are performed
- through EJB-QL (<xref linkend="queryhql" />).</para>
+ through JP-QL (<xref linkend="queryhql" />).</para>
<para>The pseudo-syntax for <literal>UPDATE</literal> and
<literal>DELETE</literal> statements is: <literal>( UPDATE | DELETE )
@@ -63,7 +63,7 @@
<listitem>
<para>No joins (either implicit or explicit) can be specified in a
- bulk EJB-QL query. Sub-queries may be used in the where-clause.</para>
+ bulk JP-QL query. Sub-queries may be used in the where-clause.</para>
</listitem>
<listitem>
@@ -71,26 +71,26 @@
</listitem>
</itemizedlist>
- <para>As an example, to execute an EJB-QL <literal>UPDATE</literal>, use
+ <para>As an example, to execute an JP-QL <literal>UPDATE</literal>, use
the <literal>Query.executeUpdate()</literal> method:</para>
- <programlisting>EntityManager entityManager = entityManagerFactory.createEntityManager();
+ <programlisting role="JAVA" language="JAVA">EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
-String ejbqlUpdate = "update Customer set name = :newName where name = :oldName"
-int updatedEntities = entityManager.createQuery( ejbqlUpdate )
+String jpqlUpdate = "update Customer set name = :newName where name = :oldName"
+int updatedEntities = entityManager.createQuery( jpqlUpdate )
.setParameter( "newName", newName )
.setParameter( "oldName", oldName )
.executeUpdate();
entityManager.getTransaction().commit();
entityManager.close();</programlisting>
- <para>To execute an EJB-QL <literal>DELETE</literal>, use the same
+ <para>To execute an JP-QL <literal>DELETE</literal>, use the same
<literal>Query.executeUpdate()</literal> method (the method is named for
those familiar with JDBC's
<literal>PreparedStatement.executeUpdate()</literal>):</para>
- <programlisting>EntityManager entityManager = entityManagerFactory.createEntityManager();
+ <programlisting role="JAVA" language="JAVA">EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
String hqlDelete = "delete Customer where name = :oldName";
@@ -103,13 +103,13 @@
<para>The <literal>int</literal> value returned by the
<literal>Query.executeUpdate()</literal> method indicate the number of
entities effected by the operation. This may or may not correlate with the
- number of rows effected in the database. An EJB-QL bulk operation might
+ number of rows effected in the database. A JP-QL bulk operation might
result in multiple actual SQL statements being executed, for
joined-subclass, for example. The returned number indicates the number of
actual entities affected by the statement. Going back to the example of
joined-subclass, a delete against one of the subclasses may actually
result in deletes against not just the table to which that subclass is
mapped, but also the "root" table and potentially joined-subclass tables
- further down the inheritence hierarchy.</para>
- </sect1>
-</chapter>
\ No newline at end of file
+ further down the inheritance hierarchy.</para>
+ </section>
+</chapter>
Modified: core/trunk/entitymanager/src/main/docbook/en/modules/configuration.xml
===================================================================
--- core/trunk/entitymanager/src/main/docbook/en/modules/configuration.xml 2010-03-10 10:37:27 UTC (rev 18955)
+++ core/trunk/entitymanager/src/main/docbook/en/modules/configuration.xml 2010-03-10 10:56:16 UTC (rev 18956)
@@ -669,10 +669,10 @@
<class>org.hibernate.ejb.test.Distributor</class>
<class>org.hibernate.ejb.test.Item</class>
<properties>
- <property name="<literal>javax.persistence.jdbc.driver</literal>" value="org.hsqldb.jdbcDriver"/>
- <property name="<literal>javax.persistence.jdbc.user</literal>" value="sa"/>
- <property name="<literal>javax.persistence.jdbc.password</literal>" value=""/>
- <property name="<literal>javax.persistence.jdbc.url</literal>" value="jdbc:hsqldb:."/>
+ <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
+ <property name="javax.persistence.jdbc.user" value="sa"/>
+ <property name="javax.persistence.jdbc.password" value=""/>
+ <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:."/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/
<property name="hibernate.max_fetch_depth" value="3"/>
@@ -857,7 +857,7 @@
<classname>Persistence</classname> class is bootstrap class to create an
entity manager factory.</para>
- <programlisting role="JAVA" language="JAVA">// Use persistence.xml configuration
+ <programlisting role="JAVA" language="JAVA">// Use persistence.xml configuration
EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1")
EntityManager em = emf.createEntityManager(); // Retrieve an application managed entity manager
// Work with the EM
Modified: core/trunk/entitymanager/src/main/docbook/en/modules/entitymanagerapi.xml
===================================================================
--- core/trunk/entitymanager/src/main/docbook/en/modules/entitymanagerapi.xml 2010-03-10 10:37:27 UTC (rev 18955)
+++ core/trunk/entitymanager/src/main/docbook/en/modules/entitymanagerapi.xml 2010-03-10 10:56:16 UTC (rev 18956)
@@ -74,7 +74,7 @@
<literal>new</literal> operator) it is in <literal>new</literal> state.
You can make it persistent by associating it to an entity manager:</para>
- <programlisting>DomesticCat fritz = new DomesticCat();
+ <programlisting language="JAVA" role="JAVA">DomesticCat fritz = new DomesticCat();
fritz.setColor(Color.GINGER);
fritz.setSex('M');
fritz.setName("Fritz");
@@ -93,7 +93,7 @@
<para>Load an entity instance by its identifier value with the entity
manager's <code>find()</code> method:</para>
- <programlisting>cat = em.find(Cat.class, catId);
+ <programlisting language="JAVA" role="JAVA">cat = em.find(Cat.class, catId);
// You may need to wrap the primitive identifiers
long catId = 1234;
@@ -105,7 +105,7 @@
useful to link a child to its parent without having to load the
parent.</para>
- <programlisting>child = new Child();
+ <programlisting language="JAVA" role="JAVA">child = new Child();
child.SetName("Henry");
Parent parent = em.getReference(Parent.class, parentId); //no query to the DB
child.setParent(parent);
@@ -118,7 +118,7 @@
refreshed unless you specify <literal>REFRESH</literal> as a cascade style
of any associations:</para>
- <programlisting>em.persist(cat);
+ <programlisting language="JAVA" role="JAVA">em.persist(cat);
em.flush(); // force the SQL insert and triggers to run
em.refresh(cat); //re-read the state (after the trigger executes)</programlisting>
</section>
@@ -145,7 +145,7 @@
the query. Queries are always created using the current entity
manager:</para>
- <programlisting>List<?> cats = em.createQuery(
+ <programlisting language="JAVA" role="JAVA">List<?> cats = em.createQuery(
"select cat from Cat as cat where cat.birthdate < ?1")
.setParameter(1, date, TemporalType.DATE)
.getResultList();
@@ -176,7 +176,7 @@
type-safe approach is the Criteria API explained in <xref
linkend="querycriteria" />.</para>
- <programlisting>CriteriaQuery<Cat> criteria = builder.createQuery( Cat.class );
+ <programlisting language="JAVA" role="JAVA">CriteriaQuery<Cat> criteria = builder.createQuery( Cat.class );
Root<Cat> cat = criteria.from( Cat.class );
criteria.select( cat );
criteria.where( builder.lt( cat.get( Cat_.birthdate ), catDate ) );
@@ -186,7 +186,7 @@
using JP-QL (note that it's not as type-safe as the compiler has to
trust you with the return type.</para>
- <programlisting>//No downcasting since we pass the return type
+ <programlisting language="JAVA" role="JAVA">//No downcasting since we pass the return type
List<Cat> cats = em.createQuery(
"select cat from Cat as cat where cat.birthdate < ?1", Cat.class)
.setParameter(1, date, TemporalType.DATE)
@@ -205,7 +205,7 @@
<para>JPA queries can return tuples of objects if projection is used.
Each result tuple is returned as an object array:</para>
- <programlisting>Iterator kittensAndMothers = sess.createQuery(
+ <programlisting language="JAVA" role="JAVA">Iterator kittensAndMothers = sess.createQuery(
"select kitten, mother from Cat kitten join kitten.mother mother")
.getResultList()
.iterator();
@@ -233,7 +233,7 @@
persistent state (in other words, they are considered "read
only"):</para>
- <programlisting>Iterator results = em.createQuery(
+ <programlisting language="JAVA" role="JAVA">Iterator results = em.createQuery(
"select cat.color, min(cat.birthdate), count(cat) from Cat cat " +
"group by cat.color")
.getResultList()
@@ -258,7 +258,7 @@
in the query string. Named parameters should be preferred, they are
more robust and easier to read and understand:</para>
- <programlisting>// Named parameter (preferred)
+ <programlisting language="JAVA" role="JAVA">// Named parameter (preferred)
Query q = em.createQuery("select cat from DomesticCat cat where cat.name = :name");
q.setParameter("name", "Fritz");
List cats = q.getResultList();
@@ -284,7 +284,7 @@
number of rows you want to retrieve and/or the first row you want to
retrieve), use the following methods:</para>
- <programlisting>Query q = em.createQuery("select cat from DomesticCat cat");
+ <programlisting language="JAVA" role="JAVA">Query q = em.createQuery("select cat from DomesticCat cat");
q.setFirstResult(20);
q.setMaxResults(10);
List cats = q.getResultList(); //return cats from the 20th position to 29th</programlisting>
@@ -298,20 +298,20 @@
<para>You may also define named queries through annotations:</para>
- <programlisting>@javax.persistence.NamedQuery(name="eg.DomesticCat.by.name.and.minimum.weight",
+ <programlisting language="JAVA" role="JAVA">@javax.persistence.NamedQuery(name="eg.DomesticCat.by.name.and.minimum.weight",
query="select cat from eg.DomesticCat as cat where cat.name = ?1 and cat.weight > ?2")</programlisting>
<para>Parameters are bound programmatically to the named query, before
it is executed:</para>
- <programlisting>Query q = em.createNamedQuery("eg.DomesticCat.by.name.and.minimum.weight");
+ <programlisting language="JAVA" role="JAVA">Query q = em.createNamedQuery("eg.DomesticCat.by.name.and.minimum.weight");
q.setString(1, name);
q.setInt(2, minWeight);
List<?> cats = q.getResultList();</programlisting>
<para>You can also use the slightly more type-safe approach:</para>
- <programlisting>Query q = em.createNamedQuery("eg.DomesticCat.by.name.and.minimum.weight", Cat.class);
+ <programlisting language="JAVA" role="JAVA">Query q = em.createNamedQuery("eg.DomesticCat.by.name.and.minimum.weight", Cat.class);
q.setString(1, name);
q.setInt(2, minWeight);
List<Cat> cats = q.getResultList();</programlisting>
@@ -335,7 +335,7 @@
remember that all entity columns have to be returned for this
mechanism to work):</para>
- <programlisting>@SqlResultSetMapping(name="getItem", entities =
+ <programlisting language="JAVA" role="JAVA">@SqlResultSetMapping(name="getItem", entities =
@EntityResult(entityClass=org.hibernate.ejb.test.Item.class, fields= {
@FieldResult(name="name", column="itemname"),
@FieldResult(name="descr", column="itemdescription")
@@ -358,7 +358,7 @@
<title>Query lock and flush mode</title>
<para>You can adjust the flush mode used when executing the query as
- well as define the lock mode used to load the entities. </para>
+ well as define the lock mode used to load the entities.</para>
<para>Adjusting the flush mode is interesting when one must guaranty
that a query execution will not trigger a flush operation. Most of the
@@ -367,7 +367,7 @@
<para>Adjusting the lock mode is useful if you need to lock the
objects returns by the query to a certain level.</para>
- <programlisting>query.setFlushMode(FlushModeType.COMMIT)
+ <programlisting language="JAVA" role="JAVA">query.setFlushMode(FlushModeType.COMMIT)
.setLockMode(LockModeType.PESSIMISTIC_READ);</programlisting>
<note>
@@ -492,7 +492,7 @@
<methodname>find()</methodname> it, and then manipulate it directly, while
the persistence context is open:</para>
- <programlisting>Cat cat = em.find( Cat.class, new Long(69) );
+ <programlisting language="JAVA" role="JAVA">Cat cat = em.find( Cat.class, new Long(69) );
cat.setName("PK");
em.flush(); // changes to cat are automatically detected and persisted</programlisting>
@@ -510,7 +510,7 @@
by Hibernate) by closing the EntityManager or in a more fine-grained
approach by calling the <methodname>detach()</methodname> method.</para>
- <programlisting>Cat cat = em.find( Cat.class, new Long(69) );
+ <programlisting language="JAVA" role="JAVA">Cat cat = em.find( Cat.class, new Long(69) );
...
em.detach(cat);
cat.setName("New name"); //not propatated to the database</programlisting>
@@ -530,7 +530,7 @@
for persistence of modifications made to detached instances using the
<methodname>EntityManager.merge()</methodname> method:</para>
- <programlisting>// in the first entity manager
+ <programlisting language="JAVA" role="JAVA">// in the first entity manager
Cat cat = firstEntityManager.find(Cat.class, catId);
Cat potentialMate = new Cat();
firstEntityManager.persist(potentialMate);
@@ -563,7 +563,7 @@
not a detached instance) to <literal>merge()</literal>, the entity manager
will figure this out for you:</para>
- <programlisting>// In the first entity manager
+ <programlisting language="JAVA" role="JAVA">// In the first entity manager
Cat cat = firstEntityManager.find(Cat.class, catID);
// In a higher layer of the application, detached
@@ -739,7 +739,7 @@
automatically using the explained routine unless
<methodname>flush()</methodname> is called explicitly.</para>
- <programlisting>em = emf.createEntityManager();
+ <programlisting language="JAVA" role="JAVA">em = emf.createEntityManager();
Transaction tx = em.getTransaction().begin();
em.setFlushMode(FlushModeType.COMMIT); // allow queries to return stale state
@@ -817,11 +817,11 @@
associated entity (or collection of entities), you must indicate that in
the association annotation:</para>
- <programlisting>@OneToOne(cascade=CascadeType.PERSIST)</programlisting>
+ <programlisting language="JAVA" role="JAVA">@OneToOne(cascade=CascadeType.PERSIST)</programlisting>
<para>Cascading options can be combined:</para>
- <programlisting>@OneToOne(cascade= { CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.REFRESH } )</programlisting>
+ <programlisting language="JAVA" role="JAVA">@OneToOne(cascade= { CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.REFRESH } )</programlisting>
<para>You may even use <literal>CascadeType.ALL</literal> to specify that
all operations should be cascaded for a particular association. Remember
@@ -924,4 +924,137 @@
nobody changes the data underneath while pessimistic locks enforce the
lock right away and keep it till the transaction is committed.</para>
</section>
+
+ <section>
+ <title>Caching</title>
+
+ <para>When the second-level cache is activated (see <xref
+ linkend="setup-configuration-packaging" /> and the Hibernate Annotations
+ reference documentation), Hibernate ensures it is used and properly
+ updated. You can however adjust these settings by passing two
+ properties:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>javax.persistence.cache.retrieveMode</literal> which
+ accepts <literal><classname>CacheRetrieveMode</classname></literal>
+ values</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>javax.persistence.cache.storeMode</literal> which
+ accepts <classname>CacheStoreMode</classname> values</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><classname>CacheRetrieveMode</classname> controls how Hibernate
+ accesses information from the second-level cache: <literal>USE</literal>
+ which is the default or <literal>BYPASS</literal> which means ignore the
+ cache. <classname>CacheStoreMode</classname> controls how Hibernate pushes
+ information to the second-level cache: <literal>USE</literal> which is the
+ default and push data in the cache when reading from and writing to the
+ database, <literal>BYPASS</literal> which does not insert new data in the
+ cache (but can invalidate obsolete data) and
+ <classname>REFRESH</classname> which does like default but also force data
+ to be pushed to the cache on database read even if the data is already
+ cached.</para>
+
+ <para>You can set these properties:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>on a particular <classname>EntityManager</classname> via the
+ <methodname>setProperty</methodname> method</para>
+ </listitem>
+
+ <listitem>
+ <para>on a query via a query hint (<methodname>setHint</methodname>
+ method)</para>
+ </listitem>
+
+ <listitem>
+ <para>when calling <methodname>find()</methodname> and
+ <methodname>refresh()</methodname> and passing the properties in the
+ appropriate <classname>Map</classname></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>JPA also introduces an API to interrogate the second-level cache and
+ evict data manually.</para>
+
+ <programlisting language="JAVA" role="JAVA">Cache cache = entityManagerFactory.getCache();
+
+if ( cache.contains(User.class, userId) ) {
+ //load it as we don't hit the DB
+}
+
+cache.evict(User.class, userId); //manually evict user form the second-level cache
+cache.evict(User.class); //evict all users from the second-level cache
+cache.evictAll(); //purge the second-level cache entirely</programlisting>
+ </section>
+
+ <section>
+ <title>Checking the state of an object</title>
+
+ <para>You can check whether an object is managed by the persistence
+ context</para>
+
+ <programlisting language="JAVA" role="JAVA">entityManager.get(Cat.class, catId);
+...
+boolean isIn = entityManager.contains(cat);
+assert isIn;</programlisting>
+
+ <para>You can also check whether an object, an association or a property
+ is lazy or not. You can do that independently of the underlying
+ persistence provider: </para>
+
+ <programlisting language="JAVA" role="JAVA">PersistenceUtil jpaUtil = Persistence.getPersistenceUtil();
+if ( jpaUtil.isLoaded( customer.getAddress() ) {
+ //display address if loaded
+}
+if ( jpaUtil.isLoaded( customer.getOrders ) ) {
+ //display orders if loaded
+}
+if (jpaUtil.isLoaded(customer, "detailedBio") ) {
+ //display property detailedBio if loaded
+}</programlisting>
+
+ <para>However, if you have access to the entityManagerFactory, we
+ recommend you to use:</para>
+
+ <programlisting language="JAVA" role="JAVA">PersistenceUnitUtil jpaUtil = entityManager.getEntityManagerFactory().getPersistenceUnitUtil();
+
+Customer customer = entityManager.get( Customer.class, customerId );
+
+if ( jpaUtil.isLoaded( customer.getAddress() ) {
+ //display address if loaded
+}
+if ( jpaUtil.isLoaded( customer.getOrders ) ) {
+ //display orders if loaded
+}
+if (jpaUtil.isLoaded(customer, "detailedBio") ) {
+ //display property detailedBio if loaded
+}
+
+log.debug( "Customer id {}", jpaUtil.getIdentifier(customer) );</programlisting>
+
+ <para>The performances are likely to be slightly better and you can get
+ the identifier value from an object (using
+ <methodname>getIdentifier()</methodname>).</para>
+
+ <note>
+ <para>These are roughly the counterpart methods of
+ <methodname>Hibernate.isInitialize</methodname>.</para>
+ </note>
+ </section>
+
+ <section>
+ <title>Native Hibernate API</title>
+
+ <para>You can always fall back to the underlying
+ <classname>Session</classname> API from a given
+ <classname>EntityManager</classname>:</para>
+
+ <programlisting language="JAVA" role="JAVA">Session session = entityManager.unwrap(Session.class);</programlisting>
+ </section>
</chapter>
Modified: core/trunk/entitymanager/src/main/docbook/en/modules/listeners.xml
===================================================================
--- core/trunk/entitymanager/src/main/docbook/en/modules/listeners.xml 2010-03-10 10:37:27 UTC (rev 18955)
+++ core/trunk/entitymanager/src/main/docbook/en/modules/listeners.xml 2010-03-10 10:56:16 UTC (rev 18956)
@@ -45,7 +45,7 @@
entity class with the <literal>@EntityListeners</literal>
annotation:</para>
- <programlisting>@Entity
+ <programlisting role="JAVA" language="JAVA">@Entity
@EntityListeners(class=Audit.class)
public class Cat {
@Id private Integer id;
@@ -221,7 +221,7 @@
deployment descriptors. There is also an additional feature that can be
useful: default event listeners.</para>
- <programlisting><?xml version="1.0" encoding="UTF-8"?>
+ <programlisting role="XML" language="XML"><?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Modified: core/trunk/entitymanager/src/main/docbook/en/modules/query_criteria.xml
===================================================================
--- core/trunk/entitymanager/src/main/docbook/en/modules/query_criteria.xml 2010-03-10 10:37:27 UTC (rev 18955)
+++ core/trunk/entitymanager/src/main/docbook/en/modules/query_criteria.xml 2010-03-10 10:56:16 UTC (rev 18956)
@@ -49,7 +49,7 @@
of the
<interfacename>javax.persistence.EntityManagerFactory</interfacename></para>
- <programlisting>CriteriaBuilder builder = entityManagerFactory.getCriteriaBuilder();</programlisting>
+ <programlisting role="JAVA" language="JAVA">CriteriaBuilder builder = entityManagerFactory.getCriteriaBuilder();</programlisting>
<para>The next step is to obtain a
<interfacename>javax.persistence.criteria.CriteriaQuery</interfacename>. You
@@ -57,11 +57,11 @@
<interfacename>javax.persistence.criteria.CriteriaBuilder</interfacename>
for this purpose.</para>
- <programlisting>CriteriaQuery<T> createQuery(Class<T>)</programlisting>
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<T> createQuery(Class<T>)</programlisting>
- <programlisting>CriteriaQuery<Tuple> createTupleQuery()</programlisting>
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Tuple> createTupleQuery()</programlisting>
- <programlisting>CriteriaQuery<Object> createQuery()</programlisting>
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Object> createQuery()</programlisting>
<para>Each serves a different purpose depending on the expected type of the
query results.</para>
@@ -77,7 +77,7 @@
<section id="querycriteria-typedquery">
<title>Typed criteria queries</title>
- <programlisting>CriteriaQuery<T> createQuery(Class<T>)</programlisting>
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<T> createQuery(Class<T>)</programlisting>
<para>The type of the criteria query (aka the <T>) indicates the
expected types in the query result. This might be an entity, an Integer,
@@ -106,7 +106,7 @@
<area coords="4" id="ex.criteria.typedquery.entity.3" />
</areaspec>
- <programlisting>CriteriaQuery<Person> criteria = builder.createQuery( Person.class );
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Person> criteria = builder.createQuery( Person.class );
Root<Person> personRoot = criteria.from( Person.class );
criteria.select( personRoot );
criteria.where( builder.equal( personRoot.get( Person_.eyeColor ), "brown" ) );
@@ -160,7 +160,7 @@
<area coords="3" id="ex.criteria.typedquery.attr.2" />
</areaspec>
- <programlisting>CriteriaQuery<Integer> criteria = builder.createQuery( Integer.class );
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Integer> criteria = builder.createQuery( Integer.class );
Root<Person> personRoot = criteria.from( Person.class );
criteria.select( personRoot.get( Person_.age ) );
criteria.where( builder.equal( personRoot.get( Person_.eyeColor ), "brown" ) );
@@ -195,7 +195,7 @@
<area coords="3" id="ex.criteria.typedquery.expr.1" />
</areaspec>
- <programlisting>CriteriaQuery<Integer> criteria = builder.createQuery( Integer.class );
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Integer> criteria = builder.createQuery( Integer.class );
Root<Person> personRoot = criteria.from( Person.class );
criteria.select( builder.max( personRoot.get( Person_.age ) ) );
criteria.where( builder.equal( personRoot.get( Person_.eyeColor ), "brown" ) );
@@ -239,7 +239,7 @@
<area coords="5" id="ex.criteria.typedquery.array.2" />
</areaspec>
- <programlisting>CriteriaQuery<Object[]> criteria = builder.createQuery( Object[].class );
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Object[]> criteria = builder.createQuery( Object[].class );
Root<Person> personRoot = criteria.from( Person.class );
Path<Long> idPath = personRoot.get( Person_.id );
Path<Integer> agePath = personRoot.get( Person_.age );
@@ -284,7 +284,7 @@
<area coords="5" id="ex.criteria.typedquery.array2.2" />
</areaspec>
- <programlisting>CriteriaQuery<Object[]> criteria = builder.createQuery( Object[].class );
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Object[]> criteria = builder.createQuery( Object[].class );
Root<Person> personRoot = criteria.from( Person.class );
Path<Long> idPath = personRoot.get( Person_.id );
Path<Integer> agePath = personRoot.get( Person_.age );
@@ -351,7 +351,7 @@
</areaset>
</areaspec>
- <programlisting>public class PersonWrapper {
+ <programlisting role="JAVA" language="JAVA">public class PersonWrapper {
private final Long id;
private final Integer age;
public PersonWrapper(Long id, Integer age) {
@@ -433,7 +433,7 @@
</areaset>
</areaspec>
- <programlisting>CriteriaQuery<Tuple> criteria = builder.createTupleQuery();
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Tuple> criteria = builder.createTupleQuery();
Root<Person> personRoot = criteria.from( Person.class );
Path<Long> idPath = personRoot.get( Person_.id );
Path<Integer> agePath = personRoot.get( Person_.age );
@@ -493,7 +493,7 @@
<term>typed</term>
<listitem>
- <programlisting><X> X get(TupleElement<X> tupleElement)</programlisting>
+ <programlisting role="JAVA" language="JAVA"><X> X get(TupleElement<X> tupleElement)</programlisting>
<para>This allows typed access to the underlying tuple elements.
We see this in <xref linkend="ex-criteria-typedquery-tuple" /> in
@@ -508,9 +508,9 @@
<term>positional</term>
<listitem>
- <programlisting>Object get(int i)</programlisting>
+ <programlisting role="JAVA" language="JAVA">Object get(int i)</programlisting>
- <programlisting><X> X get(int i, Class<X> type)</programlisting>
+ <programlisting role="JAVA" language="JAVA"><X> X get(int i, Class<X> type)</programlisting>
<para>Very similar to what we saw in <xref
linkend="ex-criteria-typedquery-array" /> and <xref
@@ -527,9 +527,9 @@
<term>aliased</term>
<listitem>
- <programlisting>Object get(String alias)</programlisting>
+ <programlisting role="JAVA" language="JAVA">Object get(String alias)</programlisting>
- <programlisting><X> X get(String alias, Class<X> type)</programlisting>
+ <programlisting role="JAVA" language="JAVA"><X> X get(String alias, Class<X> type)</programlisting>
<para>Again, only the second form here provides typing, because
the user explicitly provides the typing on access. We have not
@@ -574,14 +574,14 @@
<methodname>from</methodname> methods on
<interfacename>javax.persistence.criteria.CriteriaQuery</interfacename>:</para>
- <programlisting><X> Root<X> from(Class<X>)</programlisting>
+ <programlisting role="JAVA" language="JAVA"><X> Root<X> from(Class<X>)</programlisting>
- <programlisting><X> Root<X> from(EntityType<X>)</programlisting>
+ <programlisting role="JAVA" language="JAVA"><X> Root<X> from(EntityType<X>)</programlisting>
<example>
<title>Adding a root</title>
- <programlisting>CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class );
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class );
// create and add the root
person.from( Person.class );
...</programlisting>
@@ -593,7 +593,7 @@
product</ulink> between the newly added root and the others. Here is an
example matching all single men and all single women:</para>
- <programlisting>CriteriaQuery query = builder.createQuery();
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery query = builder.createQuery();
Root<Person> men = query.from( Person.class );
Root<Person> women = query.from( Person.class );
Predicate menRestriction = builder.and(
@@ -620,7 +620,7 @@
<example id="criteria-join-singular">
<title>Example with Embedded and ManyToOne</title>
- <programlisting>CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class );
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class );
Root<Person> personRoot = person.from( Person.class );
// Person.address is an embedded attribute
Join<Person,Address> personAddress = personRoot.join( Person_.address );
@@ -632,7 +632,7 @@
<example id="criteria-join-plural">
<title>Example with Collections</title>
- <programlisting>CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class );
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class );
Root<Person> personRoot = person.from( Person.class );
Join<Person,Order> orders = personRoot.join( Person_.orders );
Join<Order,LineItem> orderLines = orders.join( Order_.lineItems );
@@ -652,7 +652,7 @@
<example id="criteria-fetch-singular">
<title>Example with Embedded and ManyToOne</title>
- <programlisting>CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class );
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class );
Root<Person> personRoot = person.from( Person.class );
// Person.address is an embedded attribute
Join<Person,Address> personAddress = personRoot.fetch( Person_.address );
@@ -672,7 +672,7 @@
<example id="criteria-fetch-plural">
<title>Example with Collections</title>
- <programlisting>CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class );
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class );
Root<Person> personRoot = person.from( Person.class );
Join<Person,Order> orders = personRoot.fetch( Person_.orders );
Join<Order,LineItem> orderLines = orders.fetch( Order_.lineItems );
@@ -704,7 +704,7 @@
<area coords="7" id="ex.criteria.param.3" />
</areaspec>
- <programlisting>CriteriaQuery<Person> criteria = build.createQuery( Person.class );
+ <programlisting role="JAVA" language="JAVA">CriteriaQuery<Person> criteria = build.createQuery( Person.class );
Root<Person> personRoot = criteria.from( Person.class );
criteria.select( personRoot );
ParameterExpression<String> eyeColorParam = builder.parameter( String.class );
Modified: core/trunk/entitymanager/src/main/docbook/en/modules/query_ejbql.xml
===================================================================
--- core/trunk/entitymanager/src/main/docbook/en/modules/query_ejbql.xml 2010-03-10 10:37:27 UTC (rev 18955)
+++ core/trunk/entitymanager/src/main/docbook/en/modules/query_ejbql.xml 2010-03-10 10:56:16 UTC (rev 18956)
@@ -1,4 +1,4 @@
-<?xml version='1.0' encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
@@ -22,19 +22,23 @@
~ 51 Franklin Street, Fifth Floor
~ Boston, MA 02110-1301 USA
-->
-
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="queryhql">
- <title>EJB-QL: The Object Query Language</title>
+ <title>JP-QL: The Object Query Language</title>
- <para>
- EJB3-QL has been heavily inspired by HQL, the native Hibernate Query Language. Both
- are therefore very close to SQL, but portable and independent of the database schema.
- People familiar with HQL shouldn't have any problem using EJB-QL. Actually, you
- use the same query API for EJB-QL and HQL queries. Portable EJB3 applications however
- should stick to EJB-QL or similar vendor extensions are needed.
- </para>
+ <para>The Java Persistence Query Language (JP-QL) has been heavily inspired
+ by HQL, the native Hibernate Query Language. Both are therefore very close
+ to SQL, but portable and independent of the database schema. People familiar
+ with HQL shouldn't have any problem using JP-QL. In fact HQL is a strict
+ superset of JP-QL and you use the same query API for both types of queries.
+ Portable JPA applications however should stick to JP-QL.</para>
+ <note>
+ <para>For a type-safe approach to query, we highly recommend you to use
+ the Criteria query, see <xref linkend="querycriteria" />.</para>
+ </note>
+
<sect1 id="queryhql-casesensitivity">
<title>Case Sensitivity</title>
@@ -45,7 +49,7 @@
<literal>org.hibernate.eg.Foo</literal> and <literal>foo.barSet</literal>
is not <literal>foo.BARSET</literal>.</para>
- <para>This manual uses lowercase EJBQL keywords. Some users find queries
+ <para>This manual uses lowercase JP-QL keywords. Some users find queries
with uppercase keywords more readable, but we find this convention ugly
when embedded in Java code.</para>
</sect1>
@@ -53,28 +57,28 @@
<sect1 id="queryhql-from">
<title>The from clause</title>
- <para>The simplest possible EJB-QL query is of the form:</para>
+ <para>The simplest possible JP-QL query is of the form:</para>
<programlisting>select c from eg.Cat c</programlisting>
<para>which simply returns all instances of the class
<literal>eg.Cat</literal>. Unlike HQL, the select clause is not optional
- in EJB-QL. We don't usually need to qualify the class name, since the
+ in JP-QL. We don't usually need to qualify the class name, since the
entity name defaults to the unqualified class name
(<literal>@Entity</literal>). So we almost always just write:</para>
<programlisting>select c from Cat c</programlisting>
<para>As you may have noticed you can assign aliases to classes, the
- <literal>as</literal> keywork is optional. An alias allows you to refer
- to <literal>Cat</literal> in other parts of the query.</para>
+ <literal>as</literal> keywork is optional. An alias allows you to refer to
+ <literal>Cat</literal> in other parts of the query.</para>
<programlisting>select cat from Cat as cat</programlisting>
<para>Multiple classes may appear, resulting in a cartesian product or
"cross" join.</para>
- <programlisting>select form, param from Formula as form, Parameter as param</programlisting>
+ <programlisting>select from, param from Formula as form, Parameter as param</programlisting>
<para>It is considered good practice to name query aliases using an
initial lowercase, consistent with Java naming standards for local
@@ -88,7 +92,7 @@
elements of a collection of values, using a
<literal>join</literal>.</para>
- <programlisting>select cat, mate, kitten from Cat as cat
+ <programlisting>select cat, mate, kitten from Cat as cat
inner join cat.mate as mate
left outer join cat.kittens as kitten</programlisting>
@@ -109,18 +113,18 @@
<para>The <literal>inner join</literal>, <literal>left outer
join</literal> constructs may be abbreviated.</para>
- <programlisting>select cat, mate, kitten from Cat as cat
+ <programlisting>select cat, mate, kitten from Cat as cat
join cat.mate as mate
left join cat.kittens as kitten</programlisting>
<para>In addition, a "fetch" join allows associations or collections of
values to be initialized along with their parent objects, using a single
select. This is particularly useful in the case of a collection. It
- effectively overrides the fetching options in the associations and collection
- mapping metadata. See the Performance chapter of the Hibernate reference guide
- for more information.</para>
+ effectively overrides the fetching options in the associations and
+ collection mapping metadata. See the Performance chapter of the Hibernate
+ reference guide for more information.</para>
- <programlisting>select cat from Cat as cat
+ <programlisting>select cat from Cat as cat
inner join fetch cat.mate
left join fetch cat.kittens</programlisting>
@@ -141,16 +145,13 @@
<literal>iterate()</literal>. Nor should <literal>fetch</literal> be used
together with <literal>setMaxResults()</literal> or
<literal>setFirstResult()</literal>. It is possible to create a cartesian
- product by join fetching more than one collection in a query (as in the example
- above), be careful the result of this product isn't bigger than you expect.
- Join fetching multiple collection roles also sometimes gives unexpected results for
- bag mappings, so be careful about how you formulate your queries in this case.</para>
+ product by join fetching more than one collection in a query (as in the
+ example above), be careful the result of this product isn't bigger than
+ you expect. Join fetching multiple collection roles gives unexpected
+ results for bag mappings as it is impossible for Hibernate to
+ differentiate legit duplicates of a given bag from artificial duplicates
+ created by the multi-table cartesian product.</para>
- <para>
- TODO: The last statement is useless and typical developer thinking, please elaborate.
- The word "sometimes" should never appear in any technical documentation.
- </para>
-
<para>If you are using property-level lazy fetching (with bytecode
instrumentation), it is possible to force Hibernate to fetch the lazy
properties immediately (in the first query) using <literal>fetch all
@@ -200,7 +201,8 @@
inner join mother.mate as mate
left outer join mother.kittens as offspr</programlisting>
- <para>or as an actual typesafe Java object,</para>
+ <para>or as an actual type-safe Java object (often called a view
+ object),</para>
<programlisting>select new Family(mother, mate, offspr)
from DomesticCat as mother
@@ -254,7 +256,8 @@
</itemizedlist>
<para>You may use arithmetic operators, concatenation, and recognized SQL
- functions in the select clause (dpending on configured dialect, HQL specific feature):</para>
+ functions in the select clause (dpending on configured dialect, HQL
+ specific feature):</para>
<programlisting>select cat.weight + sum(kitten.weight)
from Cat cat
@@ -281,7 +284,7 @@
<para>returns instances not only of <literal>Cat</literal>, but also of
subclasses like <literal>DomesticCat</literal>. Hibernate queries may name
<emphasis>any</emphasis> Java class or interface in the
- <literal>from</literal> clause (portable EJB-QL queries should only name
+ <literal>from</literal> clause (portable JP-QL queries should only name
mapped entities). The query will return instances of all persistent
classes that extend that class or implement the interface. The following
query would return all persistent objects:</para>
@@ -342,7 +345,8 @@
<para>The special property (lowercase) <literal>id</literal> may be used
to reference the unique identifier of an object. (You may also use its
- mapped identifer property name.). Note that this keyword is specific to HQL.</para>
+ mapped identifer property name.). Note that this keyword is specific to
+ HQL.</para>
<programlisting>select cat from Cat as cat where cat.id = 123
@@ -427,14 +431,20 @@
</listitem>
<listitem>
+ <para><literal>exists</literal>, <literal>all</literal>,
+ <literal>any</literal>, <literal>some</literal> (taking
+ subqueries)</para>
+ </listitem>
+
+ <listitem>
<para>"Simple" case, <literal>case ... when ... then ... else ...
end</literal>, and "searched" case, <literal>case when ... then ...
- else ... end (specific to HQL)</literal></para>
+ else ... end</literal></para>
</listitem>
<listitem>
<para>string concatenation <literal>...||...</literal> or
- <literal>concat(...,...) (use concat() for portable EJB-QL
+ <literal>concat(...,...) (use concat() for portable JP-QL
queries)</literal></para>
</listitem>
@@ -452,9 +462,9 @@
</listitem>
<listitem>
- <para>Any function or operator defined by EJB-QL 3.0:
- <literal>substring(), trim(), lower(), upper(), length(), locate(),
- abs(), sqrt(), bit_length()</literal></para>
+ <para>Any function or operator: <literal>substring(), trim(), lower(),
+ upper(), length(), locate(), abs(), sqrt(),
+ bit_length()</literal></para>
</listitem>
<listitem>
@@ -463,6 +473,13 @@
</listitem>
<listitem>
+ <para><literal>TYPE ... in ...</literal>, where the first argument is
+ an identifier variable and the second argument is the subclass to
+ restrict polymorphism to (or a list of subclasses surrounded by
+ parenthesis)</para>
+ </listitem>
+
+ <listitem>
<para><literal>cast(... as ...)</literal>, where the second argument
is the name of a Hibernate type, and <literal>extract(... from
...)</literal> if ANSI <literal>cast()</literal> and
@@ -491,6 +508,11 @@
</listitem>
<listitem>
+ <para>JDBC escape syntax for dates (dependent on your JDBC driver
+ support) (eg. <code>where date = {d '2008-12-31'}</code>)</para>
+ </listitem>
+
+ <listitem>
<para>Java <literal>public static final</literal> constants
<literal>eg.Color.TABBY</literal></para>
</listitem>
@@ -548,7 +570,7 @@
supported when passed the element or index set of a collection
(<literal>elements</literal> and <literal>indices</literal> functions) or
the result of a subquery (see below). While subqueries are supported by
- EJB-QL, <literal>elements</literal> and <literal>indices</literal> are
+ JP-QL, <literal>elements</literal> and <literal>indices</literal> are
specific HQL features.</para>
<programlisting>select mother from Cat as mother, Cat as kit
@@ -567,8 +589,14 @@
<literal>elements</literal>, <literal>indices</literal>,
<literal>minindex</literal>, <literal>maxindex</literal>,
<literal>minelement</literal>, <literal>maxelement</literal> - may only be
- used in the where clause in Hibernate3.</para>
+ used in the where clause in Hibernate.</para>
+ <para>JP-QL lets you access the key or the value of a map by using the
+ <literal>KEY()</literal> and <literal>VALUE()</literal> operations (even
+ access the Entry object using <literal>ENTRY()</literal>)</para>
+
+ <programlisting>SELECT i.name, VALUE(p) FROM Item i JOIN i.photos p WHERE KEY(p) LIKE ‘%egret’</programlisting>
+
<para>In HQL, elements of indexed collections (arrays, lists, maps) may be
referred to by index (in a where clause only):</para>
@@ -687,7 +715,7 @@
<sect1 id="queryhql-subqueries">
<title>Subqueries</title>
- <para>For databases that support subselects, EJB-QL supports subqueries
+ <para>For databases that support subselects, JP-QL supports subqueries
within queries. A subquery must be surrounded by parentheses (often by an
SQL aggregate function call). Even correlated subqueries (subqueries that
refer to an alias in the outer query) are allowed.</para>
@@ -737,11 +765,11 @@
</sect1>
<sect1 id="queryhql-examples">
- <title>EJB-QL examples</title>
+ <title>JP-QL examples</title>
<para>Hibernate queries can be quite powerful and complex. In fact, the
power of the query language is one of Hibernate's main selling points (and
- now EJB-QL). Here are some example queries very similar to queries that I
+ now JP-QL). Here are some example queries very similar to queries that I
used on a recent project. Note that most queries you will write are much
simpler than these!</para>
@@ -848,8 +876,8 @@
<sect1 id="queryhql-bulk">
<title>Bulk UPDATE & DELETE Statements</title>
- <para>Hibernate now supports UPDATE and DELETE statements in HQL/EJB-QL. See <xref
- linkend="batch-direct" /> for details.</para>
+ <para>Hibernate now supports UPDATE and DELETE statements in HQL/JP-QL.
+ See <xref linkend="batch-direct" /> for details.</para>
</sect1>
<sect1 id="queryhql-tipstricks">
@@ -888,4 +916,4 @@
group by usr.id, usr.name
having count(msg) = 0</programlisting>
</sect1>
-</chapter>
\ No newline at end of file
+</chapter>
Modified: core/trunk/entitymanager/src/main/docbook/en/modules/query_native.xml
===================================================================
--- core/trunk/entitymanager/src/main/docbook/en/modules/query_native.xml 2010-03-10 10:37:27 UTC (rev 18955)
+++ core/trunk/entitymanager/src/main/docbook/en/modules/query_native.xml 2010-03-10 10:56:16 UTC (rev 18956)
@@ -1,4 +1,4 @@
-<?xml version='1.0' encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
@@ -22,8 +22,8 @@
~ 51 Franklin Street, Fifth Floor
~ Boston, MA 02110-1301 USA
-->
-
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="query_native">
<title>Native query</title>
@@ -31,7 +31,7 @@
database. This is useful if you want to utilize database specific features
such as query hints or the CONNECT BY option in Oracle. It also provides a
clean migration path from a direct SQL/JDBC based application to Hibernate.
- Note that Hibernate3 allows you to specify handwritten SQL (including stored
+ Note that Hibernate allows you to specify handwritten SQL (including stored
procedures) for all create, update, delete, and load operations (please
refer to the reference guide for more information.)</para>
@@ -42,10 +42,10 @@
description will help the <literal>EntityManager</literal> to map your
columns onto entity properties. This is done using the
<literal>@SqlResultSetMapping</literal> annotation. Each
- <literal>@SqlResultSetMapping </literal>has a name wich is used when
+ <literal>@SqlResultSetMapping </literal>has a name which is used when
creating a SQL query on <literal>EntityManager</literal>.</para>
- <programlisting>@SqlResultSetMapping(name="GetNightAndArea", entities={
+ <programlisting role="JAVA" language="JAVA">@SqlResultSetMapping(name="GetNightAndArea", entities={
@EntityResult(name="org.hibernate.test.annotations.query.Night", fields = {
@FieldResult(name="id", column="nid"),
@FieldResult(name="duration", column="night_duration"),
@@ -65,7 +65,7 @@
<para>You can also define scalar results and even mix entity results and
scalar results</para>
- <programlisting>@SqlResultSetMapping(name="ScalarAndEntities",
+ <programlisting role="JAVA" language="JAVA">@SqlResultSetMapping(name="ScalarAndEntities",
entities={
@EntityResult(name="org.hibernate.test.annotations.query.Night", fields = {
@FieldResult(name="id", column="nid"),
@@ -103,7 +103,7 @@
third one (not yet supported by Hibernate entity manager), returns pure
scalar results.</para>
- <programlisting>String sqlQuery = "select night.id nid, night.night_duration, night.night_date, area.id aid, "
+ <programlisting role="JAVA" language="JAVA">String sqlQuery = "select night.id nid, night.night_duration, night.night_date, area.id aid, "
+ "night.area_id, area.name from Night night, Area area where night.area_id = area.id "
+ "and night.night_duration >= ?";
Query q = entityManager.createNativeQuery(sqlQuery, "GetNightAndArea");
@@ -113,7 +113,7 @@
<para>This native query returns nights and area based on the
<literal>GetNightAndArea</literal> result set.</para>
- <programlisting>String sqlQuery = "select * from tbl_spaceship where owner = ?";
+ <programlisting role="JAVA" language="JAVA">String sqlQuery = "select * from tbl_spaceship where owner = ?";
Query q = entityManager.createNativeQuery(sqlQuery, SpaceShip.class);
q.setParameter( 1, "Han" );
q.getResultList();</programlisting>
@@ -125,12 +125,12 @@
<sect1>
<title>Named queries</title>
- <para>Native named queries share the same calling API than EJB-QL named
+ <para>Native named queries share the same calling API than JP-QL named
queries. Your code doesn't need to know the difference between the two.
- This is very useful for migration from SQL to EJB-QL:</para>
+ This is very useful for migration from SQL to JP-QL:</para>
- <programlisting>Query q = entityManager.createNamedQuery("getSeasonByNativeQuery");
+ <programlisting role="JAVA" language="JAVA">Query q = entityManager.createNamedQuery("getSeasonByNativeQuery");
q.setParameter( 1, name );
Season season = (Season) q.getSingleResult();</programlisting>
</sect1>
-</chapter>
\ No newline at end of file
+</chapter>
Modified: core/trunk/entitymanager/src/main/docbook/en/modules/transactions.xml
===================================================================
--- core/trunk/entitymanager/src/main/docbook/en/modules/transactions.xml 2010-03-10 10:37:27 UTC (rev 18955)
+++ core/trunk/entitymanager/src/main/docbook/en/modules/transactions.xml 2010-03-10 10:56:16 UTC (rev 18956)
@@ -418,7 +418,7 @@
mechanism behind the scenes. The common entity manager and transaction
handling idiom looks like this:</para>
- <programlisting>// Non-managed environment idiom
+ <programlisting role="JAVA" language="JAVA">// Non-managed environment idiom
EntityManager em = emf.createEntityManager();
EntityTransaction tx = null;
try {
@@ -501,7 +501,7 @@
<para>If you use bean-managed transactions (BMT), the code will look
like this:</para>
- <programlisting>// BMT idiom
+ <programlisting role="JAVA" language="JAVA">// BMT idiom
@Resource public UserTransaction utx;
@Resource public EntityManagerFactory factory;
@@ -554,13 +554,13 @@
<para>Our entity manager/transaction management idiom for CMT and EJB3
container-use is reduced to this:</para>
- <programlisting>//CMT idiom through injection
+ <programlisting role="JAVA" language="JAVA">//CMT idiom through injection
@PersistenceContext(name="sample") EntityManager em;</programlisting>
<para>Or this if you use Java Context and Dependency Injection
(CDI).</para>
- <programlisting>@Inject EntityManager em;</programlisting>
+ <programlisting role="JAVA" language="JAVA">@Inject EntityManager em;</programlisting>
<para>In other words, all you have to do in a managed environment is to
inject the <literal>EntityManager</literal>, do your data access work,
@@ -834,7 +834,7 @@
the least efficient in terms of database access. It is the approach most
similar to EJB2 entities:</para>
- <programlisting>// foo is an instance loaded by a previous entity manager
+ <programlisting role="JAVA" language="JAVA">// foo is an instance loaded by a previous entity manager
em = factory.createEntityManager();
EntityTransaction t = em.getTransaction();
t.begin();
@@ -895,7 +895,7 @@
performance impact. The following examples show the idiom in a
non-managed environment:</para>
- <programlisting>// foo is an instance loaded earlier by the extended entity manager
+ <programlisting role="JAVA" language="JAVA">// foo is an instance loaded earlier by the extended entity manager
em.getTransaction.begin(); // new connection to data store is obtained and tx started
foo.setProperty("bar");
em.getTransaction().commit(); // End tx, flush and check version, disconnect</programlisting>
@@ -936,7 +936,7 @@
persistence context and then merges the changes using
<literal>EntityManager.merge()</literal>:</para>
- <programlisting>// foo is an instance loaded by a non-extended entity manager
+ <programlisting role="JAVA" language="JAVA">// foo is an instance loaded by a non-extended entity manager
foo.setProperty("bar");
entityManager = factory.createEntityManager();
entityManager.getTransaction().begin();
14 years, 9 months
Hibernate SVN: r18955 - core/trunk/entitymanager/src/main/java/org/hibernate/ejb.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-03-10 05:37:27 -0500 (Wed, 10 Mar 2010)
New Revision: 18955
Modified:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
Log:
HHH-4994 pass the properties variable
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2010-03-10 10:25:03 UTC (rev 18954)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2010-03-10 10:37:27 UTC (rev 18955)
@@ -530,7 +530,7 @@
}
public <T> T find(Class<T> entityClass, Object primaryKey, Map<String, Object> properties) {
- return find( entityClass, primaryKey, null, null );
+ return find( entityClass, primaryKey, null, properties );
}
@SuppressWarnings("unchecked")
@@ -654,7 +654,7 @@
}
public void refresh(Object entity, Map<String, Object> properties) {
- refresh( entity, null, null );
+ refresh( entity, null, properties );
}
public void refresh(Object entity, LockModeType lockModeType) {
14 years, 9 months
Hibernate SVN: r18954 - in core/trunk/core/src/main/java/org/hibernate: persister/entity and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: gbadner
Date: 2010-03-10 05:25:03 -0500 (Wed, 10 Mar 2010)
New Revision: 18954
Modified:
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java
core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
Log:
HHH-4993 : Updates to read-only entity associations made while in persistent state are ignored by flush
Modified: core/trunk/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java 2010-03-10 09:59:43 UTC (rev 18953)
+++ core/trunk/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java 2010-03-10 10:25:03 UTC (rev 18954)
@@ -141,7 +141,7 @@
Map.Entry me = list[i];
EntityEntry entry = (EntityEntry) me.getValue();
Status status = entry.getStatus();
- if ( status == Status.MANAGED || status == Status.SAVING ) {
+ if ( status == Status.MANAGED || status == Status.SAVING || status == Status.READ_ONLY ) {
cascadeOnFlush( session, entry.getPersister(), me.getKey(), anything );
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java 2010-03-10 09:59:43 UTC (rev 18953)
+++ core/trunk/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java 2010-03-10 10:25:03 UTC (rev 18954)
@@ -478,7 +478,7 @@
}
private boolean isCollectionDirtyCheckNecessary(EntityPersister persister, Status status) {
- return status==Status.MANAGED &&
+ return ( status == Status.MANAGED || status == Status.READ_ONLY ) &&
persister.isVersioned() &&
persister.hasCollections();
}
Modified: core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2010-03-10 09:59:43 UTC (rev 18953)
+++ core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2010-03-10 10:25:03 UTC (rev 18954)
@@ -2759,14 +2759,8 @@
if ( entry == null && ! isMutable() ) {
throw new IllegalStateException( "Updating immutable entity that is not in session yet!" );
}
- if ( entry != null && ! isModifiableEntity( entry ) && entry.getStatus() != Status.DELETED ) {
- throw new IllegalStateException( "Updating non-modifiable entity that is not being deleted!" );
- }
- if ( ( entityMetamodel.isDynamicUpdate() || ! isModifiableEntity( entry ) ) && dirtyFields != null ) {
- // For the following cases we need to generate the UPDATE SQL
- // - dynamic-update="true"
- // - a non-modifiable entity (e.g., read-only or immutable) needs to have
- // references to transient entities set to null before being deleted
+ if ( ( entityMetamodel.isDynamicUpdate() && dirtyFields != null ) ) {
+ // We need to generate the UPDATE SQL when dynamic-update="true"
propsToUpdate = getPropertiesToUpdate( dirtyFields, hasDirtyCollection );
// don't need to check laziness (dirty checking algorithm handles that)
updateStrings = new String[span];
@@ -2776,6 +2770,26 @@
null;
}
}
+ else if ( ! isModifiableEntity( entry ) ) {
+ // We need to generate UPDATE SQL when a non-modifiable entity (e.g., read-only or immutable)
+ // needs:
+ // - to have references to transient entities set to null before being deleted
+ // - to have version incremented do to a "dirty" association
+ // If dirtyFields == null, then that means that there are no dirty properties to
+ // to be updated; an empty array for the dirty fields needs to be passed to
+ // getPropertiesToUpdate() instead of null.
+ propsToUpdate = getPropertiesToUpdate(
+ ( dirtyFields == null ? ArrayHelper.EMPTY_INT_ARRAY : dirtyFields ),
+ hasDirtyCollection
+ );
+ // don't need to check laziness (dirty checking algorithm handles that)
+ updateStrings = new String[span];
+ for ( int j = 0; j < span; j++ ) {
+ updateStrings[j] = tableUpdateNeeded[j] ?
+ generateUpdateString( propsToUpdate, j, oldFields, j == 0 && rowId != null ) :
+ null;
+ }
+ }
else {
// For the case of dynamic-update="false", or no snapshot, we use the static SQL
updateStrings = getUpdateStrings(
14 years, 9 months
Hibernate SVN: r18953 - core/trunk/core/src/main/java/org/hibernate/engine.
by hibernate-commits@lists.jboss.org
Author: gbadner
Date: 2010-03-10 04:59:43 -0500 (Wed, 10 Mar 2010)
New Revision: 18953
Modified:
core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java
Log:
HHH-4958 : Immutable entity snapshot is retained after insert
Modified: core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java 2010-03-10 08:43:08 UTC (rev 18952)
+++ core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java 2010-03-10 09:59:43 UTC (rev 18953)
@@ -74,7 +74,8 @@
final boolean lazyPropertiesAreUnfetched) {
this.status=status;
this.previousStatus = null;
- this.loadedState=loadedState;
+ // only retain loaded state if the status is not Status.READ_ONLY
+ if ( status != Status.READ_ONLY ) { this.loadedState = loadedState; }
this.id=id;
this.rowId=rowId;
this.existsInDatabase=existsInDatabase;
14 years, 9 months
Hibernate SVN: r18952 - jpamodelgen/trunk/src/test/resources/org/hibernate/jpamodelgen/test/xmlmapped.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-03-10 03:43:08 -0500 (Wed, 10 Mar 2010)
New Revision: 18952
Modified:
jpamodelgen/trunk/src/test/resources/org/hibernate/jpamodelgen/test/xmlmapped/jpa1-orm.xml
Log:
Clarify bckward compatibility test on orm_1_0.xml
Modified: jpamodelgen/trunk/src/test/resources/org/hibernate/jpamodelgen/test/xmlmapped/jpa1-orm.xml
===================================================================
--- jpamodelgen/trunk/src/test/resources/org/hibernate/jpamodelgen/test/xmlmapped/jpa1-orm.xml 2010-03-10 08:42:18 UTC (rev 18951)
+++ jpamodelgen/trunk/src/test/resources/org/hibernate/jpamodelgen/test/xmlmapped/jpa1-orm.xml 2010-03-10 08:43:08 UTC (rev 18952)
@@ -5,6 +5,7 @@
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
version="1.0"
>
+ <!-- use orm_1_0 on purpose (backward compatibility test -->
<package>org.hibernate.jpamodelgen.test.model</package>
<entity class="Airplane" metadata-complete="true" access="PROPERTY">
<attributes>
14 years, 9 months
Hibernate SVN: r18951 - in core/trunk: annotations/src/test/resources/org/hibernate/test/annotations/configuration and 12 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-03-10 03:42:18 -0500 (Wed, 10 Mar 2010)
New Revision: 18951
Modified:
core/trunk/annotations/src/main/docbook/en/modules/xml-overriding.xml
core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/configuration/orm.xml
core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/idclass/xml/HabitatSpeciesLink.xml
core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/reflection/metadata-complete.xml
core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/reflection/orm.xml
core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/xml/ejb3/orm2.xml
core/trunk/entitymanager/src/main/docbook/en/modules/listeners.xml
core/trunk/entitymanager/src/test/bundles/defaultpar/META-INF/orm.xml
core/trunk/entitymanager/src/test/bundles/defaultpar_1_0/META-INF/orm.xml
core/trunk/entitymanager/src/test/bundles/excludehbmpar/META-INF/orm2.xml
core/trunk/entitymanager/src/test/bundles/explicitpar/META-INF/orm.xml
core/trunk/entitymanager/src/test/bundles/externaljar/META-INF/orm.xml
core/trunk/entitymanager/src/test/bundles/war/WEB-INF/classes/META-INF/orm.xml
core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/orm.xml
core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/orm2.xml
core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/orm3.xml
core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/sequences/orm.xml
core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/sequences/orm2.xml
core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/sequences/orm3.xml
Log:
HHH-4933 Move all orm.xml files to orm_2_0.xml except on a few tests for backward compatiblilty
Modified: core/trunk/annotations/src/main/docbook/en/modules/xml-overriding.xml
===================================================================
--- core/trunk/annotations/src/main/docbook/en/modules/xml-overriding.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/annotations/src/main/docbook/en/modules/xml-overriding.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -58,8 +58,8 @@
<entity-mappings
xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0">
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0">
<persistence-unit-metadata>
<xml-mapping-metadata-complete/>
@@ -117,8 +117,8 @@
<entity-mappings
xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0">
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0">
<package>org.hibernate.test.annotations.reflection</package>
<entity class="Administration" access="PROPERTY" metadata-complete="true">
@@ -254,8 +254,8 @@
<entity-mappings
xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0">
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0">
<package>org.hibernate.test.annotations.reflection</package>
<entity class="Music" access="PROPERTY" metadata-complete="true">
@@ -424,4 +424,4 @@
informations in the chapter describing annotations.</para>
</section>
</section>
-</chapter>
\ No newline at end of file
+</chapter>
Modified: core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/configuration/orm.xml
===================================================================
--- core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/configuration/orm.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/configuration/orm.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,6 +2,6 @@
<entity-mappings
xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0">
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0">
</entity-mappings>
Modified: core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/idclass/xml/HabitatSpeciesLink.xml
===================================================================
--- core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/idclass/xml/HabitatSpeciesLink.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/idclass/xml/HabitatSpeciesLink.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
- version="1.0">
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
+ version="2.0">
<entity class="org.hibernate.test.annotations.idclass.xml.HabitatSpeciesLink" access="FIELD">
<table name="HABITAT_SPECIES_LINK"/>
<id-class
Modified: core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/reflection/metadata-complete.xml
===================================================================
--- core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/reflection/metadata-complete.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/reflection/metadata-complete.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,8 +2,8 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0"
>
<persistence-unit-metadata>
<xml-mapping-metadata-complete/>
Modified: core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/reflection/orm.xml
===================================================================
--- core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/reflection/orm.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/reflection/orm.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,8 +2,8 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0"
>
<persistence-unit-metadata>
<persistence-unit-defaults>
Modified: core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/xml/ejb3/orm2.xml
===================================================================
--- core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/xml/ejb3/orm2.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/annotations/src/test/resources/org/hibernate/test/annotations/xml/ejb3/orm2.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -5,6 +5,7 @@
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
version="1.0"
>
+ <!-- use orm_1_0 on purpose (backward compatibility test -->
<package>org.hibernate.test.annotations.xml.ejb3</package>
<entity class="Light" access="FIELD" metadata-complete="true">
<attributes>
Modified: core/trunk/entitymanager/src/main/docbook/en/modules/listeners.xml
===================================================================
--- core/trunk/entitymanager/src/main/docbook/en/modules/listeners.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/entitymanager/src/main/docbook/en/modules/listeners.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -1,4 +1,4 @@
-<?xml version='1.0' encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
@@ -22,8 +22,8 @@
~ 51 Franklin Street, Fifth Floor
~ Boston, MA 02110-1301 USA
-->
-
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="listeners">
<title>Entity listeners and Callback methods</title>
@@ -33,7 +33,7 @@
<para>It is often useful for the application to react to certain events
that occur inside the persistence mechanism. This allows the
implementation of certain kinds of generic functionality, and extension of
- built-in functionality. The EJB3 specification provides two related
+ built-in functionality. The JPA specification provides two related
mechanisms for this purpose.</para>
<para>A method of the entity may be designated as a callback method to
@@ -89,11 +89,11 @@
have two methods being annotated by the same callback annotation whether
it is a callback method or an entity listener method. A callback method is
a no-arg method with no return type and any arbitrary name. An entity
- listener has the signature <code>void <METHOD>(Object)</code>
- where Object is of the actual entity type (note that Hibernate Entity
- Manager relaxed this constraint and allows <literal>Object</literal> of
+ listener has the signature <code>void <METHOD>(Object)</code> where
+ Object is of the actual entity type (note that Hibernate Entity Manager
+ relaxed this constraint and allows <literal>Object</literal> of
<literal>java.lang.Object</literal> type (allowing sharing of listeners
- accross several entities.)</para>
+ across several entities.)</para>
<para>A callback method can raise a
<classname>RuntimeException</classname>. The current transaction, if any,
@@ -163,7 +163,7 @@
<row>
<entry>@PostLoad</entry>
- <entry>Eexecuted after an entity has been loaded into the current
+ <entry>Executed after an entity has been loaded into the current
persistence context or an entity has been refreshed.</entry>
</row>
</tbody>
@@ -179,7 +179,7 @@
<title>Callbacks and listeners inheritance</title>
<para>You can define several entity listeners per entity at different
- level of the hierarchy.You can also define several callbacks at different
+ level of the hierarchy. You can also define several callbacks at different
level of the hierarchy. But you cannot define two listeners for the same
event in the same entity or the same entity listener.</para>
@@ -217,16 +217,16 @@
<section>
<title>XML definition</title>
- <para>The EJB3 specification allows annotation overriding through EJB3
- deployment descriptor. There is also an additional feature that can be
+ <para>The JPA specification allows annotation overriding through JPA
+ deployment descriptors. There is also an additional feature that can be
useful: default event listeners.</para>
<programlisting><?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0"
>
<persistence-unit-metadata>
<persistence-unit-defaults>
@@ -258,7 +258,8 @@
<para>Last but not least, you can define some default entity listeners
that will apply first on the entity listener stack of all the mapped
entities of a given persistence unit. If you don't want an entity to
- inherit the default listeners, you can use @ExcludeDefaultListeners (or
+ inherit the default listeners, you can use
+ <classname>@ExcludeDefaultListeners</classname> (or
<exclude-default-listeners/>).</para>
</section>
-</chapter>
\ No newline at end of file
+</chapter>
Modified: core/trunk/entitymanager/src/test/bundles/defaultpar/META-INF/orm.xml
===================================================================
--- core/trunk/entitymanager/src/test/bundles/defaultpar/META-INF/orm.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/entitymanager/src/test/bundles/defaultpar/META-INF/orm.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,8 +2,8 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0"
>
<persistence-unit-metadata>
<persistence-unit-defaults>
Modified: core/trunk/entitymanager/src/test/bundles/defaultpar_1_0/META-INF/orm.xml
===================================================================
--- core/trunk/entitymanager/src/test/bundles/defaultpar_1_0/META-INF/orm.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/entitymanager/src/test/bundles/defaultpar_1_0/META-INF/orm.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -5,6 +5,7 @@
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
version="1.0"
>
+ <!-- use orm_1_0 on purpose (backward compatibility test -->
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
Modified: core/trunk/entitymanager/src/test/bundles/excludehbmpar/META-INF/orm2.xml
===================================================================
--- core/trunk/entitymanager/src/test/bundles/excludehbmpar/META-INF/orm2.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/entitymanager/src/test/bundles/excludehbmpar/META-INF/orm2.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,8 +2,8 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0"
>
<package>org.hibernate.ejb.test.xml</package>
<entity class="Light" access="FIELD" metadata-complete="true">
Modified: core/trunk/entitymanager/src/test/bundles/explicitpar/META-INF/orm.xml
===================================================================
--- core/trunk/entitymanager/src/test/bundles/explicitpar/META-INF/orm.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/entitymanager/src/test/bundles/explicitpar/META-INF/orm.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,8 +2,8 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0"
>
<package>org.hibernate.ejb.test.pack.various</package>
<entity class="Seat" access="PROPERTY" metadata-complete="true">
Modified: core/trunk/entitymanager/src/test/bundles/externaljar/META-INF/orm.xml
===================================================================
--- core/trunk/entitymanager/src/test/bundles/externaljar/META-INF/orm.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/entitymanager/src/test/bundles/externaljar/META-INF/orm.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,8 +2,8 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0"
>
<package>org.hibernate.ejb.test.pack.various</package>
<entity class="Airplane" metadata-complete="true" access="PROPERTY">
Modified: core/trunk/entitymanager/src/test/bundles/war/WEB-INF/classes/META-INF/orm.xml
===================================================================
--- core/trunk/entitymanager/src/test/bundles/war/WEB-INF/classes/META-INF/orm.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/entitymanager/src/test/bundles/war/WEB-INF/classes/META-INF/orm.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,8 +2,8 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0"
>
<persistence-unit-metadata>
<persistence-unit-defaults>
Modified: core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/orm.xml
===================================================================
--- core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/orm.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/orm.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,8 +2,8 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0"
>
<persistence-unit-metadata>
<persistence-unit-defaults>
Modified: core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/orm2.xml
===================================================================
--- core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/orm2.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/orm2.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,8 +2,8 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0"
>
<entity class="org.hibernate.ejb.test.xml.Lighter" name="ALighter" access="FIELD" metadata-complete="true">
<attributes>
Modified: core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/orm3.xml
===================================================================
--- core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/orm3.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/orm3.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,8 +2,8 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
- version="1.0">
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
+ version="2.0">
<persistence-unit-metadata>
<persistence-unit-defaults>
Modified: core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/sequences/orm.xml
===================================================================
--- core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/sequences/orm.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/sequences/orm.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,8 +2,8 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0"
>
<persistence-unit-metadata>
<persistence-unit-defaults>
Modified: core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/sequences/orm2.xml
===================================================================
--- core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/sequences/orm2.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/sequences/orm2.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,8 +2,8 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
- version="1.0"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0"
>
<entity class="org.hibernate.ejb.test.xml.sequences.Lighter" name="ALighter" access="FIELD" metadata-complete="true">
<attributes>
Modified: core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/sequences/orm3.xml
===================================================================
--- core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/sequences/orm3.xml 2010-03-10 08:23:04 UTC (rev 18950)
+++ core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/xml/sequences/orm3.xml 2010-03-10 08:42:18 UTC (rev 18951)
@@ -2,8 +2,8 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
- version="1.0">
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
+ version="2.0">
<entity class="org.hibernate.ejb.test.xml.sequences.Employee" metadata-complete="false" access="FIELD">
<attributes>
14 years, 9 months