Hibernate SVN: r10792 - in trunk/Hibernate3/src/org/hibernate/proxy/pojo: cglib javassist
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-11-13 12:49:36 -0500 (Mon, 13 Nov 2006)
New Revision: 10792
Modified:
trunk/Hibernate3/src/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java
trunk/Hibernate3/src/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java
Log:
code cleanup
Modified: trunk/Hibernate3/src/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java 2006-11-13 17:44:44 UTC (rev 10791)
+++ trunk/Hibernate3/src/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java 2006-11-13 17:49:36 UTC (rev 10792)
@@ -141,22 +141,20 @@
final Object returnValue;
try {
if ( ReflectHelper.isPublic( persistentClass, method ) ) {
- if(! ( method.getDeclaringClass().isInstance(target) ) )
- {
- throw new ClassCastException(
- target.getClass()
- .getName()
- );
+ if ( !method.getDeclaringClass().isInstance( target ) ) {
+ throw new ClassCastException( target.getClass().getName() );
}
returnValue = method.invoke( target, args );
}
else {
- if ( !method.isAccessible() ) method.setAccessible( true );
+ if ( !method.isAccessible() ) {
+ method.setAccessible( true );
+ }
returnValue = method.invoke( target, args );
}
return returnValue == target ? proxy : returnValue;
}
- catch (InvocationTargetException ite) {
+ catch ( InvocationTargetException ite ) {
throw ite.getTargetException();
}
}
@@ -170,7 +168,7 @@
return this;
}
else {
- throw new LazyInitializationException("unexpected case hit, method=" + method.getName());
+ throw new LazyInitializationException( "unexpected case hit, method=" + method.getName() );
}
}
}
Modified: trunk/Hibernate3/src/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java 2006-11-13 17:44:44 UTC (rev 10791)
+++ trunk/Hibernate3/src/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java 2006-11-13 17:49:36 UTC (rev 10792)
@@ -136,7 +136,6 @@
factory.setInterfaces( interfaces );
factory.setFilter( FINALIZE_FILTER );
return factory.createClass();
- // TODO
}
catch ( Throwable t ) {
LogFactory.getLog( BasicLazyInitializer.class ).error(
@@ -167,23 +166,23 @@
Object target = getImplementation();
final Object returnValue;
try {
- if ( ReflectHelper.isPublic( persistentClass, thisMethod ) ) {
- if(! ( thisMethod.getDeclaringClass().isInstance(target) ) ) {
- throw new ClassCastException( target.getClass().getName() );
- }
- returnValue = thisMethod.invoke( target, args );
- }
- else {
- if ( !thisMethod.isAccessible() ) {
- thisMethod.setAccessible( true );
- }
- returnValue = thisMethod.invoke( target, args );
- }
- return returnValue == target ? proxy : returnValue;
- }
+ if ( ReflectHelper.isPublic( persistentClass, thisMethod ) ) {
+ if ( !thisMethod.getDeclaringClass().isInstance( target ) ) {
+ throw new ClassCastException( target.getClass().getName() );
+ }
+ returnValue = thisMethod.invoke( target, args );
+ }
+ else {
+ if ( !thisMethod.isAccessible() ) {
+ thisMethod.setAccessible( true );
+ }
+ returnValue = thisMethod.invoke( target, args );
+ }
+ return returnValue == target ? proxy : returnValue;
+ }
catch ( InvocationTargetException ite ) {
- throw ite.getTargetException();
- }
+ throw ite.getTargetException();
+ }
}
else {
return result;
18 years, 10 months
Hibernate SVN: r10791 - in branches/Branch_3_2/Hibernate3/src/org/hibernate/proxy/pojo: cglib javassist
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-11-13 12:44:44 -0500 (Mon, 13 Nov 2006)
New Revision: 10791
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java
branches/Branch_3_2/Hibernate3/src/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java
Log:
HHH-2229 : performance of castability checks during proxy initialization (port to 3.2)
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java 2006-11-13 14:14:45 UTC (rev 10790)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java 2006-11-13 17:44:44 UTC (rev 10791)
@@ -4,11 +4,7 @@
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer;
@@ -137,63 +133,31 @@
this.interfaces = interfaces;
}
- private static boolean isCastable(Class caster, Class castee) {
- if ( castee.equals( caster ) ) {
- return true;
- }
- List list = addCheckingTypes( caster, new ArrayList() );
- for ( Iterator iter = list.iterator(); iter.hasNext(); ) {
- Class cl = ( Class ) iter.next();
- if ( castee.equals( cl ) ) {
- return true;
- }
- }
- return false;
- }
-
- private static List addCheckingTypes(final Class type, final List list) {
- Class superclass = type.getSuperclass();
- if ( superclass != null ) {
- list.add( superclass );
- addCheckingTypes( superclass, list );
- }
- Class[] interfaces = type.getInterfaces();
- for ( int i = 0; i < interfaces.length; ++i ) {
- list.add( interfaces[i] );
- addCheckingTypes( interfaces[i], list );
- }
- return list;
- }
-
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
if ( constructed ) {
Object result = invoke( method, args, proxy );
if ( result == INVOKE_IMPLEMENTATION ) {
Object target = getImplementation();
- final Object returnValue;
try {
- if ( ReflectHelper.isPublic( persistentClass, method ) ) {
- if ( !isCastable(
- target.getClass(), method
- .getDeclaringClass()
- ) ) {
- throw new ClassCastException(
- target.getClass()
- .getName()
- );
+ final Object returnValue;
+ if ( ReflectHelper.isPublic( persistentClass, method ) ) {
+ if ( ! method.getDeclaringClass().isInstance( target ) ) {
+ throw new ClassCastException( target.getClass().getName() );
}
returnValue = method.invoke( target, args );
- }
- else {
- if ( !method.isAccessible() ) method.setAccessible( true );
+ }
+ else {
+ if ( !method.isAccessible() ) {
+ method.setAccessible( true );
+ }
returnValue = method.invoke( target, args );
}
return returnValue == target ? proxy : returnValue;
}
- catch (InvocationTargetException ite) {
- throw ite.getTargetException();
- }
+ catch ( InvocationTargetException ite ) {
+ throw ite.getTargetException();
}
+ }
else {
return result;
}
@@ -204,7 +168,7 @@
return this;
}
else {
- throw new LazyInitializationException("unexpected case hit, method=" + method.getName());
+ throw new LazyInitializationException( "unexpected case hit, method=" + method.getName() );
}
}
}
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java 2006-11-13 14:14:45 UTC (rev 10790)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java 2006-11-13 17:44:44 UTC (rev 10791)
@@ -3,9 +3,6 @@
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
import javassist.util.proxy.MethodFilter;
import javassist.util.proxy.MethodHandler;
@@ -139,7 +136,6 @@
factory.setInterfaces( interfaces );
factory.setFilter( FINALIZE_FILTER );
return factory.createClass();
- // TODO
}
catch ( Throwable t ) {
LogFactory.getLog( BasicLazyInitializer.class ).error(
@@ -153,34 +149,6 @@
}
}
- private static boolean isCastable(Class caster, Class castee) {
- if ( castee.equals( caster ) ) {
- return true;
- }
- List list = addCheckingTypes( caster, new ArrayList() );
- for ( Iterator iter = list.iterator(); iter.hasNext(); ) {
- Class cl = ( Class ) iter.next();
- if ( castee.equals( cl ) ) {
- return true;
- }
- }
- return false;
- }
-
- private static List addCheckingTypes(final Class type, final List list) {
- Class superclass = type.getSuperclass();
- if ( superclass != null ) {
- list.add( superclass );
- addCheckingTypes( superclass, list );
- }
- Class[] interfaces = type.getInterfaces();
- for ( int i = 0; i < interfaces.length; ++i ) {
- list.add( interfaces[i] );
- addCheckingTypes( interfaces[i], list );
- }
- return list;
- }
-
public Object invoke(
final Object proxy,
final Method thisMethod,
@@ -199,9 +167,9 @@
final Object returnValue;
try {
if ( ReflectHelper.isPublic( persistentClass, thisMethod ) ) {
- if ( !isCastable( target.getClass(), thisMethod.getDeclaringClass()) ) {
+ if ( ! thisMethod.getDeclaringClass().isInstance( target ) ) {
throw new ClassCastException( target.getClass().getName() );
- }
+ }
returnValue = thisMethod.invoke( target, args );
}
else {
18 years, 10 months
Hibernate SVN: r10790 - in trunk/Hibernate3: src/org/hibernate/persister/entity test/org/hibernate/test/instrument/buildtime test/org/hibernate/test/instrument/cases
by hibernate-commits@lists.jboss.org
Author: max.andersen(a)jboss.com
Date: 2006-11-13 09:14:45 -0500 (Mon, 13 Nov 2006)
New Revision: 10790
Modified:
trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
trunk/Hibernate3/test/org/hibernate/test/instrument/buildtime/InstrumentTest.java
trunk/Hibernate3/test/org/hibernate/test/instrument/cases/TestLazyPropertyCustomTypeExecutable.java
Log:
HHH-2236 Lazy property + setReadOnly + Instrumented classes results in NullPointerException when accessing lazy property
(merged from branch_3_2)
Modified: trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-11-13 13:49:01 UTC (rev 10789)
+++ trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-11-13 14:14:45 UTC (rev 10790)
@@ -850,7 +850,11 @@
final Object propValue
) {
setPropertyValue( entity, lazyPropertyNumbers[j], propValue, session.getEntityMode() );
- snapshot[ lazyPropertyNumbers[j] ] = lazyPropertyTypes[j].deepCopy( propValue, session.getEntityMode(), factory );
+
+ if (snapshot != null) { // object have been loaded with setReadOnly(true); HHH-2236
+ snapshot[ lazyPropertyNumbers[j] ] = lazyPropertyTypes[j].deepCopy( propValue, session.getEntityMode(), factory );
+ }
+
return fieldName.equals( lazyPropertyNames[j] );
}
Modified: trunk/Hibernate3/test/org/hibernate/test/instrument/buildtime/InstrumentTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/instrument/buildtime/InstrumentTest.java 2006-11-13 13:49:01 UTC (rev 10789)
+++ trunk/Hibernate3/test/org/hibernate/test/instrument/buildtime/InstrumentTest.java 2006-11-13 14:14:45 UTC (rev 10790)
@@ -13,6 +13,7 @@
import org.hibernate.test.instrument.cases.TestLazyManyToOneExecutable;
import org.hibernate.test.instrument.cases.TestInjectFieldInterceptorExecutable;
import org.hibernate.test.instrument.cases.TestIsPropertyInitializedExecutable;
+import org.hibernate.test.instrument.cases.TestLazyPropertyCustomTypeExecutable;
import org.hibernate.test.instrument.cases.TestManyToOneProxyExecutable;
import org.hibernate.test.instrument.cases.Executable;
@@ -53,6 +54,10 @@
execute( new TestManyToOneProxyExecutable() );
}
+ public void testLazyPropertyCustomTypeExecutable() {
+ execute( new TestLazyPropertyCustomTypeExecutable() );
+ }
+
private void execute(Executable executable) {
executable.prepare();
try {
Modified: trunk/Hibernate3/test/org/hibernate/test/instrument/cases/TestLazyPropertyCustomTypeExecutable.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/instrument/cases/TestLazyPropertyCustomTypeExecutable.java 2006-11-13 13:49:01 UTC (rev 10789)
+++ trunk/Hibernate3/test/org/hibernate/test/instrument/cases/TestLazyPropertyCustomTypeExecutable.java 2006-11-13 14:14:45 UTC (rev 10790)
@@ -29,28 +29,25 @@
s.getTransaction().commit();
s.close();
- // this access should be ok because p1 is not a lazy proxy
+ // this access should be ok because p1 is not a lazy proxy
s = getFactory().openSession();
s.beginTransaction();
- Problematic p1 = ( Problematic ) s.get( Problematic.class, p.getId() );
+ Problematic p1 = (Problematic) s.get( Problematic.class, p.getId() );
Assert.assertTrue( FieldInterceptionHelper.isInstrumented( p1 ) );
p1.getRepresentation();
s.getTransaction().commit();
s.close();
-
- // this should cause problems
+
s = getFactory().openSession();
s.beginTransaction();
- p1 = ( Problematic ) s.load( Problematic.class, p.getId() );
- Assert.assertFalse( FieldInterceptionHelper.isInstrumented( p1 ) );
+ p1 = (Problematic) s.createQuery( "from Problematic" ).setReadOnly(true ).list().get( 0 );
p1.getRepresentation();
s.getTransaction().commit();
s.close();
-
- // this should cause problems
+
s = getFactory().openSession();
s.beginTransaction();
- p1 = ( Problematic ) s.load( Problematic.class, p.getId() );
+ p1 = (Problematic) s.load( Problematic.class, p.getId() );
Assert.assertFalse( FieldInterceptionHelper.isInstrumented( p1 ) );
p1.setRepresentation( p.getRepresentation() );
s.getTransaction().commit();
@@ -61,11 +58,11 @@
Session s = getFactory().openSession();
s.beginTransaction();
Iterator itr = s.createQuery( "from Problematic" ).list().iterator();
- while( itr.hasNext() ) {
- Problematic p = ( Problematic ) itr.next();
+ while ( itr.hasNext() ) {
+ Problematic p = (Problematic) itr.next();
s.delete( p );
}
s.getTransaction().commit();
s.close();
}
-}
+}
\ No newline at end of file
18 years, 10 months
Hibernate SVN: r10789 - in branches/Branch_3_2/Hibernate3: src/org/hibernate/persister/entity test/org/hibernate/test/instrument/buildtime test/org/hibernate/test/instrument/cases
by hibernate-commits@lists.jboss.org
Author: max.andersen(a)jboss.com
Date: 2006-11-13 08:49:01 -0500 (Mon, 13 Nov 2006)
New Revision: 10789
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/instrument/buildtime/InstrumentTest.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/instrument/cases/TestLazyPropertyCustomTypeExecutable.java
Log:
HHH-2236 Lazy property + setReadOnly + Instrumented classes results in NullPointerException when accessing lazy property
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-11-13 13:21:19 UTC (rev 10788)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-11-13 13:49:01 UTC (rev 10789)
@@ -850,7 +850,11 @@
final Object propValue
) {
setPropertyValue( entity, lazyPropertyNumbers[j], propValue, session.getEntityMode() );
- snapshot[ lazyPropertyNumbers[j] ] = lazyPropertyTypes[j].deepCopy( propValue, session.getEntityMode(), factory );
+
+ if (snapshot != null) { // object have been loaded with setReadOnly(true); HHH-2236
+ snapshot[ lazyPropertyNumbers[j] ] = lazyPropertyTypes[j].deepCopy( propValue, session.getEntityMode(), factory );
+ }
+
return fieldName.equals( lazyPropertyNames[j] );
}
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/instrument/buildtime/InstrumentTest.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/instrument/buildtime/InstrumentTest.java 2006-11-13 13:21:19 UTC (rev 10788)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/instrument/buildtime/InstrumentTest.java 2006-11-13 13:49:01 UTC (rev 10789)
@@ -13,6 +13,7 @@
import org.hibernate.test.instrument.cases.TestLazyManyToOneExecutable;
import org.hibernate.test.instrument.cases.TestInjectFieldInterceptorExecutable;
import org.hibernate.test.instrument.cases.TestIsPropertyInitializedExecutable;
+import org.hibernate.test.instrument.cases.TestLazyPropertyCustomTypeExecutable;
import org.hibernate.test.instrument.cases.TestManyToOneProxyExecutable;
import org.hibernate.test.instrument.cases.Executable;
@@ -53,6 +54,10 @@
execute( new TestManyToOneProxyExecutable() );
}
+ public void testLazyPropertyCustomTypeExecutable() {
+ execute( new TestLazyPropertyCustomTypeExecutable() );
+ }
+
private void execute(Executable executable) {
executable.prepare();
try {
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/instrument/cases/TestLazyPropertyCustomTypeExecutable.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/instrument/cases/TestLazyPropertyCustomTypeExecutable.java 2006-11-13 13:21:19 UTC (rev 10788)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/instrument/cases/TestLazyPropertyCustomTypeExecutable.java 2006-11-13 13:49:01 UTC (rev 10789)
@@ -29,28 +29,25 @@
s.getTransaction().commit();
s.close();
- // this access should be ok because p1 is not a lazy proxy
+ // this access should be ok because p1 is not a lazy proxy
s = getFactory().openSession();
s.beginTransaction();
- Problematic p1 = ( Problematic ) s.get( Problematic.class, p.getId() );
+ Problematic p1 = (Problematic) s.get( Problematic.class, p.getId() );
Assert.assertTrue( FieldInterceptionHelper.isInstrumented( p1 ) );
p1.getRepresentation();
s.getTransaction().commit();
s.close();
-
- // this should cause problems
+
s = getFactory().openSession();
s.beginTransaction();
- p1 = ( Problematic ) s.load( Problematic.class, p.getId() );
- Assert.assertFalse( FieldInterceptionHelper.isInstrumented( p1 ) );
+ p1 = (Problematic) s.createQuery( "from Problematic" ).setReadOnly(true ).list().get( 0 );
p1.getRepresentation();
s.getTransaction().commit();
s.close();
-
- // this should cause problems
+
s = getFactory().openSession();
s.beginTransaction();
- p1 = ( Problematic ) s.load( Problematic.class, p.getId() );
+ p1 = (Problematic) s.load( Problematic.class, p.getId() );
Assert.assertFalse( FieldInterceptionHelper.isInstrumented( p1 ) );
p1.setRepresentation( p.getRepresentation() );
s.getTransaction().commit();
@@ -61,11 +58,11 @@
Session s = getFactory().openSession();
s.beginTransaction();
Iterator itr = s.createQuery( "from Problematic" ).list().iterator();
- while( itr.hasNext() ) {
- Problematic p = ( Problematic ) itr.next();
+ while ( itr.hasNext() ) {
+ Problematic p = (Problematic) itr.next();
s.delete( p );
}
s.getTransaction().commit();
s.close();
}
-}
+}
\ No newline at end of file
18 years, 10 months
Hibernate SVN: r10788 - branches/Branch_3_2/Hibernate3/test/org/hibernate/test
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-11-13 08:21:19 -0500 (Mon, 13 Nov 2006)
New Revision: 10788
Modified:
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/AllTests.java
Log:
minor changes to dialect for intersystems CacheSQL
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/AllTests.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/AllTests.java 2006-11-13 13:21:10 UTC (rev 10787)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/AllTests.java 2006-11-13 13:21:19 UTC (rev 10788)
@@ -130,6 +130,7 @@
import org.hibernate.test.version.db.DbVersionTest;
import org.hibernate.test.version.sybase.SybaseTimestampVersioningTest;
import org.hibernate.test.where.WhereTest;
+import org.hibernate.test.dialect.cache.SQLFunctionsInterSystemsTest;
/**
* @author Gavin King
@@ -288,6 +289,7 @@
suite.addTest( AbstractCompositeIdTest.suite() );
suite.addTest( UtilSuite.suite() );
suite.addTest( AnyTypeTest.suite() );
+ suite.addTest( SQLFunctionsInterSystemsTest.suite() );
return filter( suite );
//return suite;
18 years, 10 months
Hibernate SVN: r10787 - trunk/Hibernate3/test/org/hibernate/test
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-11-13 08:21:10 -0500 (Mon, 13 Nov 2006)
New Revision: 10787
Modified:
trunk/Hibernate3/test/org/hibernate/test/AllTests.java
Log:
minor changes to dialect for intersystems CacheSQL
Modified: trunk/Hibernate3/test/org/hibernate/test/AllTests.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/AllTests.java 2006-11-13 12:53:43 UTC (rev 10786)
+++ trunk/Hibernate3/test/org/hibernate/test/AllTests.java 2006-11-13 13:21:10 UTC (rev 10787)
@@ -130,6 +130,7 @@
import org.hibernate.test.version.db.DbVersionTest;
import org.hibernate.test.version.sybase.SybaseTimestampVersioningTest;
import org.hibernate.test.where.WhereTest;
+import org.hibernate.test.dialect.cache.SQLFunctionsInterSystemsTest;
/**
* @author Gavin King
@@ -288,6 +289,7 @@
suite.addTest( AbstractCompositeIdTest.suite() );
suite.addTest( UtilSuite.suite() );
suite.addTest( AnyTypeTest.suite() );
+ suite.addTest( SQLFunctionsInterSystemsTest.suite() );
return filter( suite );
//return suite;
18 years, 10 months
Hibernate SVN: r10786 - in branches/Branch_3_2/Hibernate3: etc src/org/hibernate/dialect
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-11-13 07:53:43 -0500 (Mon, 13 Nov 2006)
New Revision: 10786
Added:
branches/Branch_3_2/Hibernate3/etc/CacheSequences.xml
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java
Log:
minor changes to dialect for intersystems CacheSQL
Added: branches/Branch_3_2/Hibernate3/etc/CacheSequences.xml
===================================================================
--- branches/Branch_3_2/Hibernate3/etc/CacheSequences.xml 2006-11-13 12:53:18 UTC (rev 10785)
+++ branches/Branch_3_2/Hibernate3/etc/CacheSequences.xml 2006-11-13 12:53:43 UTC (rev 10786)
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+An example of enabling support for sequences in Intersystems' Cache SQL 2007.1 database.
+-->
+
+<Export generator="Cache" version="9" zv="Cache for Windows NT (Intel) 5.0.17 (Build 6006U)" ts="2005-09-29 14:10:54">
+<Project name="Hibernate_Sequences" LastModified="2005-09-29 14:10:54">
+ <Items>
+ <ProjectItem name="InterSystems.Sequences" type="CLS"/>
+ </Items>
+</Project>
+<Class name="InterSystems.Sequences">
+<Description><![CDATA[
+Class to maintain a table of counters for Oracle sequence or MSSql identity columns
+<br><br>Counters can be incremented by calling the stored procedure BEFORE the insert
+using syntax like: call InterSystems.Sequences_GetNext("Name"), or using standard SQL,
+or part of an SQL select like:
+<br><br>select InterSystems.Sequences_GetNext(sequencename) from InterSystems.Sequences where Name='sequencename'
+<br>
+<br>Can also be queried as table InterSystems.Sequences, but that data is actually stored
+in ^InterSystems.Sequences. Note use of %CacheSqlStorage to speed incrementing.
+<br>
+<br> Note: to make the Sequences system-wide, simply map ^InterSystems.Sequences* to a
+common location
+ <br>
+ <br> Note: counter names are case-insensitive and force to uppercase on disk.
+<br><br> Merge of ideas by JSL and APC 09/2005
+]]></Description>
+<ClassType>persistent</ClassType>
+<SqlRowIdPrivate>1</SqlRowIdPrivate>
+<StorageStrategy>custom</StorageStrategy>
+<Super>%Persistent</Super>
+<TimeChanged>60172,44404.735854</TimeChanged>
+<TimeCreated>60137,56752.747989</TimeCreated>
+<ClassDefinitionError>0</ClassDefinitionError>
+
+<Index name="UniqueIndex1">
+<IdKey>1</IdKey>
+<PrimaryKey>1</PrimaryKey>
+<Properties>Name</Properties>
+<Unique>1</Unique>
+</Index>
+
+<Property name="Name">
+<Description>
+The name of the sequence or identity, forced to uppercase. Typically a tablename
+(MSSQL identities) or an Oracle-like Sequence name</Description>
+<Type>%String</Type>
+<Parameter name="MAXLEN" value="64"/>
+</Property>
+
+<Property name="Counter">
+<Description>
+Last assigned value for this Name. Initial </Description>
+<Type>%Integer</Type>
+<InitialExpression>0</InitialExpression>
+</Property>
+
+<Method name="GetNext">
+<Description>
+Returns an integer value with next assigned counter.</Description>
+<ClassMethod>1</ClassMethod>
+<FormalSpec>name:%String</FormalSpec>
+<ReturnType>%Integer</ReturnType>
+<SqlProc>1</SqlProc>
+<Implementation><![CDATA[ quit $increment(^InterSystems.Sequences($zcvt(name,"U"))) //force name to uppercase to be safe
+]]></Implementation>
+</Method>
+
+<Method name="Init">
+<Description>
+Hibernate procedure to intialise a sequence, but can be used at any time</Description>
+<ClassMethod>1</ClassMethod>
+<FormalSpec>SequenceName:%String</FormalSpec>
+<ReturnType>%Integer</ReturnType>
+<SqlProc>1</SqlProc>
+<Implementation><![CDATA[
+ set ^InterSystems.Sequences($zcvt(SequenceName,"U"))=0
+ quit 0
+]]></Implementation>
+</Method>
+
+<Method name="Drop">
+<Description>
+Hibernate procedure to kill a sequence, but can be used at any time</Description>
+<ClassMethod>1</ClassMethod>
+<FormalSpec>SequenceName:%String</FormalSpec>
+<ReturnType>%Integer</ReturnType>
+<SqlProc>1</SqlProc>
+<Implementation><![CDATA[
+ kill ^InterSystems.Sequences($zcvt(SequenceName,"U"))
+ quit 0
+]]></Implementation>
+</Method>
+
+<Storage name="custom">
+<Type>%CacheSQLStorage</Type>
+<StreamLocation>^InterSystems.SequencesS</StreamLocation>
+<Property name="Counter"/>
+<Property name="Name">
+<Selectivity>1</Selectivity>
+</Property>
+<SQLMap name="datamap">
+<Type>data</Type>
+<Global>^InterSystems.Sequences</Global>
+<Structure>delimited</Structure>
+<Subscript name="1">
+<Expression>{Name}</Expression>
+</Subscript>
+<Data name="Counter"/>
+</SQLMap>
+</Storage>
+</Class>
+<Checksum value="3603995477"/>
+</Export>
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java 2006-11-13 12:53:18 UTC (rev 10785)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java 2006-11-13 12:53:43 UTC (rev 10786)
@@ -1,4 +1,4 @@
-//$Id: $
+//$Id: $
package org.hibernate.dialect;
import java.sql.CallableStatement;
@@ -35,7 +35,6 @@
* Caché 2007.1 dialect. This class is required in order to use Hibernate with Intersystems Cach� SQL.<br>
* <br>
* Compatible with Cach� 2007.1.
- * Cache JDBC driver version ?.?.
* <br>
* <head>
* <title>Caché and Hibernate</title>
@@ -46,10 +45,7 @@
* These setup instructions assume that both Caché and Hibernate are installed and operational.
* <br>
* <h2>HIBERNATE DIRECTORIES AND FILES</h2>
- * InterSystems support for Hibernate 2.1.8 and Hibernate 3.0.5
- * requires different dialect files from those distributed with Hibernate 3.2.
- * Also Hibernate 2.1.8 has a different directory and Java package structure which is reflected in the InterSystems sources.
- * JBoss distributes the InterSystems Cache' dialect for Hibernate 3.2.
+ * JBoss distributes the InterSystems Cache' dialect for Hibernate 3.2.1
* For earlier versions of Hibernate please contact
* <a href="http://www.intersystems.com/support/cache-support.html">InterSystems Worldwide Response Center</A> (WRC)
* for the appropriate source files.
@@ -78,7 +74,6 @@
* Hibernate. The next step depends on the location of your
* CacheDB.jar depending on your version of Caché.
* <ol>
- * <li>Copy C:\CacheSys\dev\java\lib\CacheDB.jar to C:\Hibernate\lib\CacheDB.jar.</li>
* <li>Copy C:\CacheSys\dev\java\lib\JDK15\CacheDB.jar to C:\Hibernate\lib\CacheDB.jar.</li>
* <p/>
* <li>Insert the following files into your Java classpath:
@@ -99,18 +94,15 @@
* <table cols=3 border cellpadding=5 cellspacing=0>
* <tr>
* <th>Property Name</th>
- * <th>Property Value 3.2</th>
- * <th>Property Value 2.1.8</th>
+ * <th>Property Value</th>
* </tr>
* <tr>
* <td>hibernate.dialect</td>
* <td>org.hibernate.dialect.Cache71Dialect</td>
- * <td>net.sf.hibernate.dialect.Cache50Dialect</td>
* </tr>
* <tr>
* <td>hibernate.connection.driver_class</td>
* <td>com.intersys.jdbc.CacheDriver</td>
- * <td>com.intersys.jdbc.CacheDriver</td>
* </tr>
* <tr>
* <td>hibernate.connection.username</td>
@@ -125,7 +117,6 @@
* <tr>
* <td>hibernate.connection.url</td>
* <td>jdbc:Cache://127.0.0.1:1972/USER</td>
- * <td>jdbc:Cache://127.0.0.1:1972/USER</td>
* </tr>
* </table>
* <p/>
@@ -146,100 +137,24 @@
* <br>
* <p/>
* <ol>
- * <li>
- * org.hibernate.dialect.Cache50Dialect (requires Caché
- * 5.0 or above)
- * </li>
- * <p/>
- * <li>org.hibernate.dialect.Cache51Dialect (requires Caché 5.1 or
- * above)</li>
- * <p/>
- * <li>org.hibernate.dialect.Cache51SequenceDialect (requires Caché 5.1 or
- * above)</li>
- * <p/>
* <li>org.hibernate.dialect.Cache71Dialect (requires Caché
* 2007.1 or above)</li>
* <p/>
- * <li>org.hibernate.dialect.Cache71SequenceDialect (requires Caché
- * 2007.1 or above)</li>
* </ol>
- * <p/>
- * Setting up for Caché 5.0 is similar except that the hibernate
- * dialect package is "org.hibernate.dialect.Cache50Dialect"
* <br>
- * <h2>SETTING UP CACHÉ DIALECT FROM INTERSYSTEMS SOURCES</h2>
- * <p/>
- * InterSystems provides source code for the Hibernate Dialect classes.
- * Therefore, you must first place the source code in the proper locations
- * and compile it into Java class files.
- * Doing this will eliminate possible version mismatches in the compiled Java code.
- * <p/>
- * To begin, unzip the InterSystems source into the PARENT directory of the location where you installed Hibernate.
- * The InterSystems zip file that contains InterSystems Hibernate support for
- * Hibernate 2.1.8 and Hibernate 3.0.5 already contains hibernate-2.1
- * and hibernate-3.0 in its directory structure. This is why you must
- * unzip to the directory CONTAINING your Hibernate install directory.
- * <p/>
- * If you are using Hibernate 3.2, JBoss has already built the right JAR file for you.
- * If you are NOT using Hibernate 3.2, then you must do the following:
- * <p/>
- * <ol>
- * <li>In your Hibernate install directory, after the unzip we described above,
- * type the following:
- * <br>
- * <pre>
- * build
- * </pre></li>
- * <li>Copy the JAR file to the proper place.
- * <p/>
- * For Hibernate 3.0.5, copy
- * <pre>
- * ..\hibernate\hibernate3.jar
- * </pre>
- * to the Hibernate install directory.
- * <p/>
- * For Hibernate 2.1.8, copy
- * <pre>
- * ..\hibernate\hibernate.2jar
- * </pre>
- * to the Hibernate install directory.</li>
- * <p/>
- * <li>Test your installation by configuring etc\hibernate.properties for your Caché database,
- * and then running the following:
- * <pre>
- * build eg
- * </pre>
- * The build process reports its success or failure. If you see,
- * <pre>
- * BUILD FAILED
- * </pre>
- * please contact the
- * <a href="http://www.intersystems.com/support/cache-support.html">InterSystems Worldwide Response Center</A>
- * for assistance.
- * </li>
- * </ol>
- * <br>
* <h2>SUPPORT FOR IDENTITY COLUMNS</h2>
- * Caché 5.1 or later supports identity columns. This includes Cache' 2007.1. To cause
+ * Caché 2007.1 or later supports identity columns. For
* Hibernate to use identity columns, specify "native" as the
- * generator. Also make sure that
- * hibernate.jdbc.use_get_generated_keys is set to true, which is the
- * default. In the Cache' 2007.1 release, with the
- * Cache71Dialect, you can set hibernate.jdbc.use_get_generated_keys to
- * false, and still use identity columns.
+ * generator.
* <br>
* <h2>SEQUENCE DIALECTS SUPPORT SEQUENCES</h2>
- * You do not have to use the sequence dialects with Caché.
- * These are Cache50SequenceDialect, Cache51SequenceDialect and Cache71SequenceDialect.
- * But if you choose to use them, set them up as follows:
* <p/>
* To use Hibernate sequence support with Caché in a namespace, you must FIRST load the following file into that namespace:
* <pre>
* src\org\hibernate\dialect\CacheSequences.xml
* </pre>
* In your Hibernate mapping you can specify sequence use.
- * When you are using a Cache' sequence dialect, the type "native" maps to sequence.
- * <p/>
+ * <p>
* For example, the following shows the use of a sequence generator in a Hibernate mapping:
* <pre>
* <id name="id" column="uid" type="long" unsaved-value="null">
@@ -255,47 +170,6 @@
* getSelectSequenceNextValString() in the dialect. If this happens
* you will receive the error message: new MappingException( "Dialect
* does not support sequences" ).
- * <h2>BIGINT SUPPORT</h2>
- * Caché 5.1 and above supports BIGINT. 2007.1 supports BIGINT.
- * <p/>
- * Caché 5.0.x does not have direct BIGINT support.
- * To imitate BIGINT support in Cache 5.0.x, in the SQL configuration,
- * remap %INTEGER as follows, to be used by Caché 5.0.x dialects:
- * <p/>
- * <pre>
- * %Library.Integer(MAXVAL=99999999999999999999,MINVAL=-999999999999999999)
- * </pre>
- * <p/>
- * To change SQL settings:
- * <p/>
- * <ol>
- * <li>In Caché 2007.1, use the System Management Portal.</li>
- * <p/>
- * <li>In Caché 5.0, use the Configuration Manager.</li>
- * </ol>
- * <p/>
- * Set Caché SQL to allow:
- * <p/>
- * <ol>
- * <li>delimited identifiers</li>
- * <li>drop of non-existent tables</li>
- * <li>drop of non-existent constraints</li>
- * </ol>
- * <p/>
- * <h2>HIBERNATE 2.1.8</h2>
- * Hibernate 2.1.8 requires different source files from InterSystems reflecting
- * the different directory and Java package structure of Hibernate 2.1.8.
- * Please contact
- * <a href="http://www.intersystems.com/support/cache-support.html">InterSystems Worldwide Response Center</A> (WRC)
- * for these source files if you need to use Hibernate 2.1.8.
- * <p/>
- * To run a Cach� application with Hibernate 2.1.8, set the following flag when starting your JVM:
- * <pre>
- * -Dhibernate.jdbc.use_streams_for_binary=false
- * </pre>
- * <p/>
- * In Hibernate 3.0.5, this flag is not necessary;
- * it is taken care of by the Caché dialect itself.
* <br>
* <h2>HIBERNATE FILES ASSOCIATED WITH CACHÉ DIALECT</h2>
* The following files are associated with Caché dialect:
@@ -308,87 +182,6 @@
* <li>src\org\hibernate\sql\CacheJoinFragment.java</li>
* </ol>
* Cache71Dialect ships with Hibernate 3.2. All other dialects are distributed by InterSystems and subclass Cache71Dialect.
- * <h2>Limitations</h2>
- * The following is a list of the currently known limitations of using Cache' with Hibernate. Please check with InterSystems on the latest status as these are server side issues.
- * <p/>
- * The following also lists known issues with running the full Hibernate regression tests against InterSystems Cache'.
- * <p/>
- * - Delete of self-referential foreign keys.
- * <p/>
- * We do not current support deletion of a table row when the table has a foreign key that references itself and the foreign key in the table row references that table row. (self-referential foreign keys)
- * <p/>
- * - Support for "SELECT FOR UPDATE."
- * <p/>
- * The default locking mode strategy for Cache' is Hibernate's UpdateLockingStrategy, which you use with Hibernate's versioning capability.
- * <p/>
- * To use Concurrency modes that requires other locking strategies you can subclass your Cache' dialect and define a locking strategy.
- * <p/>
- * Cache' does not currently support "SELECT FOR UPDATE." While grammatically correct, it does no locking.
- * <p/>
- * In versions prior to 2007.1, there are limitations in support for outer joins (see Cache' documentation).
- * <p/>
- * For example, Cache' prior to 2007.1 does support "NOT NULL" clauses in the ON conditions.
- * <p/>
- * Cache' does not support using longvarbinary or longvarchar in a where clause.
- * <p/>
- * In Hibernate regression tests, Baz.hbm.xml, FooBar.hbm.xml, Glarch.hbm.xml and XY.hbm.xml have to be edited to replace "!" by BANG and "^" by CARET. Our own identifier translation is not enough since Hibernate uses names containing these in its own mapping files and Hibernate (on the client-side) does not know about our server-side mapping.
- * <p/>
- * There are some tests that involve batch operations where the test
- * will succeed if you increase the size of the lock table from
- * 786432 (the default) to 1786432. You can use the System Management
- * Portal in 2007.1 or the configuration manager in 5.0.X to increase the
- * size of the lock table. This requirement of increasing the lock
- * table size is specific to running the Hibernate regression tests.
- * <p/>
- * Cache' fails tests that attempt to COUNT stream fields
- * <p/>
- * Here is an example of such an error message, SQL ERROR -37: Aggregate function COUNT not supported for Stream fields
- * <p/>
- * We fail on tests that use mappings like the following
- * <p/>
- * <pre>
- * <property name="yob" formula="year(dob)"/>
- * </pre>
- * and the error is:
- * <p/>
- * ERROR #359: User defined SQL Function 'SQLUSER.YEAR' does not exist
- * <p/>
- * If the mapping is changed to
- * <p/>
- * <pre>
- * <property name="yob" formula="{fn year(dob)}"/>
- * </pre>
- * then such tests succeed.
- * <p/>
- * Cache' 2007.1 supports temp tables. Prior versions do not.
- * <p/>
- * We do not support row valued expression. So WHERE clauses like "WHERE (a,b,c) = (d,e,f)" give syntax errors. The Hibernate regression tests use row valued expressions and we fail on these.
- * <p/>
- * For example:
- * <p/>
- * <pre>
- * result = s.createQuery("from Transaction txn where txn.value = (1.5, 'AUD')").list();
- * </pre>
- * will not generate valid Cache' SQL because of the parenthesis around (1.5, 'AUD')
- * <p/>
- * Queries like the following:
- * <p/>
- * <pre>
- * session.createQuery("select extract(second from current_timestamp()), extract(minute from current_timestamp()), extract(hour from current_timestamp()) from Mammal m").list();
- * </pre>
- * <p/>
- * will not work, because we do support "extract" function.
- * <p/>
- * We do not support in () (empty parenthesis)
- * <p/>
- * We do not guarantee the case of a column returned using a group by clause.
- * <p/>
- * For instance in the regression test,
- * <p/>
- * <pre>
- * list = s.find("select new Result( baz.name, max(foo.long), count(foo) ) from Baz baz join baz.fooArray foo group by baz.name");
- * </pre>
- * we return baz.name in lower case, and the test that generates this SQL fails.
*
* @author Jonathan Levinson
*/
@@ -702,11 +495,11 @@
}
public String getSequenceNextValString(String sequenceName) {
- return "select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "'))";
+ return "select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "')";
}
public String getSelectSequenceNextValString(String sequenceName) {
- return "(select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "')))";
+ return "(select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "'))";
}
public String getCreateSequenceString(String sequenceName) {
18 years, 10 months
Hibernate SVN: r10785 - in trunk/Hibernate3: etc src/org/hibernate/dialect
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-11-13 07:53:18 -0500 (Mon, 13 Nov 2006)
New Revision: 10785
Added:
trunk/Hibernate3/etc/CacheSequences.xml
Modified:
trunk/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java
Log:
minor changes to dialect for intersystems CacheSQL
Added: trunk/Hibernate3/etc/CacheSequences.xml
===================================================================
--- trunk/Hibernate3/etc/CacheSequences.xml 2006-11-11 05:13:01 UTC (rev 10784)
+++ trunk/Hibernate3/etc/CacheSequences.xml 2006-11-13 12:53:18 UTC (rev 10785)
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+An example of enabling support for sequences in Intersystems' Cache SQL 2007.1 database.
+-->
+
+<Export generator="Cache" version="9" zv="Cache for Windows NT (Intel) 5.0.17 (Build 6006U)" ts="2005-09-29 14:10:54">
+<Project name="Hibernate_Sequences" LastModified="2005-09-29 14:10:54">
+ <Items>
+ <ProjectItem name="InterSystems.Sequences" type="CLS"/>
+ </Items>
+</Project>
+<Class name="InterSystems.Sequences">
+<Description><![CDATA[
+Class to maintain a table of counters for Oracle sequence or MSSql identity columns
+<br><br>Counters can be incremented by calling the stored procedure BEFORE the insert
+using syntax like: call InterSystems.Sequences_GetNext("Name"), or using standard SQL,
+or part of an SQL select like:
+<br><br>select InterSystems.Sequences_GetNext(sequencename) from InterSystems.Sequences where Name='sequencename'
+<br>
+<br>Can also be queried as table InterSystems.Sequences, but that data is actually stored
+in ^InterSystems.Sequences. Note use of %CacheSqlStorage to speed incrementing.
+<br>
+<br> Note: to make the Sequences system-wide, simply map ^InterSystems.Sequences* to a
+common location
+ <br>
+ <br> Note: counter names are case-insensitive and force to uppercase on disk.
+<br><br> Merge of ideas by JSL and APC 09/2005
+]]></Description>
+<ClassType>persistent</ClassType>
+<SqlRowIdPrivate>1</SqlRowIdPrivate>
+<StorageStrategy>custom</StorageStrategy>
+<Super>%Persistent</Super>
+<TimeChanged>60172,44404.735854</TimeChanged>
+<TimeCreated>60137,56752.747989</TimeCreated>
+<ClassDefinitionError>0</ClassDefinitionError>
+
+<Index name="UniqueIndex1">
+<IdKey>1</IdKey>
+<PrimaryKey>1</PrimaryKey>
+<Properties>Name</Properties>
+<Unique>1</Unique>
+</Index>
+
+<Property name="Name">
+<Description>
+The name of the sequence or identity, forced to uppercase. Typically a tablename
+(MSSQL identities) or an Oracle-like Sequence name</Description>
+<Type>%String</Type>
+<Parameter name="MAXLEN" value="64"/>
+</Property>
+
+<Property name="Counter">
+<Description>
+Last assigned value for this Name. Initial </Description>
+<Type>%Integer</Type>
+<InitialExpression>0</InitialExpression>
+</Property>
+
+<Method name="GetNext">
+<Description>
+Returns an integer value with next assigned counter.</Description>
+<ClassMethod>1</ClassMethod>
+<FormalSpec>name:%String</FormalSpec>
+<ReturnType>%Integer</ReturnType>
+<SqlProc>1</SqlProc>
+<Implementation><![CDATA[ quit $increment(^InterSystems.Sequences($zcvt(name,"U"))) //force name to uppercase to be safe
+]]></Implementation>
+</Method>
+
+<Method name="Init">
+<Description>
+Hibernate procedure to intialise a sequence, but can be used at any time</Description>
+<ClassMethod>1</ClassMethod>
+<FormalSpec>SequenceName:%String</FormalSpec>
+<ReturnType>%Integer</ReturnType>
+<SqlProc>1</SqlProc>
+<Implementation><![CDATA[
+ set ^InterSystems.Sequences($zcvt(SequenceName,"U"))=0
+ quit 0
+]]></Implementation>
+</Method>
+
+<Method name="Drop">
+<Description>
+Hibernate procedure to kill a sequence, but can be used at any time</Description>
+<ClassMethod>1</ClassMethod>
+<FormalSpec>SequenceName:%String</FormalSpec>
+<ReturnType>%Integer</ReturnType>
+<SqlProc>1</SqlProc>
+<Implementation><![CDATA[
+ kill ^InterSystems.Sequences($zcvt(SequenceName,"U"))
+ quit 0
+]]></Implementation>
+</Method>
+
+<Storage name="custom">
+<Type>%CacheSQLStorage</Type>
+<StreamLocation>^InterSystems.SequencesS</StreamLocation>
+<Property name="Counter"/>
+<Property name="Name">
+<Selectivity>1</Selectivity>
+</Property>
+<SQLMap name="datamap">
+<Type>data</Type>
+<Global>^InterSystems.Sequences</Global>
+<Structure>delimited</Structure>
+<Subscript name="1">
+<Expression>{Name}</Expression>
+</Subscript>
+<Data name="Counter"/>
+</SQLMap>
+</Storage>
+</Class>
+<Checksum value="3603995477"/>
+</Export>
Modified: trunk/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java 2006-11-11 05:13:01 UTC (rev 10784)
+++ trunk/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java 2006-11-13 12:53:18 UTC (rev 10785)
@@ -1,4 +1,4 @@
-//$Id: $
+//$Id: $
package org.hibernate.dialect;
import java.sql.CallableStatement;
@@ -35,7 +35,6 @@
* Caché 2007.1 dialect. This class is required in order to use Hibernate with Intersystems Cach� SQL.<br>
* <br>
* Compatible with Cach� 2007.1.
- * Cache JDBC driver version ?.?.
* <br>
* <head>
* <title>Caché and Hibernate</title>
@@ -46,10 +45,7 @@
* These setup instructions assume that both Caché and Hibernate are installed and operational.
* <br>
* <h2>HIBERNATE DIRECTORIES AND FILES</h2>
- * InterSystems support for Hibernate 2.1.8 and Hibernate 3.0.5
- * requires different dialect files from those distributed with Hibernate 3.2.
- * Also Hibernate 2.1.8 has a different directory and Java package structure which is reflected in the InterSystems sources.
- * JBoss distributes the InterSystems Cache' dialect for Hibernate 3.2.
+ * JBoss distributes the InterSystems Cache' dialect for Hibernate 3.2.1
* For earlier versions of Hibernate please contact
* <a href="http://www.intersystems.com/support/cache-support.html">InterSystems Worldwide Response Center</A> (WRC)
* for the appropriate source files.
@@ -78,7 +74,6 @@
* Hibernate. The next step depends on the location of your
* CacheDB.jar depending on your version of Caché.
* <ol>
- * <li>Copy C:\CacheSys\dev\java\lib\CacheDB.jar to C:\Hibernate\lib\CacheDB.jar.</li>
* <li>Copy C:\CacheSys\dev\java\lib\JDK15\CacheDB.jar to C:\Hibernate\lib\CacheDB.jar.</li>
* <p/>
* <li>Insert the following files into your Java classpath:
@@ -99,18 +94,15 @@
* <table cols=3 border cellpadding=5 cellspacing=0>
* <tr>
* <th>Property Name</th>
- * <th>Property Value 3.2</th>
- * <th>Property Value 2.1.8</th>
+ * <th>Property Value</th>
* </tr>
* <tr>
* <td>hibernate.dialect</td>
* <td>org.hibernate.dialect.Cache71Dialect</td>
- * <td>net.sf.hibernate.dialect.Cache50Dialect</td>
* </tr>
* <tr>
* <td>hibernate.connection.driver_class</td>
* <td>com.intersys.jdbc.CacheDriver</td>
- * <td>com.intersys.jdbc.CacheDriver</td>
* </tr>
* <tr>
* <td>hibernate.connection.username</td>
@@ -125,7 +117,6 @@
* <tr>
* <td>hibernate.connection.url</td>
* <td>jdbc:Cache://127.0.0.1:1972/USER</td>
- * <td>jdbc:Cache://127.0.0.1:1972/USER</td>
* </tr>
* </table>
* <p/>
@@ -146,100 +137,24 @@
* <br>
* <p/>
* <ol>
- * <li>
- * org.hibernate.dialect.Cache50Dialect (requires Caché
- * 5.0 or above)
- * </li>
- * <p/>
- * <li>org.hibernate.dialect.Cache51Dialect (requires Caché 5.1 or
- * above)</li>
- * <p/>
- * <li>org.hibernate.dialect.Cache51SequenceDialect (requires Caché 5.1 or
- * above)</li>
- * <p/>
* <li>org.hibernate.dialect.Cache71Dialect (requires Caché
* 2007.1 or above)</li>
* <p/>
- * <li>org.hibernate.dialect.Cache71SequenceDialect (requires Caché
- * 2007.1 or above)</li>
* </ol>
- * <p/>
- * Setting up for Caché 5.0 is similar except that the hibernate
- * dialect package is "org.hibernate.dialect.Cache50Dialect"
* <br>
- * <h2>SETTING UP CACHÉ DIALECT FROM INTERSYSTEMS SOURCES</h2>
- * <p/>
- * InterSystems provides source code for the Hibernate Dialect classes.
- * Therefore, you must first place the source code in the proper locations
- * and compile it into Java class files.
- * Doing this will eliminate possible version mismatches in the compiled Java code.
- * <p/>
- * To begin, unzip the InterSystems source into the PARENT directory of the location where you installed Hibernate.
- * The InterSystems zip file that contains InterSystems Hibernate support for
- * Hibernate 2.1.8 and Hibernate 3.0.5 already contains hibernate-2.1
- * and hibernate-3.0 in its directory structure. This is why you must
- * unzip to the directory CONTAINING your Hibernate install directory.
- * <p/>
- * If you are using Hibernate 3.2, JBoss has already built the right JAR file for you.
- * If you are NOT using Hibernate 3.2, then you must do the following:
- * <p/>
- * <ol>
- * <li>In your Hibernate install directory, after the unzip we described above,
- * type the following:
- * <br>
- * <pre>
- * build
- * </pre></li>
- * <li>Copy the JAR file to the proper place.
- * <p/>
- * For Hibernate 3.0.5, copy
- * <pre>
- * ..\hibernate\hibernate3.jar
- * </pre>
- * to the Hibernate install directory.
- * <p/>
- * For Hibernate 2.1.8, copy
- * <pre>
- * ..\hibernate\hibernate.2jar
- * </pre>
- * to the Hibernate install directory.</li>
- * <p/>
- * <li>Test your installation by configuring etc\hibernate.properties for your Caché database,
- * and then running the following:
- * <pre>
- * build eg
- * </pre>
- * The build process reports its success or failure. If you see,
- * <pre>
- * BUILD FAILED
- * </pre>
- * please contact the
- * <a href="http://www.intersystems.com/support/cache-support.html">InterSystems Worldwide Response Center</A>
- * for assistance.
- * </li>
- * </ol>
- * <br>
* <h2>SUPPORT FOR IDENTITY COLUMNS</h2>
- * Caché 5.1 or later supports identity columns. This includes Cache' 2007.1. To cause
+ * Caché 2007.1 or later supports identity columns. For
* Hibernate to use identity columns, specify "native" as the
- * generator. Also make sure that
- * hibernate.jdbc.use_get_generated_keys is set to true, which is the
- * default. In the Cache' 2007.1 release, with the
- * Cache71Dialect, you can set hibernate.jdbc.use_get_generated_keys to
- * false, and still use identity columns.
+ * generator.
* <br>
* <h2>SEQUENCE DIALECTS SUPPORT SEQUENCES</h2>
- * You do not have to use the sequence dialects with Caché.
- * These are Cache50SequenceDialect, Cache51SequenceDialect and Cache71SequenceDialect.
- * But if you choose to use them, set them up as follows:
* <p/>
* To use Hibernate sequence support with Caché in a namespace, you must FIRST load the following file into that namespace:
* <pre>
* src\org\hibernate\dialect\CacheSequences.xml
* </pre>
* In your Hibernate mapping you can specify sequence use.
- * When you are using a Cache' sequence dialect, the type "native" maps to sequence.
- * <p/>
+ * <p>
* For example, the following shows the use of a sequence generator in a Hibernate mapping:
* <pre>
* <id name="id" column="uid" type="long" unsaved-value="null">
@@ -255,47 +170,6 @@
* getSelectSequenceNextValString() in the dialect. If this happens
* you will receive the error message: new MappingException( "Dialect
* does not support sequences" ).
- * <h2>BIGINT SUPPORT</h2>
- * Caché 5.1 and above supports BIGINT. 2007.1 supports BIGINT.
- * <p/>
- * Caché 5.0.x does not have direct BIGINT support.
- * To imitate BIGINT support in Cache 5.0.x, in the SQL configuration,
- * remap %INTEGER as follows, to be used by Caché 5.0.x dialects:
- * <p/>
- * <pre>
- * %Library.Integer(MAXVAL=99999999999999999999,MINVAL=-999999999999999999)
- * </pre>
- * <p/>
- * To change SQL settings:
- * <p/>
- * <ol>
- * <li>In Caché 2007.1, use the System Management Portal.</li>
- * <p/>
- * <li>In Caché 5.0, use the Configuration Manager.</li>
- * </ol>
- * <p/>
- * Set Caché SQL to allow:
- * <p/>
- * <ol>
- * <li>delimited identifiers</li>
- * <li>drop of non-existent tables</li>
- * <li>drop of non-existent constraints</li>
- * </ol>
- * <p/>
- * <h2>HIBERNATE 2.1.8</h2>
- * Hibernate 2.1.8 requires different source files from InterSystems reflecting
- * the different directory and Java package structure of Hibernate 2.1.8.
- * Please contact
- * <a href="http://www.intersystems.com/support/cache-support.html">InterSystems Worldwide Response Center</A> (WRC)
- * for these source files if you need to use Hibernate 2.1.8.
- * <p/>
- * To run a Cach� application with Hibernate 2.1.8, set the following flag when starting your JVM:
- * <pre>
- * -Dhibernate.jdbc.use_streams_for_binary=false
- * </pre>
- * <p/>
- * In Hibernate 3.0.5, this flag is not necessary;
- * it is taken care of by the Caché dialect itself.
* <br>
* <h2>HIBERNATE FILES ASSOCIATED WITH CACHÉ DIALECT</h2>
* The following files are associated with Caché dialect:
@@ -308,87 +182,6 @@
* <li>src\org\hibernate\sql\CacheJoinFragment.java</li>
* </ol>
* Cache71Dialect ships with Hibernate 3.2. All other dialects are distributed by InterSystems and subclass Cache71Dialect.
- * <h2>Limitations</h2>
- * The following is a list of the currently known limitations of using Cache' with Hibernate. Please check with InterSystems on the latest status as these are server side issues.
- * <p/>
- * The following also lists known issues with running the full Hibernate regression tests against InterSystems Cache'.
- * <p/>
- * - Delete of self-referential foreign keys.
- * <p/>
- * We do not current support deletion of a table row when the table has a foreign key that references itself and the foreign key in the table row references that table row. (self-referential foreign keys)
- * <p/>
- * - Support for "SELECT FOR UPDATE."
- * <p/>
- * The default locking mode strategy for Cache' is Hibernate's UpdateLockingStrategy, which you use with Hibernate's versioning capability.
- * <p/>
- * To use Concurrency modes that requires other locking strategies you can subclass your Cache' dialect and define a locking strategy.
- * <p/>
- * Cache' does not currently support "SELECT FOR UPDATE." While grammatically correct, it does no locking.
- * <p/>
- * In versions prior to 2007.1, there are limitations in support for outer joins (see Cache' documentation).
- * <p/>
- * For example, Cache' prior to 2007.1 does support "NOT NULL" clauses in the ON conditions.
- * <p/>
- * Cache' does not support using longvarbinary or longvarchar in a where clause.
- * <p/>
- * In Hibernate regression tests, Baz.hbm.xml, FooBar.hbm.xml, Glarch.hbm.xml and XY.hbm.xml have to be edited to replace "!" by BANG and "^" by CARET. Our own identifier translation is not enough since Hibernate uses names containing these in its own mapping files and Hibernate (on the client-side) does not know about our server-side mapping.
- * <p/>
- * There are some tests that involve batch operations where the test
- * will succeed if you increase the size of the lock table from
- * 786432 (the default) to 1786432. You can use the System Management
- * Portal in 2007.1 or the configuration manager in 5.0.X to increase the
- * size of the lock table. This requirement of increasing the lock
- * table size is specific to running the Hibernate regression tests.
- * <p/>
- * Cache' fails tests that attempt to COUNT stream fields
- * <p/>
- * Here is an example of such an error message, SQL ERROR -37: Aggregate function COUNT not supported for Stream fields
- * <p/>
- * We fail on tests that use mappings like the following
- * <p/>
- * <pre>
- * <property name="yob" formula="year(dob)"/>
- * </pre>
- * and the error is:
- * <p/>
- * ERROR #359: User defined SQL Function 'SQLUSER.YEAR' does not exist
- * <p/>
- * If the mapping is changed to
- * <p/>
- * <pre>
- * <property name="yob" formula="{fn year(dob)}"/>
- * </pre>
- * then such tests succeed.
- * <p/>
- * Cache' 2007.1 supports temp tables. Prior versions do not.
- * <p/>
- * We do not support row valued expression. So WHERE clauses like "WHERE (a,b,c) = (d,e,f)" give syntax errors. The Hibernate regression tests use row valued expressions and we fail on these.
- * <p/>
- * For example:
- * <p/>
- * <pre>
- * result = s.createQuery("from Transaction txn where txn.value = (1.5, 'AUD')").list();
- * </pre>
- * will not generate valid Cache' SQL because of the parenthesis around (1.5, 'AUD')
- * <p/>
- * Queries like the following:
- * <p/>
- * <pre>
- * session.createQuery("select extract(second from current_timestamp()), extract(minute from current_timestamp()), extract(hour from current_timestamp()) from Mammal m").list();
- * </pre>
- * <p/>
- * will not work, because we do support "extract" function.
- * <p/>
- * We do not support in () (empty parenthesis)
- * <p/>
- * We do not guarantee the case of a column returned using a group by clause.
- * <p/>
- * For instance in the regression test,
- * <p/>
- * <pre>
- * list = s.find("select new Result( baz.name, max(foo.long), count(foo) ) from Baz baz join baz.fooArray foo group by baz.name");
- * </pre>
- * we return baz.name in lower case, and the test that generates this SQL fails.
*
* @author Jonathan Levinson
*/
@@ -702,11 +495,11 @@
}
public String getSequenceNextValString(String sequenceName) {
- return "select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "'))";
+ return "select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "')";
}
public String getSelectSequenceNextValString(String sequenceName) {
- return "(select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "')))";
+ return "(select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "'))";
}
public String getCreateSequenceString(String sequenceName) {
18 years, 10 months
Hibernate SVN: r10784 - in trunk/Hibernate3: src/org/hibernate/event/def src/org/hibernate/type test/org/hibernate/test/interceptor
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-11-11 00:13:01 -0500 (Sat, 11 Nov 2006)
New Revision: 10784
Added:
trunk/Hibernate3/test/org/hibernate/test/interceptor/Image.hbm.xml
trunk/Hibernate3/test/org/hibernate/test/interceptor/Image.java
Modified:
trunk/Hibernate3/src/org/hibernate/event/def/DefaultFlushEntityEventListener.java
trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java
trunk/Hibernate3/src/org/hibernate/type/TypeFactory.java
trunk/Hibernate3/test/org/hibernate/test/interceptor/InterceptorTest.java
Log:
HHH-1921 & HHH-2027: interceptor/listener changing properties
Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultFlushEntityEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/DefaultFlushEntityEventListener.java 2006-11-11 05:12:37 UTC (rev 10783)
+++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultFlushEntityEventListener.java 2006-11-11 05:13:01 UTC (rev 10784)
@@ -232,16 +232,15 @@
);
}
}
-
- boolean substitute;
-
+
+ final boolean intercepted;
if ( !entry.isBeingReplicated() ) {
- // give the Interceptor a chance to process property values, if the properties
+ // give the Interceptor a chance to process property values, if the properties
// were modified by the Interceptor, we need to set them back to the object
- substitute = handleInterception(event);
+ intercepted = handleInterception( event );
}
else {
- substitute = false;
+ intercepted = false;
}
validate( entity, persister, status, entityMode );
@@ -251,9 +250,9 @@
// if it was dirtied by a collection only
int[] dirtyProperties = event.getDirtyProperties();
- if ( event.isDirtyCheckPossible() && dirtyProperties==null ) {
- if ( !event.hasDirtyCollection() ) {
- throw new AssertionFailure("dirty, but no dirty properties");
+ if ( event.isDirtyCheckPossible() && dirtyProperties == null ) {
+ if ( ! intercepted && !event.hasDirtyCollection() ) {
+ throw new AssertionFailure( "dirty, but no dirty properties" );
}
dirtyProperties = ArrayHelper.EMPTY_INT_ARRAY;
}
@@ -280,7 +279,7 @@
)
);
- return substitute;
+ return intercepted;
}
protected void validate(Object entity, EntityPersister persister, Status status, EntityMode entityMode) {
@@ -316,21 +315,19 @@
}
protected boolean invokeInterceptor(
- SessionImplementor session,
- Object entity,
- EntityEntry entry,
+ SessionImplementor session,
+ Object entity,
+ EntityEntry entry,
final Object[] values,
- EntityPersister persister
- ) {
- final boolean intercepted = session.getInterceptor().onFlushDirty(
+ EntityPersister persister) {
+ return session.getInterceptor().onFlushDirty(
entity,
entry.getId(),
values,
entry.getLoadedState(),
persister.getPropertyNames(),
persister.getPropertyTypes()
- );
- return intercepted;
+ );
}
/**
Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java 2006-11-11 05:12:37 UTC (rev 10783)
+++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java 2006-11-11 05:13:01 UTC (rev 10784)
@@ -352,27 +352,44 @@
}
protected void copyValues(
- final EntityPersister persister,
- final Object entity,
- final Object target,
+ final EntityPersister persister,
+ final Object entity,
+ final Object target,
final SessionImplementor source,
final Map copyCache,
- final ForeignKeyDirection foreignKeyDirection
- ) {
-
- final Object[] copiedValues = TypeFactory.replace(
+ final ForeignKeyDirection foreignKeyDirection) {
+
+ final Object[] copiedValues;
+
+ if ( foreignKeyDirection == ForeignKeyDirection.FOREIGN_KEY_TO_PARENT ) {
+ // this is the second pass through on a merge op, so here we limit the
+ // replacement to associations types (value types were already replaced
+ // during the first pass)
+ copiedValues = TypeFactory.replaceAssociations(
persister.getPropertyValues( entity, source.getEntityMode() ),
persister.getPropertyValues( target, source.getEntityMode() ),
persister.getPropertyTypes(),
source,
- target,
+ target,
copyCache,
foreignKeyDirection
- );
-
- persister.setPropertyValues( target, copiedValues, source.getEntityMode() );
+ );
}
+ else {
+ copiedValues = TypeFactory.replace(
+ persister.getPropertyValues( entity, source.getEntityMode() ),
+ persister.getPropertyValues( target, source.getEntityMode() ),
+ persister.getPropertyTypes(),
+ source,
+ target,
+ copyCache,
+ foreignKeyDirection
+ );
+ }
+ persister.setPropertyValues( target, copiedValues, source.getEntityMode() );
+ }
+
/**
* Perform any cascades needed as part of this copy event.
*
Modified: trunk/Hibernate3/src/org/hibernate/type/TypeFactory.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/type/TypeFactory.java 2006-11-11 05:12:37 UTC (rev 10783)
+++ trunk/Hibernate3/src/org/hibernate/type/TypeFactory.java 2006-11-11 05:13:01 UTC (rev 10784)
@@ -498,8 +498,43 @@
return copied;
}
+ /**
+ * Apply the {@link Type#replace} operation across a series of values, as
+ * long as the corresponding {@link Type} is an association.
+ *
+ * @param original The source of the state
+ * @param target The target into which to replace the source values.
+ * @param types The value types
+ * @param session The orginating session
+ * @param owner The entity "owning" the values
+ * @param copyCache A map representing a cache of already replaced state
+ * @param foreignKeyDirection FK directionality to be applied to the replacement
+ * @return The replaced state
+ */
+ public static Object[] replaceAssociations(
+ final Object[] original,
+ final Object[] target,
+ final Type[] types,
+ final SessionImplementor session,
+ final Object owner,
+ final Map copyCache,
+ final ForeignKeyDirection foreignKeyDirection) {
+ Object[] copied = new Object[original.length];
+ for ( int i = 0; i < types.length; i++ ) {
+ if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
+ || original[i] == BackrefPropertyAccessor.UNKNOWN
+ || !types[i].isAssociationType() ) {
+ copied[i] = target[i];
+ }
+ else {
+ copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache, foreignKeyDirection );
+ }
+ }
+ return copied;
+ }
+
/**
* Determine if any of the given field values are dirty, returning an array containing
* indices of the dirty fields.
Added: trunk/Hibernate3/test/org/hibernate/test/interceptor/Image.hbm.xml
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/interceptor/Image.hbm.xml 2006-11-11 05:12:37 UTC (rev 10783)
+++ trunk/Hibernate3/test/org/hibernate/test/interceptor/Image.hbm.xml 2006-11-11 05:13:01 UTC (rev 10784)
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+
+<hibernate-mapping package="org.hibernate.test.interceptor">
+
+ <class name="Image" table="image" abstract="false" select-before-update="true" >
+ <id name="id" type="java.lang.Long" column="id">
+ <generator class="native"/>
+ </id>
+ <component name="details" class="Image$Details">
+ <property name="perm1" not-null="true" type="long" column="permissions"/>
+ <property name="comment" type="string" column="comment_txt"/>
+ </component>
+ <property name="name" type="java.lang.String" column="name" not-null="true"/>
+ </class>
+
+</hibernate-mapping>
Added: trunk/Hibernate3/test/org/hibernate/test/interceptor/Image.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/interceptor/Image.java 2006-11-11 05:12:37 UTC (rev 10783)
+++ trunk/Hibernate3/test/org/hibernate/test/interceptor/Image.java 2006-11-11 05:13:01 UTC (rev 10784)
@@ -0,0 +1,63 @@
+package org.hibernate.test.interceptor;
+
+public class Image {
+
+ private Long id;
+ private String name;
+ private Details details;
+
+ public Details getDetails() {
+ return details;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setDetails(Details details) {
+ this.details = details;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ return "Image/" + ( details == null ? "no details" : details.toString() );
+ }
+
+ public static class Details {
+ private long perm1 = -1; // all bits turned on.
+ private String comment;
+
+ protected long getPerm1() {
+ return this.perm1;
+ }
+
+ protected void setPerm1(long value) {
+ this.perm1 = value;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+ public String toString() {
+ return "Details=" + perm1;
+ }
+ }
+
+}
+
Modified: trunk/Hibernate3/test/org/hibernate/test/interceptor/InterceptorTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/interceptor/InterceptorTest.java 2006-11-11 05:12:37 UTC (rev 10783)
+++ trunk/Hibernate3/test/org/hibernate/test/interceptor/InterceptorTest.java 2006-11-11 05:13:01 UTC (rev 10784)
@@ -2,19 +2,22 @@
package org.hibernate.test.interceptor;
import java.util.List;
+import java.io.Serializable;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.hibernate.Session;
import org.hibernate.Transaction;
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.type.Type;
import org.hibernate.test.TestCase;
/**
* @author Gavin King
*/
public class InterceptorTest extends TestCase {
-
+
public InterceptorTest(String str) {
super(str);
}
@@ -27,7 +30,7 @@
u.setPassword("vagni");
t.commit();
s.close();
-
+
s = openSession();
t = s.beginTransaction();
u = (User) s.get(User.class, "Gavin");
@@ -35,8 +38,8 @@
s.delete(u);
t.commit();
s.close();
- }
-
+ }
+
public void testPropertyIntercept() {
Session s = openSession( new PropertyInterceptor() );
Transaction t = s.beginTransaction();
@@ -45,7 +48,7 @@
u.setPassword("vagni");
t.commit();
s.close();
-
+
s = openSession();
t = s.beginTransaction();
u = (User) s.get(User.class, "Gavin");
@@ -54,20 +57,95 @@
s.delete(u);
t.commit();
s.close();
- }
-
+ }
+
+ /**
+ * Test case from HHH-1921. Here the interceptor resets the
+ * current-state to the same thing as the current db state; this
+ * causes EntityPersister.findDirty() to return no dirty properties.
+ */
+ public void testPropertyIntercept2() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ User u = new User("Josh", "test");
+ s.persist( u );
+ t.commit();
+ s.close();
+
+ s = openSession(
+ new EmptyInterceptor() {
+ public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
+ currentState[0] = "test";
+ return true;
+ }
+ }
+ );
+ t = s.beginTransaction();
+ u = ( User ) s.get( User.class, u.getName() );
+ u.setPassword( "nottest" );
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ u = (User) s.get(User.class, "Josh");
+ assertEquals("test", u.getPassword());
+ s.delete(u);
+ t.commit();
+ s.close();
+
+ }
+
+ public void testComponentInterceptor() {
+ final int checkPerm = 500;
+ final String checkComment = "generated from interceptor";
+
+ Session s = openSession(
+ new EmptyInterceptor() {
+ public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
+ if ( state[0] == null ) {
+ Image.Details detail = new Image.Details();
+ detail.setPerm1( checkPerm );
+ detail.setComment( checkComment );
+ state[0] = detail;
+ }
+ return true;
+ }
+ }
+ );
+ s.beginTransaction();
+ Image i = new Image();
+ i.setName( "compincomp" );
+ i = ( Image ) s.merge( i );
+ assertNotNull( i.getDetails() );
+ assertEquals( checkPerm, i.getDetails().getPerm1() );
+ assertEquals( checkComment, i.getDetails().getComment() );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ i = ( Image ) s.get( Image.class, i.getId() );
+ assertNotNull( i.getDetails() );
+ assertEquals( checkPerm, i.getDetails().getPerm1() );
+ assertEquals( checkComment, i.getDetails().getComment() );
+ s.delete( i );
+ s.getTransaction().commit();
+ s.close();
+ }
+
public void testStatefulIntercept() {
final StatefulInterceptor statefulInterceptor = new StatefulInterceptor();
Session s = openSession( statefulInterceptor );
statefulInterceptor.setSession(s);
-
+
Transaction t = s.beginTransaction();
User u = new User("Gavin", "nivag");
s.persist(u);
u.setPassword("vagni");
t.commit();
s.close();
-
+
s = openSession();
t = s.beginTransaction();
List logs = s.createCriteria(Log.class).list();
@@ -77,9 +155,9 @@
t.commit();
s.close();
}
-
+
protected String[] getMappings() {
- return new String[] { "interceptor/User.hbm.xml" };
+ return new String[] { "interceptor/User.hbm.xml", "interceptor/Image.hbm.xml" };
}
public static Test suite() {
18 years, 10 months
Hibernate SVN: r10783 - in branches/Branch_3_2/Hibernate3: src/org/hibernate/event/def src/org/hibernate/type test/org/hibernate/test/interceptor
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-11-11 00:12:37 -0500 (Sat, 11 Nov 2006)
New Revision: 10783
Added:
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/interceptor/Image.hbm.xml
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/interceptor/Image.java
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultFlushEntityEventListener.java
branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java
branches/Branch_3_2/Hibernate3/src/org/hibernate/type/TypeFactory.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/interceptor/InterceptorTest.java
Log:
HHH-1921 & HHH-2027: interceptor/listener changing properties
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultFlushEntityEventListener.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultFlushEntityEventListener.java 2006-11-11 04:27:51 UTC (rev 10782)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultFlushEntityEventListener.java 2006-11-11 05:12:37 UTC (rev 10783)
@@ -232,16 +232,16 @@
);
}
}
+
+ boolean intercepted;
- boolean substitute;
-
if ( !entry.isBeingReplicated() ) {
// give the Interceptor a chance to process property values, if the properties
// were modified by the Interceptor, we need to set them back to the object
- substitute = handleInterception(event);
+ intercepted = handleInterception( event );
}
else {
- substitute = false;
+ intercepted = false;
}
validate( entity, persister, status, entityMode );
@@ -251,9 +251,9 @@
// if it was dirtied by a collection only
int[] dirtyProperties = event.getDirtyProperties();
- if ( event.isDirtyCheckPossible() && dirtyProperties==null ) {
- if ( !event.hasDirtyCollection() ) {
- throw new AssertionFailure("dirty, but no dirty properties");
+ if ( event.isDirtyCheckPossible() && dirtyProperties == null ) {
+ if ( ! intercepted && !event.hasDirtyCollection() ) {
+ throw new AssertionFailure( "dirty, but no dirty properties" );
}
dirtyProperties = ArrayHelper.EMPTY_INT_ARRAY;
}
@@ -280,7 +280,7 @@
)
);
- return substitute;
+ return intercepted;
}
protected void validate(Object entity, EntityPersister persister, Status status, EntityMode entityMode) {
@@ -320,17 +320,15 @@
Object entity,
EntityEntry entry,
final Object[] values,
- EntityPersister persister
- ) {
- final boolean intercepted = session.getInterceptor().onFlushDirty(
+ EntityPersister persister) {
+ return session.getInterceptor().onFlushDirty(
entity,
entry.getId(),
values,
entry.getLoadedState(),
persister.getPropertyNames(),
persister.getPropertyTypes()
- );
- return intercepted;
+ );
}
/**
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java 2006-11-11 04:27:51 UTC (rev 10782)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java 2006-11-11 05:12:37 UTC (rev 10783)
@@ -172,7 +172,7 @@
final Object copy = persister.instantiate( id, source.getEntityMode() ); //TODO: should this be Session.instantiate(Persister, ...)?
copyCache.put(entity, copy); //before cascade!
- // cascade first, so that all unsaved objects get their
+ // cascade first, so that all unsaved objects get their
// copy created before we actually copy
//cascadeOnMerge(event, persister, entity, copyCache, Cascades.CASCADE_BEFORE_MERGE);
super.cascadeBeforeSave(source, persister, entity, copyCache);
@@ -350,27 +350,44 @@
}
protected void copyValues(
- final EntityPersister persister,
+ final EntityPersister persister,
final Object entity,
final Object target,
final SessionImplementor source,
final Map copyCache,
- final ForeignKeyDirection foreignKeyDirection
- ) {
-
- final Object[] copiedValues = TypeFactory.replace(
+ final ForeignKeyDirection foreignKeyDirection) {
+
+ final Object[] copiedValues;
+
+ if ( foreignKeyDirection == ForeignKeyDirection.FOREIGN_KEY_TO_PARENT ) {
+ // this is the second pass through on a merge op, so here we limit the
+ // replacement to associations types (value types were already replaced
+ // during the first pass)
+ copiedValues = TypeFactory.replaceAssociations(
persister.getPropertyValues( entity, source.getEntityMode() ),
persister.getPropertyValues( target, source.getEntityMode() ),
persister.getPropertyTypes(),
source,
- target,
+ target,
copyCache,
foreignKeyDirection
- );
-
- persister.setPropertyValues( target, copiedValues, source.getEntityMode() );
+ );
}
+ else {
+ copiedValues = TypeFactory.replace(
+ persister.getPropertyValues( entity, source.getEntityMode() ),
+ persister.getPropertyValues( target, source.getEntityMode() ),
+ persister.getPropertyTypes(),
+ source,
+ target,
+ copyCache,
+ foreignKeyDirection
+ );
+ }
+ persister.setPropertyValues( target, copiedValues, source.getEntityMode() );
+ }
+
/**
* Perform any cascades needed as part of this copy event.
*
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/type/TypeFactory.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/type/TypeFactory.java 2006-11-11 04:27:51 UTC (rev 10782)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/type/TypeFactory.java 2006-11-11 05:12:37 UTC (rev 10783)
@@ -498,6 +498,40 @@
return copied;
}
+ /**
+ * Apply the {@link Type#replace} operation across a series of values, as
+ * long as the corresponding {@link Type} is an association.
+ *
+ * @param original The source of the state
+ * @param target The target into which to replace the source values.
+ * @param types The value types
+ * @param session The orginating session
+ * @param owner The entity "owning" the values
+ * @param copyCache A map representing a cache of already replaced state
+ * @param foreignKeyDirection FK directionality to be applied to the replacement
+ * @return The replaced state
+ */
+ public static Object[] replaceAssociations(
+ final Object[] original,
+ final Object[] target,
+ final Type[] types,
+ final SessionImplementor session,
+ final Object owner,
+ final Map copyCache,
+ final ForeignKeyDirection foreignKeyDirection) {
+ Object[] copied = new Object[original.length];
+ for ( int i = 0; i < types.length; i++ ) {
+ if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
+ || original[i] == BackrefPropertyAccessor.UNKNOWN
+ || !types[i].isAssociationType() ) {
+ copied[i] = target[i];
+ }
+ else {
+ copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache, foreignKeyDirection );
+ }
+ }
+ return copied;
+ }
/**
Added: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/interceptor/Image.hbm.xml
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/interceptor/Image.hbm.xml 2006-11-11 04:27:51 UTC (rev 10782)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/interceptor/Image.hbm.xml 2006-11-11 05:12:37 UTC (rev 10783)
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+
+<hibernate-mapping package="org.hibernate.test.interceptor">
+
+ <class name="Image" table="image" abstract="false" select-before-update="true" >
+ <id name="id" type="java.lang.Long" column="id">
+ <generator class="native"/>
+ </id>
+ <component name="details" class="Image$Details">
+ <property name="perm1" not-null="true" type="long" column="permissions"/>
+ <property name="comment" type="string" column="comment_txt"/>
+ </component>
+ <property name="name" type="java.lang.String" column="name" not-null="true"/>
+ </class>
+
+</hibernate-mapping>
Added: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/interceptor/Image.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/interceptor/Image.java 2006-11-11 04:27:51 UTC (rev 10782)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/interceptor/Image.java 2006-11-11 05:12:37 UTC (rev 10783)
@@ -0,0 +1,63 @@
+package org.hibernate.test.interceptor;
+
+public class Image {
+
+ private Long id;
+ private String name;
+ private Details details;
+
+ public Details getDetails() {
+ return details;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setDetails(Details details) {
+ this.details = details;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ return "Image/" + ( details == null ? "no details" : details.toString() );
+ }
+
+ public static class Details {
+ private long perm1 = -1; // all bits turned on.
+ private String comment;
+
+ protected long getPerm1() {
+ return this.perm1;
+ }
+
+ protected void setPerm1(long value) {
+ this.perm1 = value;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+ public String toString() {
+ return "Details=" + perm1;
+ }
+ }
+
+}
+
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/interceptor/InterceptorTest.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/interceptor/InterceptorTest.java 2006-11-11 04:27:51 UTC (rev 10782)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/interceptor/InterceptorTest.java 2006-11-11 05:12:37 UTC (rev 10783)
@@ -2,12 +2,15 @@
package org.hibernate.test.interceptor;
import java.util.List;
+import java.io.Serializable;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.hibernate.Session;
import org.hibernate.Transaction;
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.type.Type;
import org.hibernate.test.TestCase;
/**
@@ -54,8 +57,83 @@
s.delete(u);
t.commit();
s.close();
- }
-
+ }
+
+ /**
+ * Test case from HHH-1921. Here the interceptor resets the
+ * current-state to the same thing as the current db state; this
+ * causes EntityPersister.findDirty() to return no dirty properties.
+ */
+ public void testPropertyIntercept2() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ User u = new User("Josh", "test");
+ s.persist( u );
+ t.commit();
+ s.close();
+
+ s = openSession(
+ new EmptyInterceptor() {
+ public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
+ currentState[0] = "test";
+ return true;
+ }
+ }
+ );
+ t = s.beginTransaction();
+ u = ( User ) s.get( User.class, u.getName() );
+ u.setPassword( "nottest" );
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ u = (User) s.get(User.class, "Josh");
+ assertEquals("test", u.getPassword());
+ s.delete(u);
+ t.commit();
+ s.close();
+
+ }
+
+ public void testComponentInterceptor() {
+ final int checkPerm = 500;
+ final String checkComment = "generated from interceptor";
+
+ Session s = openSession(
+ new EmptyInterceptor() {
+ public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
+ if ( state[0] == null ) {
+ Image.Details detail = new Image.Details();
+ detail.setPerm1( checkPerm );
+ detail.setComment( checkComment );
+ state[0] = detail;
+ }
+ return true;
+ }
+ }
+ );
+ s.beginTransaction();
+ Image i = new Image();
+ i.setName( "compincomp" );
+ i = ( Image ) s.merge( i );
+ assertNotNull( i.getDetails() );
+ assertEquals( checkPerm, i.getDetails().getPerm1() );
+ assertEquals( checkComment, i.getDetails().getComment() );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ i = ( Image ) s.get( Image.class, i.getId() );
+ assertNotNull( i.getDetails() );
+ assertEquals( checkPerm, i.getDetails().getPerm1() );
+ assertEquals( checkComment, i.getDetails().getComment() );
+ s.delete( i );
+ s.getTransaction().commit();
+ s.close();
+ }
+
public void testStatefulIntercept() {
final StatefulInterceptor statefulInterceptor = new StatefulInterceptor();
Session s = openSession( statefulInterceptor );
@@ -79,7 +157,7 @@
}
protected String[] getMappings() {
- return new String[] { "interceptor/User.hbm.xml" };
+ return new String[] { "interceptor/User.hbm.xml", "interceptor/Image.hbm.xml" };
}
public static Test suite() {
18 years, 10 months