Author: ste...@jb... Date: 2006-03-14 19:12:47 -0500 (Tue, 14 Mar 2006) New Revision: 9619 Added: trunk/Hibernate3/src/org/hibernate/bytecode/BasicProxyFactory.java trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/ trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/ trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/AbstractCompositeIdTest.java trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/Mappings.hbm.xml trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/MyInterface.java trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/MyInterfaceImpl.java trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/ trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/AbstractComponentPropertyRefTest.java trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/Address.java trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/AddressImpl.java trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/Mappings.hbm.xml trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/Server.java trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/ServerImpl.java Modified: trunk/Hibernate3/src/org/hibernate/bytecode/BytecodeProvider.java trunk/Hibernate3/src/org/hibernate/bytecode/ProxyFactoryFactory.java trunk/Hibernate3/src/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java trunk/Hibernate3/src/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java trunk/Hibernate3/src/org/hibernate/cfg/Configuration.java trunk/Hibernate3/src/org/hibernate/mapping/Component.java trunk/Hibernate3/src/org/hibernate/mapping/Index.java trunk/Hibernate3/src/org/hibernate/mapping/Table.java trunk/Hibernate3/src/org/hibernate/tuple/PojoComponentTuplizer.java trunk/Hibernate3/test/org/hibernate/test/AllTests.java Log: HHH-535 : embedded components (<composite-id/> and <properties/>) defined on non-concrete entities Added: trunk/Hibernate3/src/org/hibernate/bytecode/BasicProxyFactory.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/bytecode/BasicProxyFactory.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/src/org/hibernate/bytecode/BasicProxyFactory.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -0,0 +1,10 @@ +package org.hibernate.bytecode; + +/** + * A proxy factory for "basic proxy" generation + * + * @author Steve Ebersole + */ +public interface BasicProxyFactory { + public Object getProxy(); +} Modified: trunk/Hibernate3/src/org/hibernate/bytecode/BytecodeProvider.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/bytecode/BytecodeProvider.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/src/org/hibernate/bytecode/BytecodeProvider.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -2,6 +2,15 @@ /** * Contract for providers of bytecode services to Hibernate. + * <p/> + * Bytecode requirements break down into basically 4 areas<ol> + * <li>proxy generation (both for runtime-lazy-loading and basic proxy generation) + * {@link #getProxyFactoryFactory()} + * <li>bean relection optimization {@link #getReflectionOptimizer} + * <li>build-time instumentation (not covered by this contract) + * <li>class-load intrumentation {@link #generateDynamicFieldInterceptionClassLoader}; + * (currently only used in the test suite). + * </ol> * * @author Steve Ebersole */ Modified: trunk/Hibernate3/src/org/hibernate/bytecode/ProxyFactoryFactory.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/bytecode/ProxyFactoryFactory.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/src/org/hibernate/bytecode/ProxyFactoryFactory.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -11,5 +11,27 @@ * @author Steve Ebersole */ public interface ProxyFactoryFactory { + /** + * Build a proxy factory specifically for handling runtime + * lazy loading. + * + * @return The lazy-load proxy factory. + */ public ProxyFactory buildProxyFactory(); + + /** + * Build a proxy factory for basic proxy concerns. The return + * should be capable of properly handling newInstance() calls. + * <p/> + * Should build basic proxies essentially equivalent to JDK proxies in + * terms of capabilities, but should be able to deal with abstract super + * classes in addition to proxy interfaces. + * <p/> + * Must pass in either superClass or interfaces (or both). + * + * @param superClass The abstract super class (or null if none). + * @param interfaces Interfaces to be proxied (or null if none). + * @return The proxy class + */ + public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces); } Modified: trunk/Hibernate3/src/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/src/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -1,15 +1,29 @@ package org.hibernate.bytecode.cglib; import org.hibernate.bytecode.ProxyFactoryFactory; +import org.hibernate.bytecode.BasicProxyFactory; import org.hibernate.proxy.ProxyFactory; import org.hibernate.proxy.pojo.cglib.CGLIBProxyFactory; +import org.hibernate.AssertionFailure; +import org.hibernate.HibernateException; +import net.sf.cglib.proxy.Enhancer; +import net.sf.cglib.proxy.CallbackFilter; +import net.sf.cglib.proxy.MethodInterceptor; +import net.sf.cglib.proxy.MethodProxy; +import net.sf.cglib.proxy.NoOp; +import net.sf.cglib.proxy.Callback; +import net.sf.cglib.proxy.Factory; +import java.lang.reflect.Method; +import java.util.HashMap; + /** * A factory for CGLIB-based {@link ProxyFactory} instances. * * @author Steve Ebersole */ public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory { + /** * Builds a CGLIB-based proxy factory. * @@ -18,4 +32,110 @@ public ProxyFactory buildProxyFactory() { return new CGLIBProxyFactory(); } + + public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces) { + return new BasicProxyFactoryImpl( superClass, interfaces ); + } + + public static class BasicProxyFactoryImpl implements BasicProxyFactory { + private final Class proxyClass; + private final Factory factory; + + public BasicProxyFactoryImpl(Class superClass, Class[] interfaces) { + if ( superClass == null && ( interfaces == null || interfaces.length < 1 ) ) { + throw new AssertionFailure( "attempting to build proxy without any superclass or interfaces" ); + } + + Enhancer en = new Enhancer(); + en.setUseCache( false ); + en.setInterceptDuringConstruction( false ); + en.setUseFactory( true ); + en.setCallbackTypes( CALLBACK_TYPES ); + en.setCallbackFilter( FINALIZE_FILTER ); + if ( superClass != null ) { + en.setSuperclass( superClass ); + } + if ( interfaces != null && interfaces.length > 0 ) { + en.setInterfaces( interfaces ); + } + proxyClass = en.createClass(); + try { + factory = ( Factory ) proxyClass.newInstance(); + } + catch ( Throwable t ) { + throw new HibernateException( "Unable to build CGLIB Factory instance" ); + } + } + + public Object getProxy() { + try { + return factory.newInstance( + new Callback[] { new PassThroughInterceptor( proxyClass.getName() ), NoOp.INSTANCE } + ); + } + catch ( Throwable t ) { + throw new HibernateException( "Unable to instantiate proxy instance" ); + } + } + } + + private static final CallbackFilter FINALIZE_FILTER = new CallbackFilter() { + public int accept(Method method) { + if ( method.getParameterTypes().length == 0 && method.getName().equals("finalize") ){ + return 1; + } + else { + return 0; + } + } + }; + + private static final Class[] CALLBACK_TYPES = new Class[] { MethodInterceptor.class, NoOp.class }; + + private static class PassThroughInterceptor implements MethodInterceptor { + private HashMap data = new HashMap(); + private final String proxiedClassName; + + public PassThroughInterceptor(String proxiedClassName) { + this.proxiedClassName = proxiedClassName; + } + + public Object intercept( + Object obj, + Method method, + Object[] args, + MethodProxy proxy) throws Throwable { + String name = method.getName(); + if ( "toString".equals( name ) ) { + return proxiedClassName + "@" + System.identityHashCode( obj ); + } + else if ( "equals".equals( name ) ) { + return args[0] instanceof Factory && ( ( Factory ) args[0] ).getCallback( 0 ) == this + ? Boolean.TRUE + : Boolean.FALSE; + } + else if ( "hashCode".equals( name ) ) { + return new Integer( System.identityHashCode( obj ) ); + } + boolean hasGetterSignature = method.getParameterTypes().length == 0 && method.getReturnType() != null; + boolean hasSetterSignature = method.getParameterTypes().length == 1 && ( method.getReturnType() == null || method.getReturnType() == void.class ); + if ( name.startsWith( "get" ) && hasGetterSignature ) { + String propName = name.substring( 3 ); + return data.get( propName ); + } + else if ( name.startsWith( "is" ) && hasGetterSignature ) { + String propName = name.substring( 2 ); + return data.get( propName ); + } + else if ( name.startsWith( "set" ) && hasSetterSignature) { + String propName = name.substring( 3 ); + data.put( propName, args[0] ); + return null; + } + else { + // todo : what else to do here? + return null; + } + } + } } Modified: trunk/Hibernate3/src/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/src/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -1,15 +1,25 @@ package org.hibernate.bytecode.javassist; import org.hibernate.bytecode.ProxyFactoryFactory; +import org.hibernate.bytecode.BasicProxyFactory; import org.hibernate.proxy.ProxyFactory; import org.hibernate.proxy.pojo.javassist.JavassistProxyFactory; +import org.hibernate.AssertionFailure; +import org.hibernate.HibernateException; +import javassist.util.proxy.MethodFilter; +import javassist.util.proxy.ProxyObject; +import javassist.util.proxy.MethodHandler; +import java.lang.reflect.Method; +import java.util.HashMap; + /** * A factory for Javassist-based {@link ProxyFactory} instances. * * @author Steve Ebersole */ public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory { + /** * Builds a Javassist-based proxy factory. * @@ -18,4 +28,96 @@ public ProxyFactory buildProxyFactory() { return new JavassistProxyFactory(); } + + public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces) { + return new BasicProxyFactoryImpl( superClass, interfaces ); + } + + private static class BasicProxyFactoryImpl implements BasicProxyFactory { + private final Class proxyClass; + + public BasicProxyFactoryImpl(Class superClass, Class[] interfaces) { + if ( superClass == null && ( interfaces == null || interfaces.length < 1 ) ) { + throw new AssertionFailure( "attempting to build proxy without any superclass or interfaces" ); + } + javassist.util.proxy.ProxyFactory factory = new javassist.util.proxy.ProxyFactory(); + factory.setFilter( FINALIZE_FILTER ); + if ( superClass != null ) { + factory.setSuperclass( superClass ); + } + if ( interfaces != null && interfaces.length > 0 ) { + factory.setInterfaces( interfaces ); + } + proxyClass = factory.createClass(); + } + + public Object getProxy() { + try { + ProxyObject proxy = ( ProxyObject ) proxyClass.newInstance(); + proxy.setHandler( new PassThroughHandler( proxy, proxyClass.getName() ) ); + return proxy; + } + catch ( Throwable t ) { + throw new HibernateException( "Unable to instantiated proxy instance" ); + } + } + + public boolean isInstance(Object object) { + return proxyClass.isInstance( object ); + } + } + + private static final MethodFilter FINALIZE_FILTER = new MethodFilter() { + public boolean isHandled(Method m) { + // skip finalize methods + return !( m.getParameterTypes().length == 0 && m.getName().equals( "finalize" ) ); + } + }; + + private static class PassThroughHandler implements MethodHandler { + private HashMap data = new HashMap(); + private final Object proxiedObject; + private final String proxiedClassName; + + public PassThroughHandler(Object proxiedObject, String proxiedClassName) { + this.proxiedObject = proxiedObject; + this.proxiedClassName = proxiedClassName; + } + + public Object invoke( + Object object, + Method method, + Method method1, + Object[] args) throws Exception { + String name = method.getName(); + if ( "toString".equals( name ) ) { + return proxiedClassName + "@" + System.identityHashCode( object ); + } + else if ( "equals".equals( name ) ) { + return proxiedObject == object ? Boolean.TRUE : Boolean.FALSE; + } + else if ( "hashCode".equals( name ) ) { + return new Integer( System.identityHashCode( object ) ); + } + boolean hasGetterSignature = method.getParameterTypes().length == 0 && method.getReturnType() != null; + boolean hasSetterSignature = method.getParameterTypes().length == 1 && ( method.getReturnType() == null || method.getReturnType() == void.class ); + if ( name.startsWith( "get" ) && hasGetterSignature ) { + String propName = name.substring( 3 ); + return data.get( propName ); + } + else if ( name.startsWith( "is" ) && hasGetterSignature ) { + String propName = name.substring( 2 ); + return data.get( propName ); + } + else if ( name.startsWith( "set" ) && hasSetterSignature) { + String propName = name.substring( 3 ); + data.put( propName, args[0] ); + return null; + } + else { + // todo : what else to do here? + return null; + } + } + } } Modified: trunk/Hibernate3/src/org/hibernate/cfg/Configuration.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/cfg/Configuration.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/src/org/hibernate/cfg/Configuration.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -1906,7 +1906,7 @@ return this; } - private Mapping buildMapping() { + public Mapping buildMapping() { return new Mapping() { /** * Returns the identifier type of a mapped class Modified: trunk/Hibernate3/src/org/hibernate/mapping/Component.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/mapping/Component.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/src/org/hibernate/mapping/Component.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -138,7 +138,17 @@ this.dynamic = dynamic; } + private Type type; + public Type getType() throws MappingException { + // added this caching as I noticed that getType() is being called multiple times... + if ( type == null ) { + type = buildType(); + } + return type; + } + + private Type buildType() { final int span = getPropertySpan(); String[] names = new String[span]; org.hibernate.type.Type[] types = new org.hibernate.type.Type[span]; Modified: trunk/Hibernate3/src/org/hibernate/mapping/Index.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/mapping/Index.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/src/org/hibernate/mapping/Index.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -57,7 +57,7 @@ String defaultSchema ) { StringBuffer buf = new StringBuffer("create") - .append( unique ? " unique " : "") + .append( unique ? " unique" : "") .append(" index ") .append( dialect.qualifyIndexName() ? name : StringHelper.unqualify(name) ) .append(" on ") Modified: trunk/Hibernate3/src/org/hibernate/mapping/Table.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/mapping/Table.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/src/org/hibernate/mapping/Table.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -86,7 +86,9 @@ } public String getQualifiedName(Dialect dialect, String defaultCatalog, String defaultSchema) { - if ( subselect != null ) return "( " + subselect + " )"; + if ( subselect != null ) { + return "( " + subselect + " )"; + } String quotedName = getQuotedName(dialect); String usedSchema = schema == null ? defaultSchema : getQuotedSchema(dialect); String usedCatalog = catalog == null ? defaultCatalog : catalog; @@ -151,7 +153,9 @@ * @return the underlying column or null if not inside this table. Note: the instance *can* be different than the input parameter, but the name will be the same. */ public Column getColumn(Column column) { - if (column == null) return null; + if ( column == null ) { + return null; + } Column myColumn = ( Column ) columns.get( column.getCanonicalName() ); @@ -162,7 +166,9 @@ public Column getColumn(int n) { Iterator iter = columns.values().iterator(); - for ( int i = 0; i < n - 1; i++ ) iter.next(); + for ( int i = 0; i < n - 1; i++ ) { + iter.next(); + } return ( Column ) iter.next(); } @@ -276,7 +282,9 @@ } String columnComment = column.getComment(); - if (columnComment!=null) alter.append( dialect.getColumnComment(columnComment) ); + if ( columnComment != null ) { + alter.append( dialect.getColumnComment( columnComment ) ); + } results.add( alter.toString() ); } @@ -385,7 +393,9 @@ buf.append( dialect.getColumnComment(columnComment) ); } - if ( iter.hasNext() ) buf.append( ", " ); + if ( iter.hasNext() ) { + buf.append( ", " ); + } } if ( hasPrimaryKey() ) { @@ -417,18 +427,24 @@ } buf.append( ')' ); + + if ( comment != null ) { + buf.append( dialect.getTableComment( comment ) ); + } - if (comment!=null) buf.append( dialect.getTableComment(comment) ); - return buf.append( dialect.getTableTypeString() ).toString(); } public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) { StringBuffer buf = new StringBuffer( "drop table " ); - if ( dialect.supportsIfExistsBeforeTableName() ) buf.append( "if exists " ); + if ( dialect.supportsIfExistsBeforeTableName() ) { + buf.append( "if exists " ); + } buf.append( getQualifiedName( dialect , defaultCatalog, defaultSchema ) ) .append( dialect.getCascadeConstraintsString() ); - if ( dialect.supportsIfExistsAfterTableName() ) buf.append( " if exists" ); + if ( dialect.supportsIfExistsAfterTableName() ) { + buf.append( " if exists" ); + } return buf.toString(); } @@ -524,10 +540,14 @@ foreignKeys.put( key, fk ); fk.setReferencedEntityName( referencedEntityName ); fk.addColumns( keyColumns.iterator() ); - if(referencedColumns!=null) fk.addReferencedColumns( referencedColumns.iterator() ); + if ( referencedColumns != null ) { + fk.addReferencedColumns( referencedColumns.iterator() ); + } } - if ( keyName != null ) fk.setName( keyName ); + if ( keyName != null ) { + fk.setName( keyName ); + } return fk; } @@ -538,8 +558,12 @@ public String uniqueColumnString(Iterator iterator, String referencedEntityName) { int result = 0; - if (referencedEntityName!=null) result += referencedEntityName.hashCode(); - while ( iterator.hasNext() ) result += iterator.next().hashCode(); + if ( referencedEntityName != null ) { + result += referencedEntityName.hashCode(); + } + while ( iterator.hasNext() ) { + result += iterator.next().hashCode(); + } return ( Integer.toHexString( name.hashCode() ) + Integer.toHexString( result ) ).toUpperCase(); } @@ -574,6 +598,10 @@ this.idValue = idValue; } + public KeyValue getIdentifierValue() { + return idValue; + } + public boolean isSchemaQuoted() { return schemaQuoted; } @@ -605,8 +633,12 @@ public String toString() { StringBuffer buf = new StringBuffer().append( getClass().getName() ) .append('('); - if ( getCatalog()!=null ) buf.append( getCatalog() + "." ); - if ( getSchema()!=null ) buf.append( getSchema()+ "."); + if ( getCatalog() != null ) { + buf.append( getCatalog() + "." ); + } + if ( getSchema() != null ) { + buf.append( getSchema() + "." ); + } buf.append( getName() ).append(')'); return buf.toString(); } @@ -654,7 +686,11 @@ public void setComment(String comment) { this.comment = comment; } - + + public Iterator getCheckConstraintsIterator() { + return checkConstraints.iterator(); + } + public Iterator sqlCommentStrings(Dialect dialect, String defaultCatalog, String defaultSchema) { List comments = new ArrayList(); if ( dialect.supportsCommentOn() ) { Modified: trunk/Hibernate3/src/org/hibernate/tuple/PojoComponentTuplizer.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/tuple/PojoComponentTuplizer.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/src/org/hibernate/tuple/PojoComponentTuplizer.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -2,9 +2,13 @@ package org.hibernate.tuple; import java.lang.reflect.Method; +import java.io.Serializable; import org.hibernate.HibernateException; +import org.hibernate.AssertionFailure; +import org.hibernate.util.ReflectHelper; import org.hibernate.bytecode.ReflectionOptimizer; +import org.hibernate.bytecode.BasicProxyFactory; import org.hibernate.cfg.Environment; import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.mapping.Component; @@ -18,7 +22,7 @@ * @author Gavin King */ public class PojoComponentTuplizer extends AbstractComponentTuplizer { - + private final Class componentClass; private ReflectionOptimizer optimizer; private final Getter parentGetter; @@ -63,7 +67,7 @@ public Class getMappedClass() { return componentClass; } - + public Object[] getPropertyValues(Object component) throws HibernateException { if ( optimizer != null && optimizer.getAccessOptimizer() != null ) { return optimizer.getAccessOptimizer().getPropertyValues( component ); @@ -82,15 +86,15 @@ } } - + public Object getParent(Object component) { return parentGetter.get( component ); } - + public boolean hasParentProperty() { return parentGetter!=null; } - + public boolean isMethodOf(Method method) { for ( int i=0; i<propertySpan; i++ ) { final Method getterMethod = getters[i].getMethod(); @@ -98,12 +102,15 @@ } return false; } - + public void setParent(Object component, Object parent, SessionFactoryImplementor factory) { parentSetter.set(component, parent, factory); } - + protected Instantiator buildInstantiator(Component component) { + if ( component.isEmbedded() && ReflectHelper.isAbstractClass( component.getComponentClass() ) ) { + return new ProxiedInstantiator( component ); + } if ( optimizer == null ) { return new PojoInstantiator( component, null ); } @@ -120,4 +127,34 @@ return prop.getSetter( component.getComponentClass() ); } + private static class ProxiedInstantiator implements Instantiator { + private final Class proxiedClass; + private final BasicProxyFactory factory; + + public ProxiedInstantiator(Component component) { + proxiedClass = component.getComponentClass(); + if ( proxiedClass.isInterface() ) { + factory = Environment.getBytecodeProvider() + .getProxyFactoryFactory() + .buildBasicProxyFactory( null, new Class[] { proxiedClass } ); + } + else { + factory = Environment.getBytecodeProvider() + .getProxyFactoryFactory() + .buildBasicProxyFactory( proxiedClass, null ); + } + } + + public Object instantiate(Serializable id) { + throw new AssertionFailure( "ProxiedInstantiator can only be used to instantiate component" ); + } + + public Object instantiate() { + return factory.getProxy(); + } + + public boolean isInstance(Object object) { + return proxiedClass.isInstance( object ); + } + } } Modified: trunk/Hibernate3/test/org/hibernate/test/AllTests.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/AllTests.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/test/org/hibernate/test/AllTests.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -128,6 +128,8 @@ import org.hibernate.test.version.sybase.SybaseTimestampVersioningTest; import org.hibernate.test.where.WhereTest; import org.hibernate.test.ejb3.EJB3Suite; +import org.hibernate.test.abstractembeddedcomponents.propertyref.AbstractComponentPropertyRefTest; +import org.hibernate.test.abstractembeddedcomponents.cid.AbstractCompositeIdTest; import org.hibernate.dialect.Dialect; /** @@ -288,6 +290,8 @@ suite.addTest( org.hibernate.test.bytecode.cglib.ReflectionOptimizerTest.suite() ); suite.addTest( org.hibernate.test.bytecode.javassist.ReflectionOptimizerTest.suite() ); suite.addTest( EJB3Suite.suite() ); + suite.addTest( AbstractComponentPropertyRefTest.suite() ); + suite.addTest( AbstractCompositeIdTest.suite() ); return filter( suite ); //return suite; Added: trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/AbstractCompositeIdTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/AbstractCompositeIdTest.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/AbstractCompositeIdTest.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -0,0 +1,43 @@ +package org.hibernate.test.abstractembeddedcomponents.cid; + +import org.hibernate.test.TestCase; +import org.hibernate.Session; +import org.hibernate.Transaction; +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * @author Steve Ebersole + */ +public class AbstractCompositeIdTest extends TestCase { + public AbstractCompositeIdTest(String x) { + super( x ); + } + + public static Test suite() { + return new TestSuite( AbstractCompositeIdTest.class ); + } + + protected String[] getMappings() { + return new String[] { "abstractembeddedcomponents/cid/Mappings.hbm.xml" }; + } + + public void testEmbeddedCompositeIdentifierOnAbstractClass() { + MyInterfaceImpl myInterface = new MyInterfaceImpl(); + myInterface.setKey1( "key1" ); + myInterface.setKey2( "key2" ); + myInterface.setName( "test" ); + + Session s = openSession(); + Transaction t = s.beginTransaction(); + s.save( myInterface ); + s.flush(); + + s.createQuery( "from MyInterface" ).list(); + + s.delete( myInterface ); + t.commit(); + s.close(); + + } +} Added: trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/Mappings.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/Mappings.hbm.xml 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/Mappings.hbm.xml 2006-03-15 00:12:47 UTC (rev 9619) @@ -0,0 +1,20 @@ +<?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.abstractembeddedcomponents.cid"> + + <class name="MyInterface" table="MY_INTF" proxy="MyInterface"> + <composite-id> + <key-property name="key1" type="string"/> + <key-property name="key2" type="string"/> + </composite-id> + <discriminator column="TYPE" type="string" length="10"/> + <property name="name" type="string"/> + </class> + + <subclass name="MyInterfaceImpl" extends="MyInterface" discriminator-value="1" proxy="MyInterface"> + </subclass> + +</hibernate-mapping> Added: trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/MyInterface.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/MyInterface.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/MyInterface.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -0,0 +1,15 @@ +package org.hibernate.test.abstractembeddedcomponents.cid; + +import java.io.Serializable; + +/** + * @author Steve Ebersole + */ +public interface MyInterface extends Serializable { + public String getKey1(); + public void setKey1(String key1); + public String getKey2(); + public void setKey2(String key2); + public String getName(); + public void setName(String name); +} Added: trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/MyInterfaceImpl.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/MyInterfaceImpl.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/cid/MyInterfaceImpl.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -0,0 +1,36 @@ +package org.hibernate.test.abstractembeddedcomponents.cid; + +import org.hibernate.test.abstractembeddedcomponents.cid.MyInterface; + +/** + * @author Steve Ebersole + */ +public class MyInterfaceImpl implements MyInterface { + private String key1; + private String key2; + private String name; + + public String getKey1() { + return key1; + } + + public void setKey1(String key1) { + this.key1 = key1; + } + + public String getKey2() { + return key2; + } + + public void setKey2(String key2) { + this.key2 = key2; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} Added: trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/AbstractComponentPropertyRefTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/AbstractComponentPropertyRefTest.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/AbstractComponentPropertyRefTest.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -0,0 +1,48 @@ +package org.hibernate.test.abstractembeddedcomponents.propertyref; + +import org.hibernate.test.TestCase; +import org.hibernate.Session; +import org.hibernate.Transaction; +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * @author Steve Ebersole + */ +public class AbstractComponentPropertyRefTest extends TestCase { + public AbstractComponentPropertyRefTest(String name) { + super( name ); + } + + public static Test suite() { + return new TestSuite( AbstractComponentPropertyRefTest.class ); + } + + protected String[] getMappings() { + return new String[] { "abstractembeddedcomponents/propertyref/Mappings.hbm.xml" }; + } + + public void testPropertiesRefCascades() { + Session session = openSession(); + Transaction trans = session.beginTransaction(); + ServerImpl server = new ServerImpl(); + session.save( server ); + AddressImpl address = new AddressImpl(); + server.setAddress( address ); + address.setServer( server ); + session.flush(); + session.createQuery( "from Server s join fetch s.address" ).list(); + trans.commit(); + session.close(); + + assertNotNull( server.getId() ); + assertNotNull( address.getId() ); + + session = openSession(); + trans = session.beginTransaction(); + session.delete( address ); + session.delete( server ); + trans.commit(); + session.close(); + } +} Added: trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/Address.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/Address.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/Address.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -0,0 +1,13 @@ +package org.hibernate.test.abstractembeddedcomponents.propertyref; + +/** + * @author Steve Ebersole + */ +public interface Address { + public Long getId(); + public void setId(Long id); + public String getAddressType(); + public void setAddressType(String addressType); + public Server getServer(); + public void setServer(Server server); +} Added: trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/AddressImpl.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/AddressImpl.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/AddressImpl.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -0,0 +1,36 @@ +package org.hibernate.test.abstractembeddedcomponents.propertyref; + +import org.hibernate.test.abstractembeddedcomponents.propertyref.Address; + +/** + * @author Steve Ebersole + */ +public class AddressImpl implements Address { + private Long id; + private String addressType; + private Server server; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getAddressType() { + return addressType; + } + + public void setAddressType(String addressType) { + this.addressType = addressType; + } + + public Server getServer() { + return server; + } + + public void setServer(Server server) { + this.server = server; + } +} Added: trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/Mappings.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/Mappings.hbm.xml 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/Mappings.hbm.xml 2006-03-15 00:12:47 UTC (rev 9619) @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<!DOCTYPE hibernate-mapping PUBLIC + "-//Hibernate/Hibernate Mapping DTD 3.0//EN" + "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> + +<hibernate-mapping package="org.hibernate.test.abstractembeddedcomponents.propertyref"> + + <class name="Address" table="ADDRESS" proxy="Address"> + <id name="id" type="long" column="ADDRESS_ID"> + <generator class="native"/> + </id> + <discriminator column="ADDRESS_TYPE" type="string" length="30"/> + <properties name="uniqueAddress"> + <property name="addressType" column="ADDRESS_TYPE" type="string" insert="false" update="false" length="30"/> + <many-to-one name="server" column="SERVER_ID" class="Server" not-null="true"/> + </properties> + </class> + + <subclass name="AddressImpl" extends="Address" discriminator-value="2" proxy="Address"> + </subclass> + + <class name="Server" table="SERVER" proxy="Server"> + <id name="id" type="long" column="SERVER_ID"> + <generator class="native"/> + </id> + <discriminator column="SERVER_TYPE" type="string" length="10"/> + <property name="serverType" type="string" column="SERVER_TYPE" length="10" update="false" insert="false"/> + </class> + + <subclass name="ServerImpl" extends="Server" discriminator-value="1" proxy="Server"> + <many-to-one name="address" + class="AddressImpl" + property-ref="uniqueAddress" + cascade="all" + unique="true" + update="false" + insert="false"> + <column name="ADDRESS_TYPE"/> + <column name="SERVER_ID"/> + </many-to-one> + </subclass> + +</hibernate-mapping> Added: trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/Server.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/Server.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/Server.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -0,0 +1,15 @@ +package org.hibernate.test.abstractembeddedcomponents.propertyref; + +import org.hibernate.test.abstractembeddedcomponents.propertyref.Address; + +/** + * @author Steve Ebersole + */ +public interface Server { + public Long getId(); + public void setId(Long id); + public String getServerType(); + public void setServerType(String serverType); + public Address getAddress(); + public void setAddress(Address address); +} Added: trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/ServerImpl.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/ServerImpl.java 2006-03-14 23:55:14 UTC (rev 9618) +++ trunk/Hibernate3/test/org/hibernate/test/abstractembeddedcomponents/propertyref/ServerImpl.java 2006-03-15 00:12:47 UTC (rev 9619) @@ -0,0 +1,37 @@ +package org.hibernate.test.abstractembeddedcomponents.propertyref; + +import org.hibernate.test.abstractembeddedcomponents.propertyref.Address; +import org.hibernate.test.abstractembeddedcomponents.propertyref.Server; + +/** + * @author Steve Ebersole + */ +public class ServerImpl implements Server { + private Long id; + private String serverType; + private Address address; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getServerType() { + return serverType; + } + + public void setServerType(String serverType) { + this.serverType = serverType; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } +} |