You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(22) |
Nov
(308) |
Dec
(131) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(369) |
Feb
(171) |
Mar
(236) |
Apr
(187) |
May
(218) |
Jun
(217) |
Jul
(127) |
Aug
(448) |
Sep
(270) |
Oct
(231) |
Nov
(422) |
Dec
(255) |
2004 |
Jan
(111) |
Feb
(73) |
Mar
(338) |
Apr
(351) |
May
(349) |
Jun
(495) |
Jul
(394) |
Aug
(1048) |
Sep
(499) |
Oct
(142) |
Nov
(269) |
Dec
(638) |
2005 |
Jan
(825) |
Feb
(1272) |
Mar
(593) |
Apr
(690) |
May
(950) |
Jun
(958) |
Jul
(767) |
Aug
(839) |
Sep
(525) |
Oct
(449) |
Nov
(585) |
Dec
(455) |
2006 |
Jan
(603) |
Feb
(656) |
Mar
(195) |
Apr
(114) |
May
(136) |
Jun
(100) |
Jul
(128) |
Aug
(68) |
Sep
(7) |
Oct
(1) |
Nov
(1) |
Dec
(8) |
2007 |
Jan
(4) |
Feb
(3) |
Mar
(8) |
Apr
(16) |
May
(5) |
Jun
(4) |
Jul
(6) |
Aug
(23) |
Sep
(15) |
Oct
(5) |
Nov
(7) |
Dec
(5) |
2008 |
Jan
(5) |
Feb
(1) |
Mar
(1) |
Apr
(5) |
May
(1) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2012 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
(1) |
Jul
(1) |
Aug
(1) |
Sep
|
Oct
(2) |
Nov
(3) |
Dec
(2) |
2013 |
Jan
(1) |
Feb
|
Mar
(2) |
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(2) |
Jun
(1) |
Jul
|
Aug
(1) |
Sep
(1) |
Oct
|
Nov
(1) |
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2017 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <hib...@li...> - 2006-05-02 23:33:27
|
Author: epbernard Date: 2006-05-02 19:33:15 -0400 (Tue, 02 May 2006) New Revision: 9859 Added: trunk/HibernateExt/ejb/src/test-resources/excludehbmpar/orm2.xml Removed: trunk/HibernateExt/ejb/src/test-resources/explicitpar/orm2.xml Modified: trunk/HibernateExt/ejb/lib/ejb3-persistence.jar trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java trunk/HibernateExt/ejb/src/test-resources/excludehbmpar/META-INF/persistence.xml trunk/HibernateExt/ejb/src/test-resources/explicitpar/META-INF/persistence.xml trunk/HibernateExt/ejb/src/test/log4j.properties trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/PackagedEntityManagerTest.java trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/QueryTest.java trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/Wallet.java trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/xml/orm2.xml Log: EJB-169 META-INF was mandatory EJB-170 locate files by jar parsing before resource location start a cleaner error handling with PU name Modified: trunk/HibernateExt/ejb/lib/ejb3-persistence.jar =================================================================== (Binary files differ) Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java =================================================================== --- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java 2006-05-02 22:29:55 UTC (rev 9858) +++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java 2006-05-02 23:33:15 UTC (rev 9859) @@ -105,16 +105,16 @@ private EntityManagerFactory createFactory(PersistenceMetadata metadata, Map overrides) { log.debug( "Creating Factory: " + metadata.getName() ); + Map workingVars = new HashMap(); + workingVars.put( HibernatePersistence.PERSISTENCE_UNIT_NAME, metadata.getName() ); + if ( StringHelper.isNotEmpty( metadata.getJtaDatasource() ) ) { this.setProperty( Environment.DATASOURCE, metadata.getJtaDatasource() ); } else if ( StringHelper.isNotEmpty( metadata.getNonJtaDatasource() ) ) { this.setProperty( Environment.DATASOURCE, metadata.getNonJtaDatasource() ); } - - Map workingVars = new HashMap(); - //workingVars.put( HibernatePersistence.TRANSACTION_TYPE, metadata.getTransactionType() ); - defineTransactionType( metadata.getTransactionType(), metadata.getName() ); + defineTransactionType( metadata.getTransactionType(), workingVars ); if ( metadata.getClasses().size() > 0 ) { workingVars.put( HibernatePersistence.CLASS_NAMES, metadata.getClasses() ); } @@ -130,7 +130,6 @@ Properties props = new Properties(); props.putAll( metadata.getProps() ); if ( overrides != null ) props.putAll( overrides ); //yuk! - workingVars.put( HibernatePersistence.PERSISTENCE_UNIT_NAME, metadata.getName() ); return createEntityManagerFactory( props, workingVars ); } @@ -161,7 +160,7 @@ cfg.getEntityResolver() ); for ( PersistenceMetadata metadata : metadataFiles ) { - JarVisitor.Filter[] filters = getFilters( metadata.getProps(), integration ); + JarVisitor.Filter[] filters = getFilters( metadata.getProps(), integration, metadata.getMappingFiles() ); if ( metadata.getProvider() == null || IMPLEMENTATION_NAME.equalsIgnoreCase( metadata.getProvider() @@ -193,7 +192,12 @@ return null; } catch (Exception e) { - throw new PersistenceException( e ); + if ( e instanceof PersistenceException) { + throw (PersistenceException) e; + } + else { + throw new PersistenceException( e ); + } } } @@ -216,6 +220,7 @@ } else if ( filters[index] instanceof JarVisitor.FileFilter ) { hbmFiles.add( entry.getInputStream() ); + metadata.getMappingFiles().remove( entry.getName() ); } } } @@ -240,7 +245,9 @@ return null; } if ( info.getClassLoader() == null ) { - throw new IllegalStateException( "PersistenceUnitInfo.getClassLoader() id null" ); + throw new IllegalStateException( + "[PersistenceUnit: " + info.getPersistenceUnitName() == null ? "" : info.getPersistenceUnitName() + + "] " + "PersistenceUnitInfo.getClassLoader() id null" ); } //set the classloader Thread thread = Thread.currentThread(); @@ -265,7 +272,7 @@ // defineTransactionType( overridenTxType, info.getPersistenceUnitName() ); // } // else { - defineTransactionType( info.getTransactionType(), info.getPersistenceUnitName() ); + defineTransactionType( info.getTransactionType(), workingVars ); // } //workingVars.put( HibernatePersistence.TRANSACTION_TYPE, transactionType ); boolean[] detectArtifact = getDetectedArtifacts( info.getProperties(), null ); @@ -326,7 +333,7 @@ return entityManagerFactory; } - private void defineTransactionType(Object overridenTxType, String persistenceUnitName) { + private void defineTransactionType(Object overridenTxType, Map workingVars) { if ( overridenTxType == null ) { if ( transactionType == null ) { transactionType = PersistenceUnitTransactionType.JTA; //this is the default value @@ -339,9 +346,8 @@ transactionType = (PersistenceUnitTransactionType) overridenTxType; } else { - throw new PersistenceException( + throw new PersistenceException( getExceptionHeader( workingVars ) + HibernatePersistence.TRANSACTION_TYPE + " of the wrong class type" - + ( persistenceUnitName != null ? " in unit " + persistenceUnitName : "" ) + ": " + overridenTxType.getClass() ); } @@ -373,7 +379,7 @@ return result; } - private JarVisitor.Filter[] getFilters(Properties properties, Map overridenProperties) { + private JarVisitor.Filter[] getFilters(Properties properties, Map overridenProperties, final List<String> mappingFiles) { boolean[] result = getDetectedArtifacts( properties, overridenProperties ); int size = ( result[0] ? 2 : 0 ) + 1; //( result[1] ? 1 : 0 ); JarVisitor.Filter[] filters = new JarVisitor.Filter[size]; @@ -397,14 +403,19 @@ if ( result[1] ) { filters[size - 1] = new JarVisitor.FileFilter( true ) { public boolean accept(String javaElementName) { - return javaElementName.endsWith( "hbm.xml" ) || javaElementName.endsWith( META_INF_ORM_XML ); + log.fatal( javaElementName + "O-:-O" + mappingFiles.contains( javaElementName ) ); + return javaElementName.endsWith( "hbm.xml" ) + || javaElementName.endsWith( META_INF_ORM_XML ) + || mappingFiles.contains( javaElementName ); } }; } else { filters[size - 1] = new JarVisitor.FileFilter( true ) { public boolean accept(String javaElementName) { - return javaElementName.endsWith( META_INF_ORM_XML ); + log.fatal( javaElementName + "O:O" + mappingFiles.contains( javaElementName ) ); + return javaElementName.endsWith( META_INF_ORM_XML ) + || mappingFiles.contains( javaElementName ); } }; } @@ -559,10 +570,10 @@ if ( uncastObject != null && uncastObject instanceof String ) { String propertyKey = (String) uncastObject; if ( propertyKey.startsWith( HibernatePersistence.CLASS_CACHE_PREFIX ) ) { - setCacheStrategy( propertyKey, preparedProperties, true ); + setCacheStrategy( propertyKey, preparedProperties, true, workingVars ); } else if ( propertyKey.startsWith( HibernatePersistence.COLLECTION_CACHE_PREFIX ) ) { - setCacheStrategy( propertyKey, preparedProperties, false ); + setCacheStrategy( propertyKey, preparedProperties, false, workingVars ); } else if ( propertyKey.startsWith( HibernatePersistence.JACC_PREFIX ) && ! ( propertyKey.equals( HibernatePersistence.JACC_CONTEXT_ID ) @@ -581,21 +592,23 @@ cfg.setInterceptor( (Interceptor) interceptor.newInstance() ); } catch (ClassNotFoundException e) { - throw new PersistenceException( "Unable to find interceptor class: " + interceptorName, e ); + throw new PersistenceException( + getExceptionHeader(workingVars) + "Unable to find interceptor class: " + interceptorName, e + ); } catch (IllegalAccessException e) { throw new PersistenceException( - "Unable to access interceptor class: " + interceptorName, e + getExceptionHeader(workingVars) + "Unable to access interceptor class: " + interceptorName, e ); } catch (InstantiationException e) { throw new PersistenceException( - "Unable to instanciate interceptor class: " + interceptorName, e + getExceptionHeader(workingVars) + "Unable to instanciate interceptor class: " + interceptorName, e ); } catch (ClassCastException e) { throw new PersistenceException( - "Interceptor class does not implement Interceptor interface: " + interceptorName, e + getExceptionHeader(workingVars) + "Interceptor class does not implement Interceptor interface: " + interceptorName, e ); } } @@ -610,29 +623,29 @@ } catch (ClassNotFoundException e) { throw new PersistenceException( - "Unable to find naming strategy class: " + namingStrategyName, e + getExceptionHeader(workingVars) + "Unable to find naming strategy class: " + namingStrategyName, e ); } catch (IllegalAccessException e) { throw new PersistenceException( - "Unable to access naming strategy class: " + namingStrategyName, e + getExceptionHeader(workingVars) + "Unable to access naming strategy class: " + namingStrategyName, e ); } catch (InstantiationException e) { throw new PersistenceException( - "Unable to instanciate naming strategy class: " + namingStrategyName, e + getExceptionHeader(workingVars) + "Unable to instanciate naming strategy class: " + namingStrategyName, e ); } catch (ClassCastException e) { throw new PersistenceException( - "Naming strategyy class does not implement NmaingStrategy interface: " + namingStrategyName, + getExceptionHeader(workingVars) + "Naming strategyy class does not implement NmaingStrategy interface: " + namingStrategyName, e ); } } if ( jaccKeys.size() > 0 ) { - addSecurity( jaccKeys, preparedProperties ); + addSecurity( jaccKeys, preparedProperties, workingVars ); } //initialize listeners @@ -655,7 +668,7 @@ Collection<String> classNames = (Collection<String>) workingVars.get( HibernatePersistence.CLASS_NAMES ); - addNamedAnnotatedClasses( this, classNames ); + addNamedAnnotatedClasses( this, classNames, workingVars ); } if ( workingVars.containsKey( HibernatePersistence.LOADED_CLASSES ) ) { Collection<Class> classes = (Collection<Class>) workingVars.get( HibernatePersistence.LOADED_CLASSES ); @@ -676,7 +689,29 @@ HibernatePersistence.XML_FILE_NAMES ); for ( String xmlFile : xmlFiles ) { - cfg.addResource( xmlFile ); + Boolean useMetaInf = null; + try { + if ( xmlFile.endsWith( META_INF_ORM_XML ) ) useMetaInf = true; + cfg.addResource( xmlFile ); + } + catch( MappingException me ) { + if ( ! xmlFile.endsWith( META_INF_ORM_XML ) ) { + throw new PersistenceException( getExceptionHeader(workingVars) + + "Unable to find XML mapping file in classpath: " + xmlFile); + } + else { + useMetaInf = false; + //swallow it, the META-INF/orm.xml is optional + } + } + if ( log.isInfoEnabled() ) { + if ( Boolean.TRUE.equals( useMetaInf ) ) { + log.info( getExceptionHeader( workingVars ) + META_INF_ORM_XML + " found"); + } + else if (Boolean.FALSE.equals( useMetaInf ) ) { + log.info( getExceptionHeader( workingVars ) + "no " + META_INF_ORM_XML + " found"); + } + } } } if ( workingVars.containsKey( HibernatePersistence.HBXML_FILES ) ) { @@ -689,6 +724,18 @@ } } + private String getExceptionHeader(Map workingVars) { + if ( workingVars != null ) { + String puName = (String) workingVars.get( HibernatePersistence.PERSISTENCE_UNIT_NAME); + puName = puName == null ? "" : puName; + String header = "[PersistenceUnit: " + puName + "] "; + return header; + } + else { + return ""; + } + } + private Properties prepareProperties(Properties properties, Map workingVars) { Properties preparedProperties = new Properties(); @@ -704,7 +751,7 @@ if ( properties != null ) preparedProperties.putAll( properties ); defineTransactionType( preparedProperties.getProperty( HibernatePersistence.TRANSACTION_TYPE ), - (String) workingVars.get( HibernatePersistence.PERSISTENCE_UNIT_NAME ) + workingVars ); boolean hasTxStrategy = StringHelper.isNotEmpty( preparedProperties.getProperty( Environment.TRANSACTION_STRATEGY ) @@ -729,13 +776,11 @@ return preparedProperties; } - private Class classForName( - String className - ) throws ClassNotFoundException { + private Class classForName(String className) throws ClassNotFoundException { return ReflectHelper.classForName( className, this.getClass() ); } - private void setCacheStrategy(String propertyKey, Map properties, boolean isClass) { + private void setCacheStrategy(String propertyKey, Map properties, boolean isClass, Map workingVars) { String role = propertyKey.substring( ( isClass ? HibernatePersistence.CLASS_CACHE_PREFIX .length() : HibernatePersistence.COLLECTION_CACHE_PREFIX.length() ) @@ -750,7 +795,7 @@ isClass ? HibernatePersistence.CLASS_CACHE_PREFIX : HibernatePersistence.COLLECTION_CACHE_PREFIX ); error.append( ": " ).append( propertyKey ).append( " " ).append( value ); - throw new MappingException( error.toString() ); + throw new PersistenceException( getExceptionHeader(workingVars) + error.toString() ); } String usage = params.nextToken(); String region = null; @@ -769,10 +814,10 @@ } } - private void addSecurity(List<String> keys, Map properties) { + private void addSecurity(List<String> keys, Map properties, Map workingVars) { log.debug( "Adding security" ); if ( !properties.containsKey( HibernatePersistence.JACC_CONTEXT_ID ) ) { - throw new MappingException( + throw new PersistenceException( getExceptionHeader(workingVars) + "Entities have been configured for JACC, but " + HibernatePersistence.JACC_CONTEXT_ID + " has not been set" @@ -793,13 +838,14 @@ jaccCfg.addPermission( role, clazz, actions ); } catch (IndexOutOfBoundsException e) { - throw new MappingException( "Illegal usage of " + HibernatePersistence.JACC_PREFIX + ": " + key ); + throw new PersistenceException( getExceptionHeader(workingVars) + + "Illegal usage of " + HibernatePersistence.JACC_PREFIX + ": " + key ); } } } private void addNamedAnnotatedClasses( - Ejb3Configuration cfg, Collection<String> classNames + Ejb3Configuration cfg, Collection<String> classNames, Map workingVars ) { for ( String name : classNames ) { try { @@ -815,7 +861,7 @@ pkg = null; } if ( pkg == null ) { - throw new IllegalArgumentException( "class or package not found", cnfe ); + throw new PersistenceException( getExceptionHeader(workingVars) + "class or package not found", cnfe ); } else { cfg.addPackage( name ); Modified: trunk/HibernateExt/ejb/src/test/log4j.properties =================================================================== --- trunk/HibernateExt/ejb/src/test/log4j.properties 2006-05-02 22:29:55 UTC (rev 9858) +++ trunk/HibernateExt/ejb/src/test/log4j.properties 2006-05-02 23:33:15 UTC (rev 9859) @@ -18,6 +18,7 @@ #log4j.logger.org.hibernate=debug log4j.logger.org.hibernate.ejb=debug +log4j.logger.org.hibernate.reflection=debug #log4j.logger.org.hibernate.engine.Cascades=debug #log4j.logger.org.hibernate.hql=debug @@ -26,8 +27,8 @@ log4j.logger.org.hibernate.SQL=debug ### log JDBC bind parameters ### -log4j.logger.org.hibernate.type=info -#log4j.logger.org.hibernate.type=debug +#log4j.logger.org.hibernate.type=info +log4j.logger.org.hibernate.type=debug ### log schema export/update ### log4j.logger.org.hibernate.tool.hbm2ddl=debug Modified: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/PackagedEntityManagerTest.java =================================================================== --- trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/PackagedEntityManagerTest.java 2006-05-02 22:29:55 UTC (rev 9858) +++ trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/PackagedEntityManagerTest.java 2006-05-02 23:33:15 UTC (rev 9859) @@ -95,7 +95,7 @@ nested = nested.getCause(); if ( nested == null ) throw e; if ( ! ( nested instanceof ClassNotFoundException ) ) throw e; - fail( "Try to process hbm file" ); + fail( "Try to process hbm file: " + e.getMessage() ); } EntityManager em = emf.createEntityManager(); Caipirinha s = new Caipirinha( "Strong" ); Modified: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/QueryTest.java =================================================================== --- trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/QueryTest.java 2006-05-02 22:29:55 UTC (rev 9858) +++ trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/QueryTest.java 2006-05-02 23:33:15 UTC (rev 9859) @@ -3,8 +3,10 @@ import java.util.ArrayList; import java.util.List; +import java.util.Date; import javax.persistence.EntityManager; import javax.persistence.Query; +import javax.persistence.TemporalType; import org.hibernate.Hibernate; @@ -182,6 +184,10 @@ query.setParameter( 1, "Lacoste" ); w = (Wallet) query.getSingleResult(); assertNotNull( w ); + query = em.createQuery( "select w from " + Wallet.class.getName() + " w where w.marketEntrance = ?1" ); + query.setParameter( 1, new Date(), TemporalType.DATE ); + //assertNull( query.getSingleResult() ); + assertEquals( 0, query.getResultList().size() ); em.remove( w ); em.getTransaction().commit(); em.close(); Modified: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/Wallet.java =================================================================== --- trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/Wallet.java 2006-05-02 22:29:55 UTC (rev 9858) +++ trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/Wallet.java 2006-05-02 23:33:15 UTC (rev 9859) @@ -2,6 +2,7 @@ package org.hibernate.ejb.test; import java.io.Serializable; +import java.util.Date; import javax.persistence.Entity; import javax.persistence.Id; @@ -12,6 +13,7 @@ public class Wallet implements Serializable { private String serial; private String model; + private Date marketEntrance; private String brand; @Id @@ -38,4 +40,12 @@ public void setBrand(String brand) { this.brand = brand; } + + public Date getMarketEntrance() { + return marketEntrance; + } + + public void setMarketEntrance(Date marketEntrance) { + this.marketEntrance = marketEntrance; + } } Modified: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/xml/orm2.xml =================================================================== --- trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/xml/orm2.xml 2006-05-02 22:29:55 UTC (rev 9858) +++ trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/xml/orm2.xml 2006-05-02 23:33:15 UTC (rev 9859) @@ -5,8 +5,8 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd" version="1.0" > - <package>org.hibernate.ejb.test.pack.defaultpar</package> - <entity class="Lighter" access="FIELD" metadata-complete="true"> + <package>org.hibernate.ejb.test.xml</package> + <entity class="Lighter" name="ALighter" access="FIELD" metadata-complete="true"> <attributes> <id name="name"> <column name="fld_id"/> Modified: trunk/HibernateExt/ejb/src/test-resources/excludehbmpar/META-INF/persistence.xml =================================================================== --- trunk/HibernateExt/ejb/src/test-resources/excludehbmpar/META-INF/persistence.xml 2006-05-02 22:29:55 UTC (rev 9858) +++ trunk/HibernateExt/ejb/src/test-resources/excludehbmpar/META-INF/persistence.xml 2006-05-02 23:33:15 UTC (rev 9859) @@ -5,6 +5,7 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="excludehbmpar" transaction-type="RESOURCE_LOCAL"> + <mapping-file>orm2.xml</mapping-file> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/> Copied: trunk/HibernateExt/ejb/src/test-resources/excludehbmpar/orm2.xml (from rev 9841, trunk/HibernateExt/ejb/src/test-resources/explicitpar/orm2.xml) =================================================================== --- trunk/HibernateExt/ejb/src/test-resources/explicitpar/orm2.xml 2006-05-01 03:56:56 UTC (rev 9841) +++ trunk/HibernateExt/ejb/src/test-resources/excludehbmpar/orm2.xml 2006-05-02 23:33:15 UTC (rev 9859) @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd" + version="1.0" + > + <package>org.hibernate.ejb.test.xml</package> + <entity class="Light" access="FIELD" metadata-complete="true"> + <attributes> + <id name="name"> + <column name="fld_id"/> + </id> + <basic name="power"></basic> + </attributes> + </entity> +</entity-mappings> \ No newline at end of file Modified: trunk/HibernateExt/ejb/src/test-resources/explicitpar/META-INF/persistence.xml =================================================================== --- trunk/HibernateExt/ejb/src/test-resources/explicitpar/META-INF/persistence.xml 2006-05-02 22:29:55 UTC (rev 9858) +++ trunk/HibernateExt/ejb/src/test-resources/explicitpar/META-INF/persistence.xml 2006-05-02 23:33:15 UTC (rev 9859) @@ -4,13 +4,11 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="manager1" transaction-type="RESOURCE_LOCAL"> - <mapping-file>orm2.xml</mapping-file> <jar-file>./build/testresources/externaljar.jar</jar-file> <class>org.hibernate.ejb.test.Cat</class> <class>org.hibernate.ejb.test.Distributor</class> <class>org.hibernate.ejb.test.Item</class> <class>org.hibernate.ejb.test</class> - <class>org.hibernate.ejb.test.xml.Light</class> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/> Deleted: trunk/HibernateExt/ejb/src/test-resources/explicitpar/orm2.xml =================================================================== --- trunk/HibernateExt/ejb/src/test-resources/explicitpar/orm2.xml 2006-05-02 22:29:55 UTC (rev 9858) +++ trunk/HibernateExt/ejb/src/test-resources/explicitpar/orm2.xml 2006-05-02 23:33:15 UTC (rev 9859) @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd" - version="1.0" - > - <package>org.hibernate.test.annotations.xml.ejb3</package> - <entity class="Light" access="FIELD" metadata-complete="true"> - <attributes> - <id name="name"> - <column name="fld_id"/> - </id> - <basic name="power"></basic> - </attributes> - </entity> -</entity-mappings> \ No newline at end of file |
From: <hib...@li...> - 2006-05-02 22:30:00
|
Author: epbernard Date: 2006-05-02 18:29:55 -0400 (Tue, 02 May 2006) New Revision: 9858 Modified: trunk/HibernateExt/metadata/build.xml trunk/HibernateExt/metadata/lib/ejb3-persistence.jar trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/Flight.java Log: ANN-338 Modified: trunk/HibernateExt/metadata/build.xml =================================================================== --- trunk/HibernateExt/metadata/build.xml 2006-05-02 22:26:29 UTC (rev 9857) +++ trunk/HibernateExt/metadata/build.xml 2006-05-02 22:29:55 UTC (rev 9858) @@ -16,7 +16,7 @@ <!-- Name of project and version, used to create filenames --> <property name="Name" value="Hibernate Annotations"/> <property name="name" value="hibernate-annotations"/> - <property name="version" value="3.1.0.Beta10"/> + <property name="version" value="3.1.0.CR1"/> <property name="javadoc.packagenames" value="org.hibernate.*"/> <property name="jdbc.dir" value="jdbc"/> <property name="copy.test" value="true"/> Modified: trunk/HibernateExt/metadata/lib/ejb3-persistence.jar =================================================================== (Binary files differ) Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/Flight.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/Flight.java 2006-05-02 22:26:29 UTC (rev 9857) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/Flight.java 2006-05-02 22:29:55 UTC (rev 9858) @@ -129,7 +129,7 @@ this.factor = factor; } - @Temporal + @Temporal(TemporalType.TIMESTAMP) public Calendar getAlternativeDepartureDate() { return alternativeDepartureDate; } |
From: <hib...@li...> - 2006-05-02 22:26:36
|
Author: epbernard Date: 2006-05-02 18:26:29 -0400 (Tue, 02 May 2006) New Revision: 9857 Modified: trunk/HibernateExt/ejb-api/src/javax/persistence/Temporal.java Log: ANN-338 Modified: trunk/HibernateExt/ejb-api/src/javax/persistence/Temporal.java =================================================================== --- trunk/HibernateExt/ejb-api/src/javax/persistence/Temporal.java 2006-05-02 21:46:17 UTC (rev 9856) +++ trunk/HibernateExt/ejb-api/src/javax/persistence/Temporal.java 2006-05-02 22:26:29 UTC (rev 9857) @@ -7,7 +7,6 @@ import java.lang.annotation.Retention; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Target; -import static javax.persistence.TemporalType.*; /** * @author Emmanuel Bernard @@ -15,5 +14,5 @@ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Temporal { - TemporalType value() default TIMESTAMP; + TemporalType value(); } |
From: <hib...@li...> - 2006-05-02 21:46:24
|
Author: epbernard Date: 2006-05-02 17:46:17 -0400 (Tue, 02 May 2006) New Revision: 9856 Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ExtendedMappings.java trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/QueryBinder.java trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/ReflectionManager.java trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/EJB3OverridenAnnotationReader.java trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXFactory.java trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/xml/XMLContext.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/Ejb3XmlTest.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/Manufacturer.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/orm.xml Log: ANN-323 xml defaults overriding has precedence over annotations Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-05-02 18:55:45 UTC (rev 9855) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-05-02 21:46:17 UTC (rev 9856) @@ -156,6 +156,52 @@ private static final Log log = LogFactory.getLog( AnnotationBinder.class ); + public static void bindDefaults(ExtendedMappings mappings) { + Map defaults = mappings.getReflectionManager().getDefaults(); + { + List<SequenceGenerator> anns = (List<SequenceGenerator>) defaults.get( SequenceGenerator.class ); + if (anns != null) { + for ( SequenceGenerator ann : anns ) { + IdGenerator idGen = buildIdGenerator(ann, mappings); + if (idGen != null) mappings.addDefaultGenerator( idGen ); + } + } + } + { + List<TableGenerator> anns = (List<TableGenerator>) defaults.get( TableGenerator.class ); + if (anns != null) { + for ( TableGenerator ann : anns ) { + IdGenerator idGen = buildIdGenerator(ann, mappings); + if (idGen != null) mappings.addDefaultGenerator( idGen ); + } + } + } + { + List<NamedQuery> anns = (List<NamedQuery>) defaults.get( NamedQuery.class ); + if (anns != null) { + for (NamedQuery ann : anns) { + QueryBinder.bindQuery(ann, mappings, true ); + } + } + } + { + List<NamedNativeQuery> anns = (List<NamedNativeQuery>) defaults.get( NamedNativeQuery.class ); + if (anns != null) { + for (NamedNativeQuery ann : anns) { + QueryBinder.bindNativeQuery(ann, mappings, true ); + } + } + } + { + List<SqlResultSetMapping> anns = (List<SqlResultSetMapping>) defaults.get( SqlResultSetMapping.class ); + if (anns != null) { + for (SqlResultSetMapping ann : anns) { + QueryBinder.bindSqlResultsetMapping(ann, mappings, true ); + } + } + } + } + public static void bindPackage(String packageName, ExtendedMappings mappings) { XPackage pckg = null; try { @@ -190,19 +236,19 @@ private static void bindQueries(XAnnotatedElement annotatedElement, ExtendedMappings mappings) { { SqlResultSetMapping ann = annotatedElement.getAnnotation( SqlResultSetMapping.class ); - QueryBinder.bindSqlResultsetMapping( ann, mappings ); + QueryBinder.bindSqlResultsetMapping( ann, mappings, false ); } { SqlResultSetMappings ann = annotatedElement.getAnnotation( SqlResultSetMappings.class ); if ( ann != null ) { for ( SqlResultSetMapping current : ann.value() ) { - QueryBinder.bindSqlResultsetMapping( current, mappings ); + QueryBinder.bindSqlResultsetMapping( current, mappings, false ); } } } { NamedQuery ann = annotatedElement.getAnnotation( NamedQuery.class ); - QueryBinder.bindQuery( ann, mappings ); + QueryBinder.bindQuery( ann, mappings, false ); } { org.hibernate.annotations.NamedQuery ann = annotatedElement.getAnnotation( @@ -212,7 +258,7 @@ } { NamedQueries ann = annotatedElement.getAnnotation( NamedQueries.class ); - QueryBinder.bindQueries( ann, mappings ); + QueryBinder.bindQueries( ann, mappings, false ); } { org.hibernate.annotations.NamedQueries ann = annotatedElement.getAnnotation( @@ -222,7 +268,7 @@ } { NamedNativeQuery ann = annotatedElement.getAnnotation( NamedNativeQuery.class ); - QueryBinder.bindNativeQuery( ann, mappings ); + QueryBinder.bindNativeQuery( ann, mappings, false ); } { org.hibernate.annotations.NamedNativeQuery ann = annotatedElement.getAnnotation( @@ -232,7 +278,7 @@ } { NamedNativeQueries ann = annotatedElement.getAnnotation( NamedNativeQueries.class ); - QueryBinder.bindNativeQueries( ann, mappings ); + QueryBinder.bindNativeQueries( ann, mappings, false ); } { org.hibernate.annotations.NamedNativeQueries ann = annotatedElement.getAnnotation( Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java 2006-05-02 18:55:45 UTC (rev 9855) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java 2006-05-02 21:46:17 UTC (rev 9856) @@ -63,6 +63,10 @@ private Map namedGenerators; private Map<String, Map<String, Join>> joins; private Map<String, AnnotatedClassType> classTypes; + private Set<String> defaultNamedQueryNames; + private Set<String> defaultNamedNativeQueryNames; + private Set<String> defaultSqlResulSetMappingNames; + private Set<String> defaultNamedGenerators; private Map<String, Properties> generatorTables; private Map<Table, List<String[]>> tableUniqueConstraints; private Map<String, String> mappedByResolver; @@ -76,6 +80,7 @@ private boolean inSecondPass = false; protected XMLHelper xmlHelper; private ReflectionManager reflectionManager; + private boolean isDefaultProcessed = false; public AnnotationConfiguration() { super(); @@ -164,6 +169,10 @@ namedQueries, namedSqlQueries, sqlResultSetMappings, + defaultNamedQueryNames, + defaultNamedNativeQueryNames, + defaultSqlResulSetMappingNames, + defaultNamedGenerators, imports, secondPasses, propertyReferences, @@ -203,6 +212,10 @@ joins = new HashMap<String, Map<String, Join>>(); classTypes = new HashMap<String, AnnotatedClassType>(); generatorTables = new HashMap<String, Properties>(); + defaultNamedQueryNames = new HashSet<String>(); + defaultNamedNativeQueryNames = new HashSet<String>(); + defaultSqlResulSetMappingNames = new HashSet<String>(); + defaultNamedGenerators = new HashSet<String>(); tableUniqueConstraints = new HashMap<Table, List<String[]>>(); mappedByResolver = new HashMap<String, String>(); propertyRefResolver = new HashMap<String, String>(); @@ -235,6 +248,14 @@ } annotatedClasses = tempAnnotatedClasses; } + + //process default values first + if ( ! isDefaultProcessed ) { + AnnotationBinder.bindDefaults( createExtendedMappings() ); + isDefaultProcessed = true; + } + + //process entities if ( precedence == null ) precedence = getProperties().getProperty( ARTEFACT ); if ( precedence == null ) precedence = DEFAULT_PRECEDENCE; StringTokenizer precedences = new StringTokenizer( precedence, ",; ", false ); Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ExtendedMappings.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ExtendedMappings.java 2006-05-02 18:55:45 UTC (rev 9855) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ExtendedMappings.java 2006-05-02 21:46:17 UTC (rev 9856) @@ -5,6 +5,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; import javax.persistence.Embeddable; import javax.persistence.Entity; import javax.persistence.MappedSuperclass; @@ -12,6 +13,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.MappingException; +import org.hibernate.engine.NamedQueryDefinition; +import org.hibernate.engine.NamedSQLQueryDefinition; +import org.hibernate.engine.ResultSetMappingDefinition; import org.hibernate.mapping.IdGenerator; import org.hibernate.mapping.Join; import org.hibernate.mapping.PersistentClass; @@ -38,10 +42,15 @@ private final Map<String, String> mappedByResolver; private final Map<String, String> propertyRefResolver; private final ReflectionManager reflectionManager; + private final Set<String> defaultNamedQueryNames; + private final Set<String> defaultNamedNativeQueryNames; + private final Set<String> defaultSqlResulSetMappingNames; + private final Set<String> defaultNamedGenerators; ExtendedMappings( Map classes, Map collections, Map tables, Map queries, Map sqlqueries, Map sqlResultSetMappings, - Map imports, + Set<String> defaultNamedQueryNames, Set<String> defaultNamedNativeQueryNames, + Set<String> defaultSqlResulSetMappingNames, Set<String> defaultNamedGenerators, Map imports, List secondPasses, List propertyReferences, NamingStrategy namingStrategy, Map typeDefs, Map filterDefinitions, Map namedGenerators, Map<String, Map<String, Join>> joins, Map<String, AnnotatedClassType> classTypes, Map extendsQueue, Map<String, TableDescription> tableNameBinding, @@ -79,11 +88,17 @@ this.mappedByResolver = mappedByResolver; this.propertyRefResolver = propertyRefResolver; this.reflectionManager = reflectionManager; + this.defaultNamedQueryNames = defaultNamedQueryNames; + this.defaultNamedNativeQueryNames = defaultNamedNativeQueryNames; + this.defaultSqlResulSetMappingNames = defaultSqlResulSetMappingNames; + this.defaultNamedGenerators = defaultNamedGenerators; } public void addGenerator(IdGenerator generator) throws MappingException { - Object old = namedGenerators.put( generator.getName(), generator ); - if ( old != null ) log.warn( "duplicate generator name: " + generator.getName() ); + if ( ! defaultNamedGenerators.contains( generator.getName() ) ) { + Object old = namedGenerators.put( generator.getName(), generator ); + if ( old != null ) log.warn( "duplicate generator name: " + generator.getName() ); + } } public void addJoins(PersistentClass persistentClass, Map<String, Join> joins) throws MappingException { @@ -202,4 +217,45 @@ public ReflectionManager getReflectionManager() { return reflectionManager; } + + public void addDefaultQuery(String name, NamedQueryDefinition query) { + super.addQuery(name, query); + defaultNamedQueryNames.add( name ); + } + + public void addDefaultSQLQuery(String name, NamedSQLQueryDefinition query) { + super.addSQLQuery(name, query); + defaultNamedNativeQueryNames.add( name ); + } + + public void addDefaultGenerator(IdGenerator idGen) { + this.addGenerator(idGen); + defaultNamedGenerators.add( idGen.getName() ); + + } + + public void addDefaultResultSetMapping(ResultSetMappingDefinition definition) { + if ( ! defaultSqlResulSetMappingNames.contains( definition.getName() ) + && super.getResultSetMapping( definition.getName() ) != null ) { + //FIXME overrides without clashing when resultSetMAppings visibility allows it + } + super.addResultSetMapping(definition); + defaultSqlResulSetMappingNames.add( definition.getName() ); + } + + @Override + public void addQuery(String name, NamedQueryDefinition query) throws MappingException { + if ( ! defaultNamedQueryNames.contains( name ) ) super.addQuery( name, query ); + } + + @Override + public void addResultSetMapping(ResultSetMappingDefinition definition) { + if ( ! defaultSqlResulSetMappingNames.contains( definition.getName() ) ) + super.addResultSetMapping( definition ); + } + + @Override + public void addSQLQuery(String name, NamedSQLQueryDefinition query) throws MappingException { + if ( ! defaultNamedNativeQueryNames.contains( name ) ) super.addSQLQuery( name, query ); + } } \ No newline at end of file Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/QueryBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/QueryBinder.java 2006-05-02 18:55:45 UTC (rev 9855) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/QueryBinder.java 2006-05-02 21:46:17 UTC (rev 9856) @@ -8,6 +8,7 @@ import javax.persistence.NamedQuery; import javax.persistence.QueryHint; import javax.persistence.SqlResultSetMapping; +import javax.persistence.SqlResultSetMappings; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -35,7 +36,7 @@ public abstract class QueryBinder { private static Log log = LogFactory.getLog( QueryBinder.class ); - public static void bindQuery(NamedQuery queryAnn, ExtendedMappings mappings) { + public static void bindQuery(NamedQuery queryAnn, ExtendedMappings mappings, boolean isDefault) { if ( queryAnn == null ) return; if ( AnnotationBinder.isDefault( queryAnn.name() ) ) { throw new AnnotationException( "A named query must have a name when used in class or package level" ); @@ -55,12 +56,17 @@ getString( queryName, "org.hibernate.comment", hints ), null ); - mappings.addQuery( queryAnn.name(), query ); + if (isDefault) { + mappings.addDefaultQuery( queryAnn.name(), query ); + } + else { + mappings.addQuery( queryAnn.name(), query ); + } if ( log.isInfoEnabled() ) log.info( "Binding Named query: " + queryAnn.name() + " => " + queryAnn.query() ); } - public static void bindNativeQuery(NamedNativeQuery queryAnn, ExtendedMappings mappings) { + public static void bindNativeQuery(NamedNativeQuery queryAnn, ExtendedMappings mappings, boolean isDefault) { if ( queryAnn == null ) return; //ResultSetMappingDefinition mappingDefinition = mappings.getResultSetMapping( queryAnn.resultSetMapping() ); if ( AnnotationBinder.isDefault( queryAnn.name() ) ) { @@ -113,7 +119,12 @@ else { throw new NotYetImplementedException( "Pure native scalar queries are not yet supported" ); } - mappings.addSQLQuery( queryAnn.name(), query ); + if (isDefault) { + mappings.addDefaultSQLQuery( queryAnn.name(), query ); + } + else { + mappings.addSQLQuery( queryAnn.name(), query ); + } if ( log.isInfoEnabled() ) { log.info( "Binding named native query: " + queryAnn.name() + " => " + queryAnn.query() ); } @@ -176,17 +187,17 @@ } } - public static void bindQueries(NamedQueries queriesAnn, ExtendedMappings mappings) { + public static void bindQueries(NamedQueries queriesAnn, ExtendedMappings mappings, boolean isDefault) { if ( queriesAnn == null ) return; for ( NamedQuery q : queriesAnn.value() ) { - bindQuery( q, mappings ); + bindQuery( q, mappings, isDefault ); } } - public static void bindNativeQueries(NamedNativeQueries queriesAnn, ExtendedMappings mappings) { + public static void bindNativeQueries(NamedNativeQueries queriesAnn, ExtendedMappings mappings, boolean isDefault) { if ( queriesAnn == null ) return; for ( NamedNativeQuery q : queriesAnn.value() ) { - bindNativeQuery( q, mappings ); + bindNativeQuery( q, mappings, isDefault ); } } @@ -271,10 +282,17 @@ } } - public static void bindSqlResultsetMapping(SqlResultSetMapping ann, ExtendedMappings mappings) { - mappings.addSecondPass( new ResultsetMappingSecondPass( ann, mappings ) ); + public static void bindSqlResultsetMappings(SqlResultSetMappings ann, ExtendedMappings mappings, boolean isDefault) { + if ( ann == null ) return; + for ( SqlResultSetMapping rs : ann.value() ) { + mappings.addSecondPass( new ResultsetMappingSecondPass( rs, mappings, true ) ); + } } + public static void bindSqlResultsetMapping(SqlResultSetMapping ann, ExtendedMappings mappings, boolean isDefault) { + mappings.addSecondPass( new ResultsetMappingSecondPass( ann, mappings, isDefault ) ); + } + private static CacheMode getCacheMode(String query, QueryHint[] hints) { for ( QueryHint hint : hints ) { if ( "org.hibernate.cacheMode".equals( hint.name() ) ) { Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java 2006-05-02 18:55:45 UTC (rev 9855) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java 2006-05-02 21:46:17 UTC (rev 9856) @@ -18,7 +18,7 @@ import org.hibernate.LockMode; import org.hibernate.MappingException; import org.hibernate.cfg.AnnotationBinder; -import org.hibernate.cfg.Mappings; +import org.hibernate.cfg.ExtendedMappings; import org.hibernate.cfg.QuerySecondPass; import org.hibernate.engine.ResultSetMappingDefinition; import org.hibernate.loader.custom.SQLQueryRootReturn; @@ -37,11 +37,13 @@ public class ResultsetMappingSecondPass implements QuerySecondPass { private static Log log = LogFactory.getLog( ResultsetMappingSecondPass.class ); private SqlResultSetMapping ann; - private Mappings mappings; + private ExtendedMappings mappings; + private boolean isDefault; - public ResultsetMappingSecondPass(SqlResultSetMapping ann, Mappings mappings) { + public ResultsetMappingSecondPass(SqlResultSetMapping ann, ExtendedMappings mappings, boolean isDefault) { this.ann = ann; this.mappings = mappings; + this.isDefault = isDefault; } public void doSecondPass(Map persistentClasses, Map inheritedMetas) throws MappingException { @@ -150,7 +152,12 @@ definition.addScalarQueryReturn( new SQLQueryScalarReturn( column.name(), null ) ); } - mappings.addResultSetMapping( definition ); + if (isDefault) { + mappings.addDefaultResultSetMapping( definition ); + } + else { + mappings.addResultSetMapping( definition ); + } } private List getFollowers(Iterator parentPropIter, String reducedName, String name) { Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/ReflectionManager.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/ReflectionManager.java 2006-05-02 18:55:45 UTC (rev 9855) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/ReflectionManager.java 2006-05-02 21:46:17 UTC (rev 9856) @@ -1,5 +1,7 @@ package org.hibernate.reflection; +import java.util.Map; + /** * The entry point to the reflection layer (a.k.a. the X* layer). * @@ -20,4 +22,6 @@ public XPackage packageForName(String packageName) throws ClassNotFoundException; public <T> boolean equals(XClass class1, Class<T> class2); + + public Map getDefaults(); } Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/EJB3OverridenAnnotationReader.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/EJB3OverridenAnnotationReader.java 2006-05-02 18:55:45 UTC (rev 9855) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/EJB3OverridenAnnotationReader.java 2006-05-02 21:46:17 UTC (rev 9856) @@ -1132,7 +1132,7 @@ } } - private List<SqlResultSetMapping> buildSqlResultsetMappings(Element element, XMLContext.Default defaults) { + public static List<SqlResultSetMapping> buildSqlResultsetMappings(Element element, XMLContext.Default defaults) { if ( element == null ) return new ArrayList<SqlResultSetMapping>(); List resultsetElementList = element.elements( "sql-result-set-mapping" ); List<SqlResultSetMapping> resultsets = new ArrayList<SqlResultSetMapping>(); @@ -1153,7 +1153,7 @@ try { clazz = ReflectHelper.classForName( XMLContext.buildSafeClassName( clazzName, defaults ), - this.getClass() + EJB3OverridenAnnotationReader.class ); } catch (ClassNotFoundException e) { @@ -1276,7 +1276,7 @@ } } - private List buildNamedQueries(Element element, boolean isNative) { + public static List buildNamedQueries(Element element, boolean isNative) { if ( element == null ) return new ArrayList(); List namedQueryElementList = isNative ? element.elements( "named-native-query" ) : @@ -1316,26 +1316,7 @@ private TableGenerator getTableGenerator(Element tree, XMLContext.Default defaults) { Element element = tree != null ? tree.element( annotationToXml.get( TableGenerator.class ) ) : null; if ( element != null ) { - AnnotationDescriptor ad = new AnnotationDescriptor( TableGenerator.class ); - copyStringAttribute( ad, element, "name", false ); - copyStringAttribute( ad, element, "table", false ); - copyStringAttribute( ad, element, "catalog", false ); - copyStringAttribute( ad, element, "schema", false ); - copyStringAttribute( ad, element, "pk-column-name", false ); - copyStringAttribute( ad, element, "value-column-name", false ); - copyStringAttribute( ad, element, "pk-column-value", false ); - copyIntegerAttribute( ad, element, "initial-value" ); - copyIntegerAttribute( ad, element, "allocation-size" ); - buildUniqueConstraints( ad, element ); - if ( StringHelper.isEmpty( (String) ad.valueOf( "schema" ) ) - && StringHelper.isNotEmpty( defaults.getSchema() ) ) { - ad.setValue( "schema", defaults.getSchema() ); - } - if ( StringHelper.isEmpty( (String) ad.valueOf( "catalog" ) ) - && StringHelper.isNotEmpty( defaults.getCatalog() ) ) { - ad.setValue( "catalog", defaults.getCatalog() ); - } - return AnnotationFactory.create( ad ); + return buildTableGeneratorAnnotation( element, defaults ); } else if ( defaults.canUseJavaAnnotations() && super.isAnnotationPresent( TableGenerator.class ) ) { TableGenerator tableAnn = super.getAnnotation( TableGenerator.class ); @@ -1371,9 +1352,44 @@ } } + public static TableGenerator buildTableGeneratorAnnotation(Element element, XMLContext.Default defaults) { + AnnotationDescriptor ad = new AnnotationDescriptor( TableGenerator.class ); + copyStringAttribute( ad, element, "name", false ); + copyStringAttribute( ad, element, "table", false ); + copyStringAttribute( ad, element, "catalog", false ); + copyStringAttribute( ad, element, "schema", false ); + copyStringAttribute( ad, element, "pk-column-name", false ); + copyStringAttribute( ad, element, "value-column-name", false ); + copyStringAttribute( ad, element, "pk-column-value", false ); + copyIntegerAttribute( ad, element, "initial-value" ); + copyIntegerAttribute( ad, element, "allocation-size" ); + buildUniqueConstraints( ad, element ); + if ( StringHelper.isEmpty( (String) ad.valueOf( "schema" ) ) + && StringHelper.isNotEmpty( defaults.getSchema() ) ) { + ad.setValue( "schema", defaults.getSchema() ); + } + if ( StringHelper.isEmpty( (String) ad.valueOf( "catalog" ) ) + && StringHelper.isNotEmpty( defaults.getCatalog() ) ) { + ad.setValue( "catalog", defaults.getCatalog() ); + } + return AnnotationFactory.create( ad ); + } + private SequenceGenerator getSequenceGenerator(Element tree, XMLContext.Default defaults) { Element element = tree != null ? tree.element( annotationToXml.get( SequenceGenerator.class ) ) : null; if ( element != null ) { + return buildSequenceGeneratorAnnotation( element ); + } + else if ( defaults.canUseJavaAnnotations() ) { + return super.getAnnotation( SequenceGenerator.class ); + } + else { + return null; + } + } + + public static SequenceGenerator buildSequenceGeneratorAnnotation(Element element) { + if (element != null) { AnnotationDescriptor ad = new AnnotationDescriptor( SequenceGenerator.class ); copyStringAttribute( ad, element, "name", false ); copyStringAttribute( ad, element, "sequence-name", false ); @@ -1381,9 +1397,6 @@ copyIntegerAttribute( ad, element, "allocation-size" ); return AnnotationFactory.create( ad ); } - else if ( defaults.canUseJavaAnnotations() ) { - return super.getAnnotation( SequenceGenerator.class ); - } else { return null; } @@ -1705,7 +1718,7 @@ } } - private void buildUniqueConstraints(AnnotationDescriptor annotation, Element element) { + private static void buildUniqueConstraints(AnnotationDescriptor annotation, Element element) { List uniqueConstraintElementList = element.elements( "unique-constraint" ); UniqueConstraint[] uniqueConstraints = new UniqueConstraint[ uniqueConstraintElementList.size() ]; int ucIndex = 0; @@ -1744,7 +1757,7 @@ return pkJoinColumns; } - private void copyStringAttribute( + private static void copyStringAttribute( AnnotationDescriptor annotation, Element element, String attributeName, boolean mandatory ) { String attribute = element.attributeValue( attributeName ); @@ -1761,7 +1774,7 @@ } } - private void copyIntegerAttribute(AnnotationDescriptor annotation, Element element, String attributeName) { + private static void copyIntegerAttribute(AnnotationDescriptor annotation, Element element, String attributeName) { String attribute = element.attributeValue( attributeName ); if ( attribute != null ) { String annotationAttributeName = getJavaAttributeNameFromXMLOne( attributeName ); @@ -1778,7 +1791,7 @@ } } - private String getJavaAttributeNameFromXMLOne(String attributeName) { + private static String getJavaAttributeNameFromXMLOne(String attributeName) { StringBuilder annotationAttributeName = new StringBuilder( attributeName ); int index = annotationAttributeName.indexOf( WORD_SEPARATOR ); while ( index != -1 ) { @@ -1791,12 +1804,12 @@ return annotationAttributeName.toString(); } - private void copyStringElement(Element element, AnnotationDescriptor ad, String annotationAttribute) { + private static void copyStringElement(Element element, AnnotationDescriptor ad, String annotationAttribute) { String discr = element.getTextTrim(); ad.setValue( annotationAttribute, discr ); } - private void copyBooleanAttribute(AnnotationDescriptor descriptor, Element element, String attribute) { + private static void copyBooleanAttribute(AnnotationDescriptor descriptor, Element element, String attribute) { String attributeValue = element.attributeValue( attribute ); if ( StringHelper.isNotEmpty( attributeValue ) ) { String javaAttribute = getJavaAttributeNameFromXMLOne( attribute ); Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXFactory.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXFactory.java 2006-05-02 18:55:45 UTC (rev 9855) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXFactory.java 2006-05-02 21:46:17 UTC (rev 9856) @@ -3,11 +3,19 @@ import java.lang.reflect.Member; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import javax.persistence.NamedNativeQuery; +import javax.persistence.NamedQuery; +import javax.persistence.SequenceGenerator; +import javax.persistence.SqlResultSetMapping; +import javax.persistence.TableGenerator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.dom4j.Element; import org.hibernate.reflection.ReflectionManager; import org.hibernate.reflection.XClass; import org.hibernate.reflection.XMethod; @@ -32,6 +40,7 @@ private static Log log = LogFactory.getLog( JavaXFactory.class ); private XMLContext xmlContext; + private HashMap defaults; private static class TypeKey extends Pair<Type, TypeEnvironment> { TypeKey(Type t, TypeEnvironment context) { @@ -65,7 +74,7 @@ packagesToXPackages.clear(); xProperties.clear(); xMethods.clear(); - + defaults = null; } public XClass toXClass(Class clazz) { @@ -87,6 +96,59 @@ return getXAnnotatedElement( ReflectHelper.classForName( packageName + ".package-info" ).getPackage() ); } + public Map getDefaults() { + if (defaults == null) { + defaults = new HashMap(); + XMLContext.Default xmlDefaults = xmlContext.getDefault( null ); + for( Element element : xmlContext.getAllDocuments() ) { + List<Element> elements = element.elements( "sequence-generator" ); + List<SequenceGenerator> sequenceGenerators = (List<SequenceGenerator>) defaults.get(SequenceGenerator.class); + if (sequenceGenerators == null) { + sequenceGenerators = new ArrayList<SequenceGenerator>(); + defaults.put( SequenceGenerator.class, sequenceGenerators ); + } + for (Element subelement : elements) { + sequenceGenerators.add( EJB3OverridenAnnotationReader.buildSequenceGeneratorAnnotation( subelement ) ); + } + + elements = element.elements( "table-generator" ); + List<TableGenerator> tableGenerators = (List<TableGenerator>) defaults.get(TableGenerator.class); + if (tableGenerators == null) { + tableGenerators = new ArrayList<TableGenerator>(); + defaults.put( TableGenerator.class, tableGenerators ); + } + for (Element subelement : elements) { + tableGenerators.add( EJB3OverridenAnnotationReader.buildTableGeneratorAnnotation( subelement, xmlDefaults ) ); + } + + List<NamedQuery> namedQueries = (List<NamedQuery>) defaults.get(NamedQuery.class); + if (namedQueries == null) { + namedQueries = new ArrayList<NamedQuery>(); + defaults.put( NamedQuery.class, namedQueries ); + } + List<NamedQuery> currentNamedQueries = EJB3OverridenAnnotationReader.buildNamedQueries(element, false); + namedQueries.addAll( currentNamedQueries ); + + List<NamedNativeQuery> namedNativeQueries = (List<NamedNativeQuery>) defaults.get(NamedNativeQuery.class); + if (namedNativeQueries == null) { + namedNativeQueries = new ArrayList<NamedNativeQuery>(); + defaults.put( NamedNativeQuery.class, namedNativeQueries ); + } + List<NamedNativeQuery> currentNamedNativeQueries = EJB3OverridenAnnotationReader.buildNamedQueries(element, true); + namedNativeQueries.addAll( currentNamedNativeQueries ); + + List<SqlResultSetMapping> sqlResultSetMappings = (List<SqlResultSetMapping>) defaults.get(SqlResultSetMapping.class); + if (sqlResultSetMappings == null) { + sqlResultSetMappings = new ArrayList<SqlResultSetMapping>(); + defaults.put( SqlResultSetMapping.class, sqlResultSetMappings ); + } + List<SqlResultSetMapping> currentSqlResultSetMappings = EJB3OverridenAnnotationReader.buildSqlResultsetMappings(element, xmlDefaults); + sqlResultSetMappings.addAll( currentSqlResultSetMappings ); + } + } + return defaults; + } + XClass toXClass(Type t, final TypeEnvironment context) { return new TypeSwitch<XClass>() { @Override Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/xml/XMLContext.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/xml/XMLContext.java 2006-05-02 18:55:45 UTC (rev 9855) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/xml/XMLContext.java 2006-05-02 21:46:17 UTC (rev 9856) @@ -20,6 +20,7 @@ private Default globalDefaults; private Map<String, Element> classOverriding = new HashMap<String, Element>(); private Map<String, Default> defaultsOverriding = new HashMap<String, Default>(); + private List<Element> defaultElements = new ArrayList<Element>(); /** * Add a document and return the list of added classes names @@ -65,6 +66,7 @@ entityMappingDefault.setCatalog( unitElement != null ? unitElement.getTextTrim() : null ); unitElement = root.element( "access" ); entityMappingDefault.setAccess( unitElement != null ? unitElement.getTextTrim() : null ); + defaultElements.add(root); List<String> addedClasses = new ArrayList<String>(); List<Element> entities = (List<Element>) root.elements( "entity" ); @@ -115,8 +117,10 @@ public Default getDefault(String className) { Default xmlDefault = new Default(); xmlDefault.override( globalDefaults ); - Default entityMappingOverriding = defaultsOverriding.get( className ); - xmlDefault.override( entityMappingOverriding ); + if (className != null) { + Default entityMappingOverriding = defaultsOverriding.get( className ); + xmlDefault.override( entityMappingOverriding ); + } return xmlDefault; } @@ -124,6 +128,10 @@ return classOverriding.get( className ); } + public List<Element> getAllDocuments() { + return defaultElements; + } + public static class Default { private String access; private String packageName; Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/Ejb3XmlTest.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/Ejb3XmlTest.java 2006-05-02 18:55:45 UTC (rev 9855) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/Ejb3XmlTest.java 2006-05-02 21:46:17 UTC (rev 9856) @@ -22,12 +22,9 @@ model.setManufacturer( manufacturer ); manufacturer.getModels().add( model ); s.persist( model ); - tx.commit(); - s.close(); + s.flush(); + s.clear(); - s = openSession(); - tx = s.beginTransaction(); - model.setYear( new Date() ); manufacturer = (Manufacturer) s.get( Manufacturer.class, manufacturer.getId() ); List<Model> cars = s.getNamedQuery( "allModelsPerManufacturer" ) @@ -39,7 +36,7 @@ s.delete( manufacturer ); s.delete( car ); } - tx.commit(); + tx.rollback(); s.close(); } @@ -55,6 +52,19 @@ s.close(); } + public void testXmlDefaultOverriding() throws Exception { + Session s = openSession(); + Transaction tx = s.beginTransaction(); + Manufacturer manufacturer = new Manufacturer(); + s.persist( manufacturer ); + s.flush(); + s.clear(); + + assertEquals( 1, s.getNamedQuery( "manufacturer.findAll" ).list().size() ); + tx.rollback(); + s.close(); + } + protected Class[] getMappings() { return new Class[]{ CarModel.class, Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/Manufacturer.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/Manufacturer.java 2006-05-02 18:55:45 UTC (rev 9855) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/Manufacturer.java 2006-05-02 21:46:17 UTC (rev 9856) @@ -6,11 +6,15 @@ import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.OneToMany; +import javax.persistence.NamedQuery; +import javax.persistence.TableGenerator; /** * @author Emmanuel Bernard */ @Entity +@NamedQuery(name="manufacturer.findAll", query = "from Manufacturer where 1 = 2") +@TableGenerator(name="generator", table = "this is a broken name with select from and other SQL keywords") public class Manufacturer { private Integer id; private Set<Model> models = new HashSet<Model>(); Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/orm.xml =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/orm.xml 2006-05-02 18:55:45 UTC (rev 9855) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/orm.xml 2006-05-02 21:46:17 UTC (rev 9856) @@ -11,6 +11,10 @@ </persistence-unit-defaults> </persistence-unit-metadata> <package>org.hibernate.test.annotations.xml.ejb3</package> + <table-generator name="generator" table="table_id"/> + <named-query name="manufacturer.findAll"> + <query>select m from Manufacturer m</query> + </named-query> <entity class="Model" access="PROPERTY" name="ModelZ" metadata-complete="true"> <table name="ModelZ"> </table> @@ -18,7 +22,7 @@ <attributes> <id name="id"> <column name="fld_id"/> - <generated-value strategy="AUTO"/> + <generated-value strategy="TABLE" generator="generator"/> </id> <many-to-one name="manufacturer" fetch="LAZY"> <join-column name="manufacturer_pk"/> |
From: <hib...@li...> - 2006-05-02 18:58:15
|
Author: ste...@jb... Date: 2006-05-02 14:55:45 -0400 (Tue, 02 May 2006) New Revision: 9855 Added: trunk/Hibernate3/src/org/hibernate/proxy/EntityNotFoundDelegate.java trunk/Hibernate3/test/org/hibernate/test/ejb3/proxy/ trunk/Hibernate3/test/org/hibernate/test/ejb3/proxy/Ejb3ProxyTest.java Modified: trunk/Hibernate3/src/org/hibernate/ObjectNotFoundException.java trunk/Hibernate3/src/org/hibernate/cfg/Configuration.java trunk/Hibernate3/src/org/hibernate/engine/SessionFactoryImplementor.java trunk/Hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java trunk/Hibernate3/src/org/hibernate/impl/SessionFactoryImpl.java trunk/Hibernate3/src/org/hibernate/impl/SessionImpl.java trunk/Hibernate3/src/org/hibernate/proxy/AbstractLazyInitializer.java trunk/Hibernate3/test/org/hibernate/test/ejb3/EJB3Suite.java trunk/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java Log: HHH-1591 - hook for ejb3 ENFE HHH-1714 - get() semantics Modified: trunk/Hibernate3/src/org/hibernate/ObjectNotFoundException.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/ObjectNotFoundException.java 2006-05-02 15:11:17 UTC (rev 9854) +++ trunk/Hibernate3/src/org/hibernate/ObjectNotFoundException.java 2006-05-02 18:55:45 UTC (rev 9855) @@ -21,17 +21,4 @@ public ObjectNotFoundException(Serializable identifier, String clazz) { super(identifier, clazz); } - - public static void throwIfNull(Object o, Serializable id, String clazz) - throws ObjectNotFoundException { - if (o==null) throw new ObjectNotFoundException(id, clazz); - } - } - - - - - - - Modified: trunk/Hibernate3/src/org/hibernate/cfg/Configuration.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/cfg/Configuration.java 2006-05-02 15:11:17 UTC (rev 9854) +++ trunk/Hibernate3/src/org/hibernate/cfg/Configuration.java 2006-05-02 18:55:45 UTC (rev 9855) @@ -36,6 +36,7 @@ import org.hibernate.Interceptor; import org.hibernate.MappingException; import org.hibernate.SessionFactory; +import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.MySQLDialect; import org.hibernate.engine.FilterDefinition; @@ -136,6 +137,7 @@ private Interceptor interceptor; private Properties properties; private EntityResolver entityResolver; + private EntityNotFoundDelegate entityNotFoundDelegate; private transient XMLHelper xmlHelper; protected transient Map typeDefs; @@ -236,6 +238,27 @@ } /** + * Retrieve the user-supplied delegate to handle non-existent entity + * scenarios. May be null. + * + * @return The user-supplied delegate + */ + public EntityNotFoundDelegate getEntityNotFoundDelegate() { + return entityNotFoundDelegate; + } + + /** + * Specify a user-supplied delegate to be used to handle scenarios where an entity could not be + * located by specified id. This is mainly intended for EJB3 implementations to be able to + * control how proxy initialization errors should be handled... + * + * @param entityNotFoundDelegate The delegate to use + */ + public void setEntityNotFoundDelegate(EntityNotFoundDelegate entityNotFoundDelegate) { + this.entityNotFoundDelegate = entityNotFoundDelegate; + } + + /** * Read mappings from a particular XML file * * @param xmlFile a path to a file @@ -343,7 +366,9 @@ * @param xml an XML string */ public Configuration addXML(String xml) throws MappingException { - if ( log.isDebugEnabled() ) log.debug( "Mapping XML:\n" + xml ); + if ( log.isDebugEnabled() ) { + log.debug( "Mapping XML:\n" + xml ); + } try { List errors = new ArrayList(); org.dom4j.Document doc = xmlHelper.createSAXReader( "XML String", errors, entityResolver ) @@ -365,7 +390,9 @@ * @param url */ public Configuration addURL(URL url) throws MappingException { - if ( log.isDebugEnabled() ) log.debug( "Reading mapping document from URL:" + url ); + if ( log.isDebugEnabled() ) { + log.debug( "Reading mapping document from URL:" + url ); + } try { addInputStream( url.openStream() ); } @@ -381,7 +408,9 @@ * @param doc a DOM document */ public Configuration addDocument(Document doc) throws MappingException { - if ( log.isDebugEnabled() ) log.debug( "Mapping document:\n" + doc ); + if ( log.isDebugEnabled() ) { + log.debug( "Mapping document:\n" + doc ); + } add( xmlHelper.createDOMReader().read( doc ) ); return this; } @@ -559,7 +588,9 @@ finally { try { - if (jarFile!=null) jarFile.close(); + if ( jarFile != null ) { + jarFile.close(); + } } catch (IOException ioe) { log.error("could not close jar", ioe); @@ -862,7 +893,9 @@ defaultCatalog, defaultSchema ); - while ( subiter.hasNext() ) script.add( subiter.next() ); + while ( subiter.hasNext() ) { + script.add( subiter.next() ); + } } Iterator comments = table.sqlCommentStrings( dialect, defaultCatalog, defaultSchema ); @@ -1413,12 +1446,16 @@ Element sfNode = doc.getRootElement().element( "session-factory" ); String name = sfNode.attributeValue( "name" ); - if ( name != null ) properties.setProperty( Environment.SESSION_FACTORY_NAME, name ); + if ( name != null ) { + properties.setProperty( Environment.SESSION_FACTORY_NAME, name ); + } addProperties( sfNode ); parseSessionFactory( sfNode, name ); Element secNode = doc.getRootElement().element( "security" ); - if ( secNode != null ) parseSecurity( secNode ); + if ( secNode != null ) { + parseSecurity( secNode ); + } log.info( "Configured SessionFactory: " + name ); log.debug( "properties: " + properties ); @@ -1527,7 +1564,9 @@ private void parseListener(Element element) { String type = element.attributeValue( "type" ); - if ( type == null ) throw new MappingException( "No type specified for listener" ); + if ( type == null ) { + throw new MappingException( "No type specified for listener" ); + } String impl = element.attributeValue( "class" ); log.debug( "Event listener: " + type + "=" + impl ); setListeners( type, new String[]{impl} ); @@ -1835,7 +1874,9 @@ void setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String region, boolean includeLazy) throws MappingException { RootClass rootClass = getRootClassMapping( clazz ); - if ( rootClass == null ) throw new MappingException( "Cannot cache an unknown entity: " + clazz ); + if ( rootClass == null ) { + throw new MappingException( "Cannot cache an unknown entity: " + clazz ); + } rootClass.setCacheConcurrencyStrategy( concurrencyStrategy ); rootClass.setCacheRegionName( region ); rootClass.setLazyPropertiesCacheable( includeLazy ); @@ -1858,7 +1899,9 @@ public void setCollectionCacheConcurrencyStrategy(String collectionRole, String concurrencyStrategy, String region) throws MappingException { Collection collection = getCollectionMapping( collectionRole ); - if ( collection == null ) throw new MappingException( "Cannot cache an unknown collection: " + collectionRole ); + if ( collection == null ) { + throw new MappingException( "Cannot cache an unknown collection: " + collectionRole ); + } collection.setCacheConcurrencyStrategy( concurrencyStrategy ); collection.setCacheRegionName( region ); } @@ -1928,7 +1971,9 @@ if ( pc == null ) { throw new MappingException( "persistent class not known: " + persistentClass ); } - if ( !pc.hasIdentifierProperty() ) return null; + if ( !pc.hasIdentifierProperty() ) { + return null; + } return pc.getIdentifierProperty().getName(); } Modified: trunk/Hibernate3/src/org/hibernate/engine/SessionFactoryImplementor.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/SessionFactoryImplementor.java 2006-05-02 15:11:17 UTC (rev 9854) +++ trunk/Hibernate3/src/org/hibernate/engine/SessionFactoryImplementor.java 2006-05-02 18:55:45 UTC (rev 9855) @@ -12,6 +12,7 @@ import org.hibernate.MappingException; import org.hibernate.SessionFactory; import org.hibernate.ConnectionReleaseMode; +import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.engine.query.QueryPlanCache; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; @@ -161,4 +162,6 @@ * @return set of all the collection roles in which the given entityName participates. */ public Set getCollectionRolesByEntityParticipant(String entityName); + + public EntityNotFoundDelegate getEntityNotFoundDelegate(); } Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java 2006-05-02 15:11:17 UTC (rev 9854) +++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java 2006-05-02 18:55:45 UTC (rev 9855) @@ -50,7 +50,6 @@ * Handle the given load event. * * @param event The load event to be handled. - * @return The result (i.e., the loaded entity). * @throws HibernateException */ public void onLoad(LoadEvent event, LoadEventListener.LoadType loadType) throws HibernateException { @@ -125,7 +124,9 @@ boolean isOptionalInstance = event.getInstanceToLoad() != null; if ( !options.isAllowNulls() || isOptionalInstance ) { - ObjectNotFoundException.throwIfNull( entity, event.getEntityId(), event.getEntityClassName() ); + if ( entity == null ) { + event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( event.getEntityClassName(), event.getEntityId() ); + } } if ( isOptionalInstance && entity != event.getInstanceToLoad() ) { @@ -198,9 +199,13 @@ if ( li.isUnwrap() ) { return li.getImplementation(); } - // return existing or narrowed proxy - Object impl = options.isAllowProxyCreation() ? - null : load(event, persister, keyToLoad, options); + Object impl = null; + if ( !options.isAllowProxyCreation() ) { + impl = load( event, persister, keyToLoad, options ); + if ( impl == null ) { + event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( persister.getEntityName(), keyToLoad.getIdentifier()); + } + } return persistenceContext.narrowProxy( proxy, persister, keyToLoad, impl ); } Modified: trunk/Hibernate3/src/org/hibernate/impl/SessionFactoryImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/impl/SessionFactoryImpl.java 2006-05-02 15:11:17 UTC (rev 9854) +++ trunk/Hibernate3/src/org/hibernate/impl/SessionFactoryImpl.java 2006-05-02 18:55:45 UTC (rev 9855) @@ -33,6 +33,8 @@ import org.hibernate.QueryException; import org.hibernate.SessionFactory; import org.hibernate.StatelessSession; +import org.hibernate.ObjectNotFoundException; +import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.context.CurrentSessionContext; import org.hibernate.context.ThreadLocalSessionContext; import org.hibernate.context.JTASessionContext; @@ -137,6 +139,7 @@ private final transient StatisticsImpl statistics = new StatisticsImpl(this); private final transient EventListeners eventListeners; private final transient CurrentSessionContext currentSessionContext; + private final transient EntityNotFoundDelegate entityNotFoundDelegate; private final QueryPlanCache queryPlanCache = new QueryPlanCache( this ); @@ -167,9 +170,11 @@ log.debug("Session factory constructed with filter configurations : " + filters); } - if ( log.isDebugEnabled() ) log.debug( - "instantiating session factory with properties: " + properties - ); + if ( log.isDebugEnabled() ) { + log.debug( + "instantiating session factory with properties: " + properties + ); + } // Caches settings.getCacheProvider().start( properties ); @@ -236,7 +241,9 @@ settings, properties ); - if (cache!=null) allCacheRegions.put( cache.getRegionName(), cache.getCache() ); + if ( cache != null ) { + allCacheRegions.put( cache.getRegionName(), cache.getCache() ); + } CollectionPersister persister = PersisterFactory.createCollectionPersister(cfg, model, cache, this); collectionPersisters.put( model.getRole(), persister.getCollectionMetadata() ); Type indexType = persister.getIndexType(); @@ -297,10 +304,18 @@ log.debug("instantiated session factory"); - if ( settings.isAutoCreateSchema() ) new SchemaExport(cfg, settings).create(false, true); - if ( settings.isAutoUpdateSchema() ) new SchemaUpdate(cfg, settings).execute(false, true); - if ( settings.isAutoValidateSchema() ) new SchemaValidator(cfg, settings).validate(); - if ( settings.isAutoDropSchema() ) schemaExport = new SchemaExport(cfg, settings); + if ( settings.isAutoCreateSchema() ) { + new SchemaExport( cfg, settings ).create( false, true ); + } + if ( settings.isAutoUpdateSchema() ) { + new SchemaUpdate( cfg, settings ).execute( false, true ); + } + if ( settings.isAutoValidateSchema() ) { + new SchemaValidator( cfg, settings ).validate(); + } + if ( settings.isAutoDropSchema() ) { + schemaExport = new SchemaExport( cfg, settings ); + } if ( settings.getTransactionManagerLookup()!=null ) { log.debug("obtaining JTA TransactionManager"); @@ -338,7 +353,9 @@ String queryName = ( String ) iterator.next(); HibernateException e = ( HibernateException ) errors.get( queryName ); failingQueries.append( queryName ); - if ( iterator.hasNext() ) failingQueries.append(", "); + if ( iterator.hasNext() ) { + failingQueries.append( ", " ); + } log.error( "Error in named query: " + queryName, e ); } throw new HibernateException( failingQueries.toString() ); @@ -346,6 +363,17 @@ //stats getStatistics().setStatisticsEnabled( settings.isStatisticsEnabled() ); + + // EntityNotFoundDelegate + EntityNotFoundDelegate entityNotFoundDelegate = cfg.getEntityNotFoundDelegate(); + if ( entityNotFoundDelegate == null ) { + entityNotFoundDelegate = new EntityNotFoundDelegate() { + public void handleEntityNotFound(String entityName, Serializable id) { + throw new ObjectNotFoundException( id, entityName ); + } + }; + } + this.entityNotFoundDelegate = entityNotFoundDelegate; } public QueryPlanCache getQueryPlanCache() { @@ -665,7 +693,9 @@ String testClassName = testQueryable.getEntityName(); boolean isMappedClass = className.equals(testClassName); if ( testQueryable.isExplicitPolymorphism() ) { - if (isMappedClass) return new String[] { className }; //NOTE EARLY EXIT + if ( isMappedClass ) { + return new String[] {className}; //NOTE EARLY EXIT + } } else { if (isMappedClass) { @@ -682,7 +712,9 @@ else { assignableSuperclass = false; } - if (!assignableSuperclass) results.add(testClassName); + if ( !assignableSuperclass ) { + results.add( testClassName ); + } } } } @@ -738,13 +770,17 @@ Iterator iter = entityPersisters.values().iterator(); while ( iter.hasNext() ) { EntityPersister p = (EntityPersister) iter.next(); - if ( p.hasCache() ) p.getCache().destroy(); + if ( p.hasCache() ) { + p.getCache().destroy(); + } } iter = collectionPersisters.values().iterator(); while ( iter.hasNext() ) { CollectionPersister p = (CollectionPersister) iter.next(); - if ( p.hasCache() ) p.getCache().destroy(); + if ( p.hasCache() ) { + p.getCache().destroy(); + } } if ( settings.isQueryCacheEnabled() ) { @@ -767,7 +803,9 @@ SessionFactoryObjectFactory.removeInstance(uuid, name, properties); } - if ( settings.isAutoDropSchema() ) schemaExport.drop(false, true); + if ( settings.isAutoDropSchema() ) { + schemaExport.drop( false, true ); + } } @@ -827,7 +865,9 @@ public void evictCollection(String roleName) throws HibernateException { CollectionPersister p = getCollectionPersister(roleName); if ( p.hasCache() ) { - if ( log.isDebugEnabled() ) log.debug( "evicting second-level cache: " + p.getRole() ); + if ( log.isDebugEnabled() ) { + log.debug( "evicting second-level cache: " + p.getRole() ); + } p.getCache().clear(); } } @@ -908,7 +948,9 @@ synchronized (allCacheRegions) { if ( settings.isQueryCacheEnabled() ) { QueryCache currentQueryCache = (QueryCache) queryCaches.get(cacheRegion); - if (currentQueryCache!=null) currentQueryCache.clear(); + if ( currentQueryCache != null ) { + currentQueryCache.clear(); + } } } } @@ -972,6 +1014,10 @@ return eventListeners; } + public EntityNotFoundDelegate getEntityNotFoundDelegate() { + return entityNotFoundDelegate; + } + /** * Custom serialization hook used during Session serialization. * Modified: trunk/Hibernate3/src/org/hibernate/impl/SessionImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/impl/SessionImpl.java 2006-05-02 15:11:17 UTC (rev 9854) +++ trunk/Hibernate3/src/org/hibernate/impl/SessionImpl.java 2006-05-02 18:55:45 UTC (rev 9855) @@ -783,7 +783,9 @@ boolean success = false; try { fireLoad( event, LoadEventListener.LOAD ); - ObjectNotFoundException.throwIfNull( event.getResult(), id, entityName); + if ( event.getResult() == null ) { + getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id ); + } success = true; return event.getResult(); } Modified: trunk/Hibernate3/src/org/hibernate/proxy/AbstractLazyInitializer.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/proxy/AbstractLazyInitializer.java 2006-05-02 15:11:17 UTC (rev 9854) +++ trunk/Hibernate3/src/org/hibernate/proxy/AbstractLazyInitializer.java 2006-05-02 18:55:45 UTC (rev 9855) @@ -65,14 +65,18 @@ else { target = session.immediateLoad(entityName, id); initialized = true; - if (!unwrap) { - ObjectNotFoundException.throwIfNull(target, id, entityName); //should it be UnresolvableObject? - } + checkTargetState(); } } else { - if ( !unwrap ) { - ObjectNotFoundException.throwIfNull(target, id, entityName); + checkTargetState(); + } + } + + private void checkTargetState() { + if ( !unwrap ) { + if ( target == null ) { + getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id ); } } } Added: trunk/Hibernate3/src/org/hibernate/proxy/EntityNotFoundDelegate.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/proxy/EntityNotFoundDelegate.java 2006-05-02 15:11:17 UTC (rev 9854) +++ trunk/Hibernate3/src/org/hibernate/proxy/EntityNotFoundDelegate.java 2006-05-02 18:55:45 UTC (rev 9855) @@ -0,0 +1,12 @@ +package org.hibernate.proxy; + +import java.io.Serializable; + +/** + * Delegate to handle the scenario of an entity not found by a specified id. + * + * @author Steve Ebersole + */ +public interface EntityNotFoundDelegate { + public void handleEntityNotFound(String entityName, Serializable id); +} Modified: trunk/Hibernate3/test/org/hibernate/test/ejb3/EJB3Suite.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/ejb3/EJB3Suite.java 2006-05-02 15:11:17 UTC (rev 9854) +++ trunk/Hibernate3/test/org/hibernate/test/ejb3/EJB3Suite.java 2006-05-02 18:55:45 UTC (rev 9855) @@ -4,6 +4,7 @@ import junit.framework.TestSuite; import org.hibernate.test.ejb3.lock.EJB3LockTest; import org.hibernate.test.ejb3.lock.RepeatableReadTest; +import org.hibernate.test.ejb3.proxy.Ejb3ProxyTest; /** * @author Steve Ebersole @@ -13,6 +14,7 @@ TestSuite suite = new TestSuite( "EJB3-compliance tests"); suite.addTest( EJB3LockTest.suite() ); suite.addTest( RepeatableReadTest.suite() ); + suite.addTest( Ejb3ProxyTest.suite() ); return suite; } } Added: trunk/Hibernate3/test/org/hibernate/test/ejb3/proxy/Ejb3ProxyTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/ejb3/proxy/Ejb3ProxyTest.java 2006-05-02 15:11:17 UTC (rev 9854) +++ trunk/Hibernate3/test/org/hibernate/test/ejb3/proxy/Ejb3ProxyTest.java 2006-05-02 18:55:45 UTC (rev 9855) @@ -0,0 +1,141 @@ +package org.hibernate.test.ejb3.proxy; + +import org.hibernate.test.TestCase; +import org.hibernate.test.ejb3.Item; +import org.hibernate.cfg.Configuration; +import org.hibernate.proxy.EntityNotFoundDelegate; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.Hibernate; + +import java.io.Serializable; + +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Test relation between proxies and get()/load() processing + * and make sure the interactions match the ejb3 expectations + * + * @author Steve Ebersole + */ +public class Ejb3ProxyTest extends TestCase { + public Ejb3ProxyTest(String name) { + super( name ); + } + + public static Test suite() { + return new TestSuite( Ejb3ProxyTest.class ); + } + + public void testEjb3ProxyUsage() { + Session s = openSession(); + Transaction txn = s.beginTransaction(); + + Item item = ( Item ) s.load( Item.class, new Long(-1) ); + assertFalse( Hibernate.isInitialized( item ) ); + try { + Hibernate.initialize( item ); + fail( "proxy access did not fail on non-existent proxy" ); + } + catch ( EntityNotFoundException e ) { + // expected behavior + } + catch ( Throwable t ) { + fail( "unexpected exception type on non-existent proxy access : " + t ); + } + + s.clear(); + + Item item2 = ( Item ) s.load( Item.class, new Long(-1) ); + assertFalse( Hibernate.isInitialized( item2 ) ); + assertFalse( item == item2 ); + try { + item2.getName(); + fail( "proxy access did not fail on non-existent proxy" ); + } + catch ( EntityNotFoundException e ) { + // expected behavior + } + catch ( Throwable t ) { + fail( "unexpected exception type on non-existent proxy access : " + t ); + } + + txn.commit(); + s.close(); + } + + /** + * The ejb3 find() method maps to the Hibernate get() method + */ + public void testGetSemantics() { + Long nonExistentId = new Long( -1 ); + Session s = openSession(); + Transaction txn = s.beginTransaction(); + Item item = ( Item ) s.get( Item.class, nonExistentId ); + assertNull( "get() of non-existent entity did not return null", item ); + txn.commit(); + s.close(); + + s = openSession(); + txn = s.beginTransaction(); + // first load() it to generate a proxy... + item = ( Item ) s.load( Item.class, nonExistentId ); + assertFalse( Hibernate.isInitialized( item ) ); + // then try to get() it to make sure we get an exception + try { + Item item2 = ( Item ) s.get( Item.class, nonExistentId ); + fail( "force load did not fail on non-existent entity" ); + } + catch ( EntityNotFoundException e ) { + // expected behavior + } + catch( AssertionFailedError e ) { + throw e; + } + catch ( Throwable t ) { + fail( "unexpected exception type on non-existent entity force load : " + t ); + } + txn.commit(); + s.close(); + } + + protected void configure(Configuration cfg) { + super.configure( cfg ); + cfg.setEntityNotFoundDelegate( new Ejb3EntityNotFoundDelegate() ); + } + + protected String[] getMappings() { + return new String[] { "ejb3/Item.hbm.xml", "ejb3/Part.hbm.xml" }; + } + + private static class Ejb3EntityNotFoundDelegate implements EntityNotFoundDelegate { + public void handleEntityNotFound(String entityName, Serializable id) { + throw new EntityNotFoundException( entityName, id ); + } + } + + private static class EntityNotFoundException extends RuntimeException { + private final String entityName; + private final Serializable id; + + public EntityNotFoundException(String entityName, Serializable id) { + this( "unable to locate specified entity", entityName, id ); + } + + public EntityNotFoundException(String message, String entityName, Serializable id) { + super( message ); + this.entityName = entityName; + this.id = id; + } + + public String getEntityName() { + return entityName; + } + + public Serializable getId() { + return id; + } + } +} Modified: trunk/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java 2006-05-02 15:11:17 UTC (rev 9854) +++ trunk/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java 2006-05-02 18:55:45 UTC (rev 9855) @@ -237,7 +237,6 @@ s.close(); } - protected String[] getMappings() { return new String[] { "proxy/DataPoint.hbm.xml" }; } |
From: <hib...@li...> - 2006-05-02 15:11:55
|
Author: ste...@jb... Date: 2006-05-02 11:11:17 -0400 (Tue, 02 May 2006) New Revision: 9854 Modified: trunk/Hibernate3/src/org/hibernate/proxy/AbstractLazyInitializer.java trunk/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java Log: HHH-1695 : subsequent access on non-existent proxy Modified: trunk/Hibernate3/src/org/hibernate/proxy/AbstractLazyInitializer.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/proxy/AbstractLazyInitializer.java 2006-05-02 15:09:11 UTC (rev 9853) +++ trunk/Hibernate3/src/org/hibernate/proxy/AbstractLazyInitializer.java 2006-05-02 15:11:17 UTC (rev 9854) @@ -70,6 +70,11 @@ } } } + else { + if ( !unwrap ) { + ObjectNotFoundException.throwIfNull(target, id, entityName); + } + } } public final void setSession(SessionImplementor s) throws HibernateException { Modified: trunk/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java 2006-05-02 15:09:11 UTC (rev 9853) +++ trunk/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java 2006-05-02 15:11:17 UTC (rev 9854) @@ -12,6 +12,7 @@ import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.FlushMode; +import org.hibernate.ObjectNotFoundException; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.impl.SessionImpl; @@ -154,7 +155,7 @@ sclone.close(); } - + public void testProxy() { Session s = openSession(); Transaction t = s.beginTransaction(); @@ -204,6 +205,38 @@ s.close(); } + public void testSubsequentNonExistentProxyAccess() { + Session s = openSession(); + Transaction t = s.beginTransaction(); + + DataPoint proxy = ( DataPoint ) s.load( DataPoint.class, new Long(-1) ); + assertFalse( Hibernate.isInitialized( proxy ) ); + try { + proxy.getDescription(); + fail( "proxy access did not fail on non-existent proxy" ); + } + catch( ObjectNotFoundException onfe ) { + // expected + } + catch( Throwable e ) { + fail( "unexpected exception type on non-existent proxy access : " + e ); + } + // try it a second (subsequent) time... + try { + proxy.getDescription(); + fail( "proxy access did not fail on non-existent proxy" ); + } + catch( ObjectNotFoundException onfe ) { + // expected + } + catch( Throwable e ) { + fail( "unexpected exception type on non-existent proxy access : " + e ); + } + + t.commit(); + s.close(); + } + protected String[] getMappings() { return new String[] { "proxy/DataPoint.hbm.xml" }; |
From: <hib...@li...> - 2006-05-02 15:09:47
|
Author: ste...@jb... Date: 2006-05-02 11:09:11 -0400 (Tue, 02 May 2006) New Revision: 9853 Modified: branches/Branch_3_1/Hibernate3/src/org/hibernate/proxy/AbstractLazyInitializer.java branches/Branch_3_1/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java Log: HHH-1695 : subsequent access on non-existent proxy Modified: branches/Branch_3_1/Hibernate3/src/org/hibernate/proxy/AbstractLazyInitializer.java =================================================================== --- branches/Branch_3_1/Hibernate3/src/org/hibernate/proxy/AbstractLazyInitializer.java 2006-05-02 14:32:27 UTC (rev 9852) +++ branches/Branch_3_1/Hibernate3/src/org/hibernate/proxy/AbstractLazyInitializer.java 2006-05-02 15:09:11 UTC (rev 9853) @@ -66,6 +66,11 @@ } } } + else { + if ( !unwrap ) { + ObjectNotFoundException.throwIfNull(target, id, entityName); + } + } } public final void setSession(SessionImplementor s) throws HibernateException { Modified: branches/Branch_3_1/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java =================================================================== --- branches/Branch_3_1/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java 2006-05-02 14:32:27 UTC (rev 9852) +++ branches/Branch_3_1/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java 2006-05-02 15:09:11 UTC (rev 9853) @@ -12,6 +12,7 @@ import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.FlushMode; +import org.hibernate.ObjectNotFoundException; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.impl.SessionImpl; @@ -203,6 +204,38 @@ s.close(); } + public void testSubsequentNonExistentProxyAccess() { + Session s = openSession(); + Transaction t = s.beginTransaction(); + + DataPoint proxy = ( DataPoint ) s.load( DataPoint.class, new Long(-1) ); + assertFalse( Hibernate.isInitialized( proxy ) ); + try { + proxy.getDescription(); + fail( "proxy access did not fail on non-existent proxy" ); + } + catch( ObjectNotFoundException onfe ) { + // expected + } + catch( Throwable e ) { + fail( "unexpected exception type on non-existent proxy access : " + e ); + } + // try it a second (subsequent) time... + try { + proxy.getDescription(); + fail( "proxy access did not fail on non-existent proxy" ); + } + catch( ObjectNotFoundException onfe ) { + // expected + } + catch( Throwable e ) { + fail( "unexpected exception type on non-existent proxy access : " + e ); + } + + t.commit(); + s.close(); + } + protected String[] getMappings() { return new String[] { "proxy/DataPoint.hbm.xml" }; |
From: <hib...@li...> - 2006-05-02 14:32:35
|
Author: ste...@jb... Date: 2006-05-02 10:32:27 -0400 (Tue, 02 May 2006) New Revision: 9852 Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/DeleteStatementNode.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/InsertStatementNode.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContext.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverAware.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectStatementNode.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/UpdateStatementNode.java Log: oops, forgot adds Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/DeleteStatementNode.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/DeleteStatementNode.java 2006-05-02 14:26:06 UTC (rev 9851) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/DeleteStatementNode.java 2006-05-02 14:32:27 UTC (rev 9852) @@ -0,0 +1,9 @@ +package org.hibernate.hql.ast.resolve; + +/** + * Specialized statement node for representing DELETE statements + * + * @author Steve Ebersole + */ +public class DeleteStatementNode extends StatementNode { +} Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/InsertStatementNode.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/InsertStatementNode.java 2006-05-02 14:26:06 UTC (rev 9851) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/InsertStatementNode.java 2006-05-02 14:32:27 UTC (rev 9852) @@ -0,0 +1,9 @@ +package org.hibernate.hql.ast.resolve; + +/** + * Specialized statement node for representing INSERT statements + * + * @author Steve Ebersole + */ +public class InsertStatementNode extends StatementNode { +} Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContext.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContext.java 2006-05-02 14:26:06 UTC (rev 9851) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContext.java 2006-05-02 14:32:27 UTC (rev 9852) @@ -0,0 +1,38 @@ +package org.hibernate.hql.ast.resolve; + +import java.util.List; + +/** + * todo: describe PersisterReferenceContext + * + * @author Steve Ebersole + */ +public interface PersisterReferenceContext { + /** + * Constructs an EntityPersisterReference node based on the given entity-name and + * any specified alias. + * + * @param entityName The entity-name of the entity to back the EntityPersisterReference + * @param alias An optional alias under which to store the EntityPersisterReference (later + * used to easily refer to that persister : {@link #locatePersisterReferenceByAlias}). + * @return The constructed EntityPersisterReference node. + */ + public EntityPersisterReference buildEntityPersisterReference(String entityName, String alias); + + /** + * Construct a CollectionPersisterReference based on collection-role. + * <p/> + * todo : not sure this is even needed... + * + * @param collectionRole The collection role (or FQN) + * @param alias The alias to be applied to the constructed CollectionPersisterReference. + * @return The constructed CollectionPersisterReference node. + */ + public CollectionPersisterReference buildCollectionPersisterReference(String collectionRole, String alias); + + public PersisterReference locatePersisterReferenceByAlias(String alias); + + public EntityPersisterReference locatePersisterReferenceExposingProperty(String firstPathExpression); + + public PersisterReference getPersisterReference(PersisterReference source, String propertyName, String alias); +} Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverAware.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverAware.java 2006-05-02 14:26:06 UTC (rev 9851) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverAware.java 2006-05-02 14:32:27 UTC (rev 9852) @@ -0,0 +1,10 @@ +package org.hibernate.hql.ast.resolve; + +/** + * todo: describe ResolverAware + * + * @author Steve Ebersole + */ +public interface ResolverAware { + public void setHqlResolver(HqlResolver resolver); +} Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectStatementNode.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectStatementNode.java 2006-05-02 14:26:06 UTC (rev 9851) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectStatementNode.java 2006-05-02 14:32:27 UTC (rev 9852) @@ -0,0 +1,9 @@ +package org.hibernate.hql.ast.resolve; + +/** + * Specialized statement node for representing SELECT statements + * + * @author Steve Ebersole + */ +public class SelectStatementNode extends StatementNode { +} Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/UpdateStatementNode.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/UpdateStatementNode.java 2006-05-02 14:26:06 UTC (rev 9851) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/UpdateStatementNode.java 2006-05-02 14:32:27 UTC (rev 9852) @@ -0,0 +1,9 @@ +package org.hibernate.hql.ast.resolve; + +/** + * Specialized statement node for representing UPDATE statements + * + * @author Steve Ebersole + */ +public class UpdateStatementNode extends StatementNode { +} |
From: <hib...@li...> - 2006-05-02 14:29:35
|
Author: ste...@jb... Date: 2006-05-02 10:26:06 -0400 (Tue, 02 May 2006) New Revision: 9851 Removed: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/RangeNode.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContext.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContextImpl.java Modified: branches/HQL_ANTLR_2/Hibernate3/grammar/hql-resolve.g branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/StatementNode.java branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/HqlResolverTest.java Log: further join structure work plus property-reference stuff Modified: branches/HQL_ANTLR_2/Hibernate3/grammar/hql-resolve.g =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/grammar/hql-resolve.g 2006-05-02 11:07:06 UTC (rev 9850) +++ branches/HQL_ANTLR_2/Hibernate3/grammar/hql-resolve.g 2006-05-02 14:26:06 UTC (rev 9851) @@ -4,8 +4,6 @@ package org.hibernate.hql.antlr; import java.util.*; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; } /** @@ -41,34 +39,50 @@ // -- Declarations -- { - private static Log log = LogFactory.getLog( HqlBaseResolver.class ); - // Semantic action methods, overridden in subclasses for clarity. + // Statement node BEGIN/END handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - protected void pushContext(AST outputAst,AST inputAst) { } + protected void pushStatement(AST statementNode) { + } - protected void popContext() { } + protected void popStatement() { + } - protected void defineRange(AST range,String path,AST alias, AST fetch) { } + // persister reference handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + protected AST buildEntityPersisterReference(String entityName, AST alias) { return null; } - protected AST buildThetaJoinNode(AST persisterReference) { - return null; + protected void handleExplicitPropertyJoin( + AST propertyReference, + AST alias, + AST joinType, + AST fetch, + AST propertyFetch, + AST withClause) { } - protected AST buildExplicitPropertyJoinNode(AST propertyReference, AST alias, AST joinType, AST fetch, AST propertyFetch, AST withClause) { - return null; + protected void handleAdHocJoinNode( + AST persisterReference, + AST joinType, + AST onClause) { } - protected AST buildAdHocJoinNode(AST persisterReference, AST joinType, AST onClause) { + protected boolean isEntityName(String test) { + return false; + } + + + // property reference handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + protected AST resolveAtomicPropertyReference(AST propertyIdent) { return null; } - protected boolean isEntityName(String test) { - return false; + protected AST resolveCompoundPropertyReference(AST dotStructure) { + return null; } } @@ -84,22 +98,19 @@ ; updateStatement - : #(UPDATE (VERSIONED)? fromClause setClause (whereClause)? - { popContext(); } ) + : #(UPDATE { pushStatement( #updateStatement ); } (VERSIONED)? fromClause setClause (whereClause)? { popStatement(); }) ; deleteStatement - : #(DELETE fromClause (whereClause)? - { popContext(); } ) + : #(DELETE { pushStatement( #deleteStatement ); } fromClause (whereClause)? { popStatement(); }) ; insertStatement - : #(INSERT intoClause query - { popContext(); } ) + : #(INSERT { pushStatement( #insertStatement ); } intoClause query { popStatement(); }) ; query - : #(QUERY + : #(QUERY { pushStatement( #query ); } // The first phase places the FROM first to make processing the SELECT simpler. #(SELECT_FROM fromClause @@ -107,8 +118,9 @@ ) (whereClause)? (groupClause)? - (orderClause)? - { popContext(); } + (orderClause)? { + popStatement(); + } ) ; @@ -120,8 +132,7 @@ fromClause -// : #( f:FROM { pushContext(#fromClause, f); } entityPersisterReference ( thetaJoin | explicitJoin )* ) - : #( f:FROM { pushContext(#fromClause, f); } range ( thetaJoin | explicitJoin )* ) + : #( f:FROM ( range | explicitJoin )* ) ; range! @@ -138,28 +149,28 @@ } ; -thetaJoin! -// : #( COMMA e:entityPersisterReference ) { -// #thetaJoin = buildThetaJoinNode( e ); -// } - : r:range { - #thetaJoin = buildThetaJoinNode( #r ); - } - ; - explicitJoin! : #(JOIN (jt:joinType)? joinRhs[jt] ) ; -joinRhs [AST joinType] +joinRhs! [AST joinType] : { isEntityName( pathAsString( _t ) ) }? e:entityPersisterReference (on:ON)? { - buildAdHocJoinNode( #e, joinType, on ); + handleAdHocJoinNode( #e, joinType, on ); } - | (f:FETCH)? ref:propertyRef[true] (a:ALIAS)? (pf:FETCH)? (with:WITH)? { - buildExplicitPropertyJoinNode( #ref, a, joinType, f, pf, with ); + | (f:FETCH)? prop:joinedProperty (a:ALIAS)? (pf:FETCH)? (with:WITH)? { + handleExplicitPropertyJoin( #prop, a, joinType, f, pf, with ); } ; +joinedProperty! + : i:identifier { + #joinedProperty = #( [DOT, "."], i ); + } + | d:dotRootStructure { + #joinedProperty = #d; + } + ; + // TODO : need to add cross joins joinType : ( (LEFT | RIGHT) (OUTER)? ) @@ -168,7 +179,7 @@ ; intoClause - : #(i:INTO { pushContext(#intoClause,i); } (subtree)* ) + : #(i:INTO (subtree)* ) ; whereClause @@ -232,8 +243,8 @@ ; collectionFunction - : #(ELEMENTS propertyRef [true] ) - | #(INDICES propertyRef [true] ) + : #( ELEMENTS propertyRef ) + | #( INDICES propertyRef ) ; count @@ -270,7 +281,7 @@ ; addrExpr - : propertyRef [true] + : propertyRef | #(INDEX_OP addrExprLhs expr) ; @@ -303,27 +314,62 @@ | #(AGGREGATE aggregateExpr ) ; -propertyRef! [ boolean root ] +// property references come in 3 basic flavors: +// (1) "simple" (either qualified or unqualified) : represents a reference to +// a value-type property +// (2) "nested" (either qualified or unqualified) : represents a series of +// property references which result in "implicit joins" being +// generated +// (3) "indexed" (either qualified or unqualified) : represents indexed access +// into an indexed collection such as a map or list +// +// an additional consideration when dealing with property references is the question +// of qualified vs unqualified references. Qualified references are "rooted" at an +// alias pointing to a particular persister reference, while unqualified references +// do not start with any such alias. Thus the "root" of the property reference +// structure may or may not begin with an explicit reference to a persister +// (via an alias). If qualified, the appropriate persister reference is simply looked +// up based on the alias. If unqualified, all non-aliased persister references are +// searched for one containing the indicated property; if one (and only one) is found +// then it is assumed to be the referenced persister; all other cases here are an error. +// +// Both "nested" and "indexed" property references may result in additional joins +// being added to the current from-clause structure implicitly. +propertyRef! : i:identifier { - if (root) { // Make the tree very regular, property refs always have a child. - #propertyRef = #([PROPERTY_REF,#i.getText()],#i); - } - else { // Otherwise, just construct the tree. - #propertyRef = #i; - } + #propertyRef = resolveAtomicPropertyReference( #i ); } - | #(d:DOT lhs:propertyRef [ false ] rhs:propertyName ) { - // Flatten nested DOTs... + | d:dotRootStructure { + #propertyRef = resolveCompoundPropertyReference( #d ); + } + ; + +dotRootStructure! + : #( d:DOT lhs:dotSubStructure rhs:dotStructureAtomic ) { AST first = (#lhs.getType() == DOT) ? #lhs.getFirstChild() : #lhs; - if (root) { // If this is the root of the path tree, then make a property ref node. - #propertyRef = #([PROPERTY_REF,#d.getText()],first,#rhs); - } - else { // If this is not the root of the path tree, then just flatten it. - #propertyRef = #(#d,first,#rhs); - } + #dotRootStructure = #( [DOT, "."], first, #rhs ); } ; +// reuseable rule to provide DOT structure flattening; +// eventually, this will get moved to the first phase as DOT +// structures are recognized there, but that needs to wait till +// we integrate this phase into the overall translation... +dotSubStructure! + : i:identifier { + // indicates we are at the base IDENT of the dot structure + #dotSubStructure = #i; + } + | #( d:DOT lhs:dotSubStructure rhs:dotStructureAtomic ) { + AST first = (#lhs.getType() == DOT) ? #lhs.getFirstChild() : #lhs; + #dotSubStructure = #( #d, first, #rhs ); + } + ; + +dotStructureAtomic + : propertyName + ; + propertyName : identifier | CLASS Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java 2006-05-02 11:07:06 UTC (rev 9850) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java 2006-05-02 14:26:06 UTC (rev 9851) @@ -1,34 +1,108 @@ package org.hibernate.hql.ast.resolve; import org.hibernate.type.AssociationType; -import org.hibernate.hql.ast.tree.Node; +import org.hibernate.type.EntityType; +import org.hibernate.type.Type; +import org.hibernate.type.ComponentType; +import org.hibernate.persister.collection.QueryableCollection; +import org.hibernate.persister.entity.Queryable; +import org.hibernate.hql.CollectionProperties; +import org.hibernate.QueryException; /** * @author Steve Ebersole */ -public class CollectionPersisterReference extends Node implements PersisterReference { - // TODO : implement +public class CollectionPersisterReference extends EntityPersisterReference implements ResolverAware { + + private HqlResolver resolver; + private String role; + private String alias; + private QueryableCollection persister; + + public void initialize(String role, String alias) { + this.role = role; + this.alias = alias; + } + + public QueryableCollection getCollectionPersister() { + if ( persister == null ) { + persister = ( QueryableCollection ) resolver.getSessionFactory().getCollectionPersister( role ); + } + return persister; + } + + public Queryable getEntityPersister() { + if ( getCollectionPersister().getElementType().isEntityType() ) { + EntityType elementEntityType = ( EntityType ) getCollectionPersister().getElementType(); + return ( Queryable ) elementEntityType.getAssociatedJoinable( resolver.getSessionFactory() ); + } + else { + throw new QueryException( "not a collection of entities" ); + } + } + public String getName() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return role; } public String getAlias() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return alias; } public AssociationType getPersisterType() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return ( AssociationType ) getEntityPersister().getType(); } + public Type getPropertyType(String propertyName) { + if ( CollectionProperties.isAnyCollectionProperty( propertyName ) ) { + // todo + return null; + } + else { + Type elementType = getCollectionPersister().getElementType(); + if ( elementType.isAssociationType() ) { + // a collection of entities + EntityType elementEntityType = ( EntityType ) elementType; + try { + Queryable elementEntityPersister = ( Queryable ) elementEntityType + .getAssociatedJoinable( resolver.getSessionFactory() ); + return elementEntityPersister.getPropertyType( propertyName ); + } + catch( Throwable t ) { + // ignore + } + } + else if ( elementType.isComponentType() ) { + ComponentType elementComponentType = ( ComponentType ) elementType; + String[] subPropertyNames = elementComponentType.getPropertyNames(); + for ( int i = 0; i < subPropertyNames.length; i++ ) { + if ( subPropertyNames[i].equals( propertyName ) ) { + return elementComponentType.getSubtypes()[i]; + } + } + } + } + return null; + } + public boolean containsProperty(String propertyName) { - return false; //To change body of implemented methods use File | Settings | File Templates. + // this should not be called for "collection properties" (i.e., size, index, etc) + // so we make that assumption here... + try { + return getPropertyType( propertyName ) != null; + } + catch( Throwable t ) { + // ignore + } + return false; } - public PropertyReference retrievePropertyReference(String propertyName) { - return null; //To change body of implemented methods use File | Settings | File Templates. + public void setHqlResolver(HqlResolver resolver) { + this.resolver = resolver; } - public String getDisplayText() { - return null; //To change body of implemented methods use File | Settings | File Templates. + public String toString() { + return "CollectionPersisterReference {role=" + getName() + ", alias=" + getAlias() + + ", element-type=" + getCollectionPersister().getElementType() + "}"; } } Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java 2006-05-02 11:07:06 UTC (rev 9850) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java 2006-05-02 14:26:06 UTC (rev 9851) @@ -1,39 +1,34 @@ package org.hibernate.hql.ast.resolve; import org.hibernate.type.AssociationType; +import org.hibernate.type.Type; import org.hibernate.persister.entity.Queryable; -import org.hibernate.hql.antlr.HqlRTokenTypes; -import org.hibernate.hql.ast.tree.Node; -import org.hibernate.engine.SessionFactoryImplementor; /** * @author Steve Ebersole */ -public class EntityPersisterReference extends Node implements PersisterReference, SessionFactoryAwareNode { +public class EntityPersisterReference extends PersisterReference implements ResolverAware { private String entityName; private String alias; - private SessionFactoryImplementor sessionFactory; - private transient Queryable persister; - public EntityPersisterReference() { - super(); - super.setType( HqlRTokenTypes.ENTITY_PERSISTER_REF ); - } + private HqlResolver resolver; + private transient Queryable persister; + public void initialize(String entityName, String alias) { this.entityName = entityName; this.alias = alias; } - public Queryable getPersister() { + public Queryable getEntityPersister() { if ( persister == null ) { - persister = ( Queryable ) sessionFactory.getEntityPersister( entityName ); + persister = ( Queryable ) resolver.getSessionFactory().getEntityPersister( entityName ); } return persister; } public String getName() { - return alias == null ? entityName : entityName + " (" + alias + ")"; + return entityName; } public String getAlias() { @@ -41,34 +36,27 @@ } public AssociationType getPersisterType() { - return ( AssociationType ) persister.getType(); + return ( AssociationType ) getEntityPersister().getType(); } + public Type getPropertyType(String propertyName) { + return getEntityPersister().getPropertyType( propertyName ); + } + public boolean containsProperty(String propertyName) { try { - return persister.getPropertyType( propertyName ) != null; + return getPropertyType( propertyName ) != null; } catch( Throwable t ) { return false; } } - public PropertyReference retrievePropertyReference(String propertyName) { - return null; - } - - public String getDisplayText() { - return "{" + - "entityName='" + entityName + '\'' + - ", alias='" + alias + '\'' + - '}'; - } - public String toString() { - return "EntityPersisterReference" + getDisplayText(); + return "EntityPersisterReference {entity-name=" + entityName + ", alias=" + alias + "}"; } - public void setSessionFactory(SessionFactoryImplementor sessionFactory) { - this.sessionFactory = sessionFactory; + public void setHqlResolver(HqlResolver resolver) { + this.resolver = resolver; } } Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java 2006-05-02 11:07:06 UTC (rev 9850) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java 2006-05-02 14:26:06 UTC (rev 9851) @@ -1,128 +1,187 @@ package org.hibernate.hql.ast.resolve; import org.hibernate.hql.antlr.HqlBaseResolver; +import org.hibernate.hql.CollectionProperties; import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.QueryException; +import org.hibernate.type.Type; +import org.hibernate.type.ComponentType; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import java.util.List; -import java.util.ArrayList; import antlr.collections.AST; /** - * Implements the methods for the HqlBaseResolver. - * <br>User: Joshua Davis - * Date: Apr 1, 2006 - * Time: 7:40:42 AM + * Adds specific semantic action behavior needed to perform useful resolution. + * + * @author Joshua Davis + * @author Steve Ebersole */ public class HqlResolver extends HqlBaseResolver { private static Log log = LogFactory.getLog( HqlResolver.class ); private final SessionFactoryImplementor sessionFactory; - private final ResolverContext resolverContext; + private StatementNode currentStatement; - private int level = 0; - private List inputContext = new ArrayList(); - private List outputContext = new ArrayList(); - public HqlResolver(SessionFactoryImplementor sessionFactory) { super(); this.sessionFactory = sessionFactory; - setASTFactory( new HqlResolverASTFactory( sessionFactory ) ); - this.resolverContext = new ResolverContextImpl( sessionFactory, getASTFactory() ); + setASTFactory( new HqlResolverASTFactory( this ) ); } + public SessionFactoryImplementor getSessionFactory() { + return sessionFactory; + } - protected void pushContext(AST outputAst,AST inputAst) { - level++; - inputContext.add(inputAst); - outputContext.add(outputAst); - if (log.isDebugEnabled()) { - log.debug("Pushed context: level = " + level + " input is " + inputAst.toStringTree()); - } + public PersisterReferenceContext getPersisterReferenceContext() { + return currentStatement; } - protected void popContext() { - level--; - AST n = (AST)inputContext.remove(inputContext.size() - 1); - outputContext.remove(outputContext.size() - 1); - if (log.isDebugEnabled()) { - log.debug("Popped context: level = " + level + " input was " + n.toStringTree()); + protected void pushStatement(AST statementNode) { + log.trace( "pushing new statement context : " + currentStatement + " -> " + statementNode ); + StatementNode statement = ( StatementNode ) statementNode; + if ( currentStatement != null ) { + currentStatement.pushChild( statement ); } + currentStatement = statement; } - protected AST getCurrentContext(boolean input) { - return (AST)((input) ? inputContext.get(inputContext.size() - 1) - : outputContext.get(outputContext.size() - 1)); + protected void popStatement() { + log.trace( "popping statement context : " + currentStatement + " -> " + currentStatement.getParentStatement() ); + currentStatement = currentStatement.getParentStatement(); } - protected int getLevel() { return level; } - - protected void defineRange(AST range, String path, AST alias, AST fetch) { - RangeNode r = (RangeNode) range; - r.setPath(path); - r.setPersisterReference( resolverContext.getEntityPersisterReference( path, alias == null ? null : alias.getText() ) ); - r.setFetch(fetch != null); - r.setAlias(alias != null ? alias.getText() : null); - } - protected AST buildEntityPersisterReference(String entityName, AST alias) { - return resolverContext.getEntityPersisterReference( entityName, alias == null ? null : alias.getText() ); + return currentStatement.buildEntityPersisterReference( entityName, alias == null ? null : alias.getText() ); } - protected AST buildThetaJoinNode(AST persisterReference) { - JoinNode join = createJoinNode( JoinType.FULL, JoinSource.THETA, false ); - join.setFirstChild( persisterReference ); - return join; - } - - private JoinNode createJoinNode(JoinType type, JoinSource source, boolean fetch) { + private JoinNode createJoinNode(JoinType type, JoinSource source, boolean fetch, PersisterReference rhs) { JoinNode node = ( JoinNode ) getASTFactory().create( JOIN, "join" ); - node.initialize( type, source, fetch ); + node.initialize( type, source, fetch, rhs ); + rhs.addChild( node ); return node; } - protected AST buildExplicitPropertyJoinNode( - AST propertyReference, - AST alias, - AST joinType, - AST fetch, - AST propertyFetch, - AST withClause) { - JoinNode join = createJoinNode( resolveJoinType( joinType ), JoinSource.EXPLICIT, fetch != null ); - join.setFirstChild( propertyReference ); - if ( withClause != null ) { - join.addChild( withClause ); + /** + * Parser has recognized an explicit join based on a "property join". + * <p/> + * For example, something like: <tt>from Animal a join a.mother</tt> or + * <tt>from Animal a join a.mother.mother as gm</tt> or even + * <tt>from Animal join mother</tt> + * <p/> + * Here, we will need to resolve the explicit join, as well as handle any + * implied joins. + * </p> + * Note that any implicit joins here are handled rather differently than + * implicit joins in any clause other than an explicit join. See + * {@link #resolveCompoundPropertyReference} for the differences. Mainly, the + * differences are:<ul> + * </ul> + * + * @param propertyPath The property(s) being joined to, which may indicate + * additional implicit joins are intended. + * @param aliasNode The alias to be applied to the generated persister reference + * @param joinTypeNode The type of join indicated + * @param fetchNode Was relation fetching specified? + * @param propertyFetchNode Was property fetching specified? + * @param withClauseNode Any with clause. + */ + protected void handleExplicitPropertyJoin( + AST propertyPath, + AST aliasNode, + AST joinTypeNode, + AST fetchNode, + AST propertyFetchNode, + AST withClauseNode) { + JoinType joinType = resolveJoinType( joinTypeNode ); + String alias = aliasNode == null ? null : aliasNode.getText(); + boolean relationFetch = fetchNode != null; + boolean propertyFetch = propertyFetchNode != null; + + // propertyPath should be a "flattened" dot node structure, which always have at least one child + AST next = null; + String firstPathExpression = propertyPath.getFirstChild().getText(); + EntityPersisterReference root = resolveRootAsAlias( firstPathExpression ); + if ( root != null ) { + // the root of the path expression is an alias referencing a persister reference, + // so the alias itself has essentially been resolved already, so "consume it" + next = propertyPath.getFirstChild().getNextSibling(); } - return join; + else { + // otherwise, the expectation is that the root of the path expression is an + // unqualified property reference, in which case we essentially use the + // root as a look ahead, and now need to actually resolve it + root = resolveRootAsUnqualified( firstPathExpression ); + if ( root == null ) { + throw new QueryException( "unable to determine root of path expression [" + reconstitutePathString( propertyPath ) + "]" ); + } + next = propertyPath.getFirstChild(); + } + + // At this point, we know the persister which acts as the root or base (root) of the + // path structure (propertyPath), as well as the first actual path expression which + // needs resolving (next). So now, we need to start iterating all the path + // expressions and performing the resolutions. + PersisterReference lhs = root; + JoinSource joinSource = JoinSource.EXPLICIT; + boolean firstPass = true; + while ( next != null ) { + // todo : components? + boolean isLast = next.getNextSibling() == null; + + JoinNode joinNode = createJoinNode( joinType, joinSource, relationFetch, lhs ); + PersisterReference rhs = currentStatement.getPersisterReference( lhs, next.getText(), isLast ? alias : null ); + joinNode.addChild( rhs ); + + if ( isLast && withClauseNode != null ) { + joinNode.addChild( withClauseNode ); + } + + if ( firstPass ) { + firstPass = false; + joinSource = JoinSource.IMPLICIT; + } + + lhs = rhs; + next = next.getNextSibling(); + } + } - protected AST buildAdHocJoinNode(AST persisterReference, AST joinType, AST onClause) { - JoinNode join = createJoinNode( resolveJoinType( joinType ), JoinSource.AD_HOC, false ); + protected void handleAdHocJoinNode(AST persisterReference, AST joinType, AST onClause) { + // todo : need to be able to resolve the lhs join operand + EntityPersisterReference other = null; + JoinNode join = createJoinNode( resolveJoinType( joinType ), JoinSource.AD_HOC, false, other ); join.setFirstChild( persisterReference ); if ( onClause != null ) { join.addChild( onClause ); } - return join; } private JoinType resolveJoinType(AST joinType) { - if ( joinType.getType() == LEFT ) { - return JoinType.LEFT; + int joinTypeType = joinType == null ? INNER : joinType.getType(); + switch ( joinTypeType ) { + case INNER: + return JoinType.INNER; + case LEFT: + return JoinType.LEFT; + case RIGHT: + return JoinType.RIGHT; + case FULL: + return JoinType.FULL; } - else if ( joinType.getType() == RIGHT ) { - return JoinType.RIGHT; - } - else if ( joinType.getType() == FULL ) { - return JoinType.FULL; - } - else { - throw new QueryException( "Unrecognized join type [" + joinType.getText() + "]" ); - } + // if no match found, throw exception + throw new QueryException( "Unrecognized join type [" + joinType.getText() + "]" ); } + public PersisterReference buildPropertyJoin(PersisterReference source, String propertyName, String alias) { + JoinNode join = createJoinNode( JoinType.INNER, JoinSource.IMPLICIT, false, source ); + PersisterReference persisterReference = currentStatement.getPersisterReference( source, propertyName, alias ); + join.addChild( persisterReference ); + return persisterReference; + } + protected boolean isEntityName(String test) { try { return sessionFactory.getEntityPersister( test ) != null; @@ -133,4 +192,277 @@ return false; } + protected String reconstitutePathString(AST propertyReference) { + AST child = propertyReference.getFirstChild(); + String prefix = ""; + StringBuffer buffer = new StringBuffer(); + while ( child != null ) { + buffer.append( prefix ).append( child.getText() ); + prefix = "."; + child = child.getNextSibling(); + } + return buffer.toString(); + } + + protected AST resolveAtomicPropertyReference(AST propertyNode) { + EntityPersisterReference persisterReference = resolveRootAsUnqualified( propertyNode.getText() ); + return generatePropertyReference( persisterReference, propertyNode.getText() ); + } + + private PropertyReference generatePropertyReference(PersisterReference persisterReference, String propertyName) { + PropertyReference propertyReferenceNode = ( PropertyReference ) getASTFactory() + .create( PROPERTY_REF, persisterReference.getAlias() + "." + propertyName ); + + AST aliasNode = getASTFactory().create( ALIAS, persisterReference.getAlias() ); + propertyReferenceNode.addChild( aliasNode ); + + AST propertyNameNode = getASTFactory().create( IDENT, propertyName ); + propertyReferenceNode.addChild( propertyNameNode ); + + return propertyReferenceNode; + } + + protected AST resolveCompoundPropertyReference(AST dotStructure) { + PersisterReference persisterReference; + AST next; + + // first, resolve root origin + String firstPathExpression = dotStructure.getFirstChild().getText(); + if ( dotStructure.getNumberOfChildren() == 1 ) { + // can only really represent an unqualified simple property ref + EntityPersisterReference match = resolveRootAsUnqualified( firstPathExpression ); + if ( match == null ) { + throw new QueryException( "unable to resolve property [" + firstPathExpression + "] as unqualified reference" ); + } + persisterReference = match; + // the root of the path expression is an alias referencing a persister reference, + // so the alias itself has essentially been resolved already, so "consume it" + next = dotStructure.getFirstChild(); + } + else { + // need to decide whether 'firstPathExpression' refers to a from-clause alias, or + // an unqualified property name. from-clause alias has a higher precedence + // for matching purposes, so try to resolve as alias first + EntityPersisterReference match = resolveRootAsAlias( firstPathExpression ); + if ( match != null ) { + // the root of the path expression is an alias referencing a persister reference, + // so the alias itself has essentially been resolved already, so "consume it" + next = dotStructure.getFirstChild().getNextSibling(); + } + else { + // then try as unqualified + match = resolveRootAsUnqualified( firstPathExpression ); + if ( match != null ) { + // the root of the path expression is an unqualified property reference, + // in which case we essentially use the root as a look ahead, and now + // need to actually resolve it + next = dotStructure.getFirstChild(); + } + else { + throw new QueryException( "unable to determine root of path expression [" + reconstitutePathString( dotStructure ) + "]" ); + } + } + persisterReference = match; + } + + PropertyPathPart propertySource = new PropertyPathRoot( ( EntityPersisterReference ) persisterReference ); + String pathSoFar = persisterReference.getAlias(); + + while ( next != null && next.getNextSibling() != null ) { + String propertyName = next.getText(); + pathSoFar += ( "." + propertyName ); + + PersisterReference built = currentStatement.locatePersisterReferenceByPath( pathSoFar ); + if ( built != null ) { + propertySource = new PropertyPathRoot( ( EntityPersisterReference ) built ); + } + else { + propertySource = propertySource.handleIntermediatePathPart( propertyName ); + } + + next = next.getNextSibling(); + } + + if ( next == null ) { + throw new QueryException( "illegal parser state" ); + } + return propertySource.handleLeafPathPart( next.getText() ); + } + + private EntityPersisterReference resolveRootAsAlias(String firstPathExpression) { + return ( EntityPersisterReference ) currentStatement.locatePersisterReferenceByAlias( firstPathExpression ); + } + + private EntityPersisterReference resolveRootAsUnqualified(String firstPathExpression) { + return currentStatement.locatePersisterReferenceExposingProperty( firstPathExpression ); + } + + private PropertyPathPart determineAppropriatePartType(EntityPersisterReference origin, String propertyName) { + Type propertyType = origin.getPropertyType( propertyName ); + if ( propertyType.isComponentType() ) { + return new ComponentPropertyReference( origin, propertyName, ( ComponentType ) propertyType ); + } + else if ( propertyType.isEntityType() ) { + return new EntityPropertyReference( origin, propertyName, false ); + } + else if ( propertyType.isCollectionType() ) { + return new CollectionPropertyReference( origin, propertyName ); + } + else { + return new SimplePropertyReference( origin, propertyName ); + } + } + + private int locateComponentPropertyIndex(ComponentType componentType, String subPropertyName) { + String[] componentPropertyNames = componentType.getPropertyNames(); + for ( int i = 0; i < componentPropertyNames.length; i++ ) { + if ( componentPropertyNames[i].equals( subPropertyName ) ) { + return i; + } + } + throw new QueryException( "could not locate component property [" + subPropertyName + "]" ); + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // todo : this stuff needs to be finished up. + // specific things needing to be completed: + // (1) only dereference an actual entity association property into a + // join when it is further dereferenced (already handled) or when + // occuring in select clause + // (2) properly handle "collection properties" + // (3) properly handle components + // (4) properly handle index operations + // + // todo : look at utilizing this from handleExplicitPropertyJoin(...) also + + /** + * Contract for handling delegation for a particular portion of an implicit + * join structure (aka property path). + */ + private interface PropertyPathPart { + public PropertyPathPart handleIntermediatePathPart(String name); + public PropertyReference handleLeafPathPart(String name); + } + + private class PropertyPathRoot implements PropertyPathPart { + private final EntityPersisterReference persisterReference; + + public PropertyPathRoot(EntityPersisterReference persisterReference) { + this.persisterReference = persisterReference; + } + + public PropertyPathPart handleIntermediatePathPart(String name) { + return determineAppropriatePartType( persisterReference, name ); + } + + public PropertyReference handleLeafPathPart(String name) { + // todo : this really needs to consider whether a join might be needed + // based on the property type and type of clause + return generatePropertyReference( persisterReference, name ); + } + + } + + private class SimplePropertyReference implements PropertyPathPart { + private final EntityPersisterReference origin; + private final String propertyName; + + public SimplePropertyReference(EntityPersisterReference origin, String propertyName) { + this.origin = origin; + this.propertyName = propertyName; + } + + public PropertyPathPart handleIntermediatePathPart(String name) { + throw new QueryException( "cannot perform implicit join based on simple property" ); + } + + public PropertyReference handleLeafPathPart(String name) { + throw new QueryException( "cannot perform implicit join based on simple property" ); + } + } + + private class ComponentPropertyReference implements PropertyPathPart { + private final EntityPersisterReference origin; + private final String componentPropertyName; + private final ComponentType componentType; + + public ComponentPropertyReference(EntityPersisterReference origin, String componentPropertyName) { + this( origin, componentPropertyName, ( ComponentType ) origin.getPropertyType( componentPropertyName ) ); + } + + public ComponentPropertyReference(EntityPersisterReference origin, String componentPropertyName, ComponentType componentType) { + this.origin = origin; + this.componentPropertyName = componentPropertyName; + this.componentType = componentType; + } + + public PropertyPathPart handleIntermediatePathPart(String propertyName) { + int index = locateComponentPropertyIndex( componentType, propertyName ); + String path = buildDerefPath( propertyName ); + Type propertyType = componentType.getSubtypes()[index]; + if ( propertyType.isComponentType() ) { + return new ComponentPropertyReference( origin, path, ( ComponentType ) propertyType ); + } + else if ( propertyType.isEntityType() ) { + return new EntityPropertyReference( origin, path, false ); + } + else { + return new SimplePropertyReference( origin, path ); + } + } + + public PropertyReference handleLeafPathPart(String name) { + return generatePropertyReference( origin, buildDerefPath( name ) ); + } + + private String buildDerefPath(String subPropertyName) { + return componentPropertyName + "." + subPropertyName; + } + } + + private class EntityPropertyReference implements PropertyPathPart { + private final EntityPersisterReference origin; + private final String propertyName; + + private boolean joined; + + public EntityPropertyReference(EntityPersisterReference origin, String propertyName, boolean joined) { + this.origin = origin; + this.propertyName = propertyName; + this.joined = joined; + } + + public PropertyPathPart handleIntermediatePathPart(String name) { + EntityPersisterReference joinedPersister = ( EntityPersisterReference ) buildPropertyJoin( origin, propertyName, null ); + return determineAppropriatePartType( joinedPersister, name ); + } + + public PropertyReference handleLeafPathPart(String name) { + // not always needed (i.e. : .id) + EntityPersisterReference joinedPersister = ( EntityPersisterReference ) buildPropertyJoin( origin, propertyName, null ); + return generatePropertyReference( joinedPersister, name ); + } + } + + private class CollectionPropertyReference implements PropertyPathPart { + private final EntityPersisterReference origin; + private final String collectionPropertyName; + + public CollectionPropertyReference(EntityPersisterReference origin, String collectionPropertyName) { + this.origin = origin; + this.collectionPropertyName = collectionPropertyName; + } + + public PropertyPathPart handleIntermediatePathPart(String name) { + throw new QueryException( "illegal attempt to perform implicit join across collection property" ); + } + + public PropertyReference handleLeafPathPart(String name) { + if ( CollectionProperties.isAnyCollectionProperty( name ) ) { + CollectionPersisterReference joinedPersister = ( CollectionPersisterReference ) buildPropertyJoin( origin, collectionPropertyName, null ); + return generatePropertyReference( joinedPersister, name ); + } + throw new QueryException( "illegal attempt to perform implicit join across collection property" ); + } + } } Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java 2006-05-02 11:07:06 UTC (rev 9850) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java 2006-05-02 14:26:06 UTC (rev 9851) @@ -13,30 +13,33 @@ * Time: 7:58:16 AM */ public class HqlResolverASTFactory extends HqlASTFactory implements HqlRTokenTypes { - private final SessionFactoryImplementor factory; + private final HqlResolver resolver; - public HqlResolverASTFactory(SessionFactoryImplementor factory) { - this.factory = factory; + public HqlResolverASTFactory(HqlResolver resolver) { + this.resolver = resolver; } public Class getASTNodeType(int tokenType) { // Statement nodes: switch (tokenType) { - case QUERY : + case QUERY: + return SelectStatementNode.class; case UPDATE: + return UpdateStatementNode.class; case DELETE: + return DeleteStatementNode.class; case INSERT: - return StatementNode.class; - case RANGE: - return RangeNode.class; + return InsertStatementNode.class; case ENTITY_PERSISTER_REF: return EntityPersisterReference.class; case COLLECTION_PERSISTER_REF: return CollectionPersisterReference.class; case JOIN: return JoinNode.class; + case PROPERTY_REF: + return PropertyReference.class; } - return super.getASTNodeType(tokenType); + return super.getASTNodeType( tokenType ); } protected AST createUsingCtor(Token token, String string) { @@ -53,7 +56,10 @@ private void prepare(AST node) { if ( node instanceof SessionFactoryAwareNode ) { - ( ( SessionFactoryAwareNode ) node ).setSessionFactory( factory ); + ( ( SessionFactoryAwareNode ) node ).setSessionFactory( resolver.getSessionFactory() ); } + if ( node instanceof ResolverAware ) { + ( ( ResolverAware ) node ).setHqlResolver( resolver ); + } } } Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java 2006-05-02 11:07:06 UTC (rev 9850) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java 2006-05-02 14:26:06 UTC (rev 9851) @@ -20,19 +20,22 @@ private JoinType joinType; private JoinSource source; private boolean fetch; + private PersisterReference lhs; public JoinNode() { + super.setText( "join" ); } public JoinNode(Token tok) { super( tok ); + super.setText( "join" ); } - public void initialize(JoinType joinType, JoinSource source, boolean fetch) { + public void initialize(JoinType joinType, JoinSource source, boolean fetch, PersisterReference lhs) { this.joinType = joinType; this.source = source; this.fetch = fetch; - super.setText( "join" ); + this.lhs = lhs; } public JoinType getJoinType() { @@ -60,10 +63,10 @@ } public String getDisplayText() { - return "{" + "type=" + joinType + ", source=" + source + "fetch=" + fetch + "}"; + return "{" + "type=" + joinType + ", source=" + source + ", fetch=" + fetch + ", lhs=" + lhs.getAlias() + "}"; } public String toString() { - return "JoinNode" + getDisplayText(); + return "JoinNode " + getDisplayText(); } } Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java 2006-05-02 11:07:06 UTC (rev 9850) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java 2006-05-02 14:26:06 UTC (rev 9851) @@ -1,7 +1,8 @@ package org.hibernate.hql.ast.resolve; import org.hibernate.type.AssociationType; -import org.hibernate.hql.ast.tree.DisplayableNode; +import org.hibernate.type.Type; +import org.hibernate.hql.ast.tree.Node; /** * Represents a reference to a persister (either entity or collection) within @@ -9,11 +10,13 @@ * * @author Steve Ebersole */ -public interface PersisterReference extends DisplayableNode { - public String getName(); - public String getAlias(); - public AssociationType getPersisterType(); +public abstract class PersisterReference extends Node { + public abstract String getName(); + public abstract String getAlias(); + public abstract AssociationType getPersisterType(); + public abstract Type getPropertyType(String propertyName); - public boolean containsProperty(String propertyName); - public PropertyReference retrievePropertyReference(String propertyName); + public String getText() { + return getName() + " (" + getAlias() + ")"; + } } Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java 2006-05-02 11:07:06 UTC (rev 9850) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java 2006-05-02 14:26:06 UTC (rev 9851) @@ -1,16 +1,57 @@ package org.hibernate.hql.ast.resolve; import org.hibernate.type.Type; -import org.hibernate.hql.ast.tree.DisplayableNode; +import org.hibernate.hql.ast.tree.Node; /** - * Represents a reference to a particular persister-managed property; also - * some special cases such as a collection property reference (e.g., size). + * Represents a reference to a particular property. + * <p/> + * The sub-tree structure of this node is such that its first child is an ALIAS + * node representing an alias pointing to the specific persister reference from + * which the property reference originates. The other child is the property name, + * as an IDENT * * @author Steve Ebersole */ -public interface PropertyReference extends DisplayableNode { - public String getPropertyName(); - public Type getPropertyType(); - public PersisterReference getPersisterReference(); +public class PropertyReference extends Node implements ResolverAware { + + private HqlResolver resolver; + + // caches + private String alias; + private String propertyName; + private Type propertyType; + private PersisterReference origin; + + public String getPersisterReferenceAlias() { + if ( alias == null ) { + alias = getFirstChild().getText(); + } + return alias; + } + + public String getPropertyName() { + if ( propertyName == null ) { + propertyName = getFirstChild().getNextSibling().getText(); + } + return propertyName; + } + + public PersisterReference getPropertyOrigination() { + if ( origin == null ) { + origin = resolver.getPersisterReferenceContext().locatePersisterReferenceByAlias( getPersisterReferenceAlias() ); + } + return origin; + } + + public Type getPropertyType() { + if ( propertyType == null ) { + propertyType = getPropertyOrigination().getPropertyType( getPropertyName() ); + } + return propertyType; + } + + public void setHqlResolver(HqlResolver resolver) { + this.resolver = resolver; + } } Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/RangeNode.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/RangeNode.java 2006-05-02 11:07:06 UTC (rev 9850) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/RangeNode.java 2006-05-02 14:26:06 UTC (rev 9851) @@ -1,69 +0,0 @@ -package org.hibernate.hql.ast.resolve; - -import org.hibernate.hql.ast.tree.Node; -import org.hibernate.hql.ast.tree.DisplayableNode; - -/** - * Represents a "top-level" element in a FROM clause (e.g. "from Animal a"). These - * "top-level" nodes are then contained in a RANGE node within the FROM node. - * - * - * @author Joshua Davis - */ -public class RangeNode extends Node implements DisplayableNode { - // TODO : would like to remove this range concept; - // a "range" is really just a series of full joins (unless further - // qualified in the where-clause, in which case they'd become inner - // joins) specified using old "theta join" syntax from SQL, so - // represent them as join structures - private String path; - private String alias; - private EntityPersisterReference persisterReference; - private boolean fetch = false; - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public EntityPersisterReference getPersisterReference() { - return persisterReference; - } - - public void setPersisterReference(EntityPersisterReference persisterReference) { - this.persisterReference = persisterReference; - } - - public boolean isFetch() { - return fetch; - } - - public void setFetch(boolean fetch) { - this.fetch = fetch; - } - - public String getAlias() { - return alias; - } - - public void setAlias(String alias) { - this.alias = alias; - } - - - public String toString() { - return "RangeNode{" + - "path='" + path + '\'' + - ", alias='" + alias + '\'' + - ", reference=" + persisterReference + - ", fetch=" + fetch + - '}'; - } - - public String getDisplayText() { - return toString(); - } -} Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContext.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContext.java 2006-05-02 11:07:06 UTC (rev 9850) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContext.java 2006-05-02 14:26:06 UTC (rev 9851) @@ -1,19 +0,0 @@ -package org.hibernate.hql.ast.resolve; - -import org.hibernate.persister.entity.EntityPersister; - -import java.util.List; - -/** - * Looks up persisters and other things by name. - * <br>User: Joshua Davis - * Date: Apr 12, 2006 - * Time: 7:34:11 AM - */ -public interface ResolverContext { - public EntityPersister lookupPersister(String path); - public PersisterReference locatePersisterReferenceByAlias(String alias); - public List collectPersisterReferences(); - public EntityPersisterReference getEntityPersisterReference(String entityName, String alias); - public CollectionPersisterReference getCollectionPersisterReference(String collectionRole, String alias); -} Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContextImpl.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContextImpl.java 2006-05-02 11:07:06 UTC (rev 9850) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContextImpl.java 2006-05-02 14:26:06 UTC (rev 9851) @@ -1,74 +0,0 @@ -package org.hibernate.hql.ast.resolve; - -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.MappingException; -import org.hibernate.hql.antlr.HqlRTokenTypes; -import org.hibernate.persister.entity.EntityPersister; - -import java.util.Map; -import java.util.HashMap; -import java.util.List; -import java.util.ArrayList; -import java.util.Collections; - -import antlr.ASTFactory; - -/** - * Implements the resolver's context with a session factory. - * <br>User: Joshua Davis - * Date: Apr 12, 2006 - * Time: 7:35:31 AM - */ -public class ResolverContextImpl implements ResolverContext { - private Map persisterReferencesByAlias = new HashMap(); - private List persisterReferences = new ArrayList(); - private final SessionFactoryImplementor sessionFactory; - private final ASTFactory astFactory; - - public ResolverContextImpl(SessionFactoryImplementor sessionFactory, ASTFactory astFactory) { - this.sessionFactory = sessionFactory; - this.astFactory = astFactory; - } - - public EntityPersister lookupPersister(String name) { - // First, try to get the persister using the class name directly. - try { - return sessionFactory.getEntityPersister( name ); - } - catch ( MappingException ignore ) { - // unable to locate it using this name - } - - // If that didn't work, try using the 'import' name. - String importedClassName = sessionFactory.getImportedClassName( name ); - if ( importedClassName == null ) { - return null; - } - return sessionFactory.getEntityPersister( importedClassName ); - } - - public PersisterReference locatePersisterReferenceByAlias(String alias) { - return ( PersisterReference ) persisterReferencesByAlias.get( alias ); - } - - public List collectPersisterReferences() { - return Collections.unmodifiableList( persisterReferences ); - } - - public EntityPersisterReference getEntityPersisterReference(String entityName, String alias) { - EntityPersister persister = lookupPersister( entityName ); - EntityPersisterReference persisterReference = ( EntityPersisterReference ) astFactory.create( HqlRTokenTypes.ENTITY_PERSISTER_REF, persister.getEntityName() ); - persisterReference.initialize( persister.getEntityName(), alias ); - persisterReferences.add( persisterReference ); - if ( alias != null ) { - persisterReferencesByAlias.put( alias, persisterReference ); - } - return persisterReference; - } - - public CollectionPersisterReference getCollectionPersisterReference(String collectionRole, String alias) { - // TODO : implement; for now returns null... - return null; - } - -} Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/StatementNode.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/StatementNode.java 2006-05-02 11:07:06 UTC (rev 9850) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/StatementNode.java 2006-05-02 14:26:06 UTC (rev 9851) @@ -1,12 +1,220 @@ package org.hibernate.hql.ast.resolve; import org.hibernate.hql.ast.tree.Node; +import org.hibernate.hql.antlr.HqlRTokenTypes; +import org.hibernate.util.EmptyIterator; +import org.hibernate.QueryException; +import org.hibernate.MappingException; +import org.hibernate.type.Type; +import org.hibernate.type.EntityType; +import org.hibernate.type.CollectionType; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.engine.SessionFactoryImplementor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; + +import antlr.ASTFactory; + /** - * Represents a statement (SELECT, UPDATE, INSERT, DELETE) in the resolved HQL tree. - * <br>User: Joshua Davis - * Date: Apr 3, 2006 - * Time: 8:00:55 AM + * Base node class for hql statements (SELECT, DELETE, INSERT, UPDATE). + * + * @author Joshua Davis + * @author Steve Ebersole */ -public class StatementNode extends Node { +public abstract class StatementNode extends Node implements ResolverAware, PersisterReferenceContext { + + private static final Log log = LogFactory.getLog( StatementNode.class ); + + private StatementNode parentStatement; + private List childStatements; + private HqlResolver resolver; + + public StatementNode getParentStatement() { + return parentStatement; + } + + public Iterator iterateChildStatements() { + return childStatements == null ? EmptyIterator.INSTANCE : childStatements.iterator(); + } + + public void pushChild(StatementNode childStatement) { + childStatement.setParent( this ); + if ( childStatements == null ) { + childStatements = new ArrayList(); + } + childStatements.add( childStatement ); + } + + private void setParent(StatementNode parentStatement) { + if ( this.parentStatement != null ) { + throw new QueryException( "statement already had an associated parent" ); + } + this.parentStatement = parentStatement; + } + + public void setHqlResolver(HqlResolver resolver) { + this.resolver = resolver; + // todo : temp (see below) + this.sessionFactory = resolver.getSessionFactory(); + this.astFactory = resolver.getASTFactory(); + } + + + // todo : temp impl of PersisterReferenceContext ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // still need to handle hierarchical lookups as well as proper scoping rules between + // statement types + + private int unaliasedCount = 0; + private Map persisterReferencesByAlias = new HashMap(); + private Map persisterReferencesByPath = new HashMap(); + private List persisterReferences = new ArrayList(); + private SessionFactoryImplementor sessionFactory; + private ASTFactory astFactory; + + public EntityPersister lookupPersister(String name) { + // First, try to get the persister using the class name directly. + try { + return sessionFactory.getEntityPersister( name ); + } + catch ( MappingException ignore ) { + // unable to locate it using this name + } + + // If that didn't work, try using the 'import' name. + String importedClassName = sessionFactory.getImportedClassName( name ); + if ( importedClassName == null ) { + return null; + } + return sessionFactory.getEntityPersister( importedClassName ); + } + + public void registerPersisterReferenceAgainstPath(String path, PersisterReference persisterReference) { + if ( persisterReferencesByPath.containsKey( path ) ) { + throw new QueryException( "persister reference already registered for path [" + path + "]" ); + } + } + + public PersisterReference locatePersisterReferenceByPath(String path) { + return ( PersisterReference ) persisterReferencesByPath.get( path ); + } + + public PersisterReference locatePersisterReferenceByAlias(String alias) { + return ( PersisterReference ) persisterReferencesByAlias.get( alias ); + } + + public EntityPersisterReference locatePersisterReferenceExposingProperty(String firstPathExpression) { + log.trace( "trying to locate persister exposing property [" + firstPathExpression + "]" ); + EntityPersisterReference match = null; + Iterator itr = persisterReferences.iterator(); + while( itr.hasNext() ) { + final EntityPersisterReference test = ( EntityPersisterReference ) itr.next(); + if ( test.containsProperty( firstPathExpression ) ) { + if ( match != null ) { + throw new QueryException( "multiple referenced persisters contained property [" + firstPathExpression + "]" ); + } + match = test; + } + } + return match; + } + + public EntityPersisterReference buildEntityPersisterReference(String entityName, String alias) { + EntityPersister persister = lookupPersister( entityName ); + alias = determineAlias( alias ); + EntityPersisterReference persisterReference = ( EntityPersisterReference ) astFactory.create( HqlRTokenTypes.ENTITY_PERSISTER_REF, persister.getEntityName() ); + persisterReference.initialize( persister.getEntityName(), alias ); + persisterReferenceBuilt( alias, persisterReference ); + return persisterReference; + } + + private String determineAlias(String alias) { + if ( alias == null ) { + alias = "<gen:" + unaliasedCount++ + ">"; + } + return alias; + } + + public PersisterReference getPersisterReference(PersisterReference source, String propertyName, String alias) { + alias = determineAlias( alias ); + if ( source.getPersisterType().isEntityType() ) { + return buildPersisterReferenceFromEntity( ( EntityPersisterReference ) source, propertyName, alias ); + } + else { + return buildPersisterReferenceFromCollection( ( CollectionPersisterReference ) source, propertyName, alias ); + } + } + + private PersisterReference buildPersisterReferenceFromCollection( + CollectionPersisterReference collectionPersisterReference, + String propertyName, + String alias) { + // todo : we may need two different forms of CollectionPersisterReference, + // the distinction being which "properties" are available from each... + // (1) represents nodes built from explicit joins (properties from + // the underlying collection elements are available + // (2) represents nodes built from implicit joins (only + // "collection properties" are available (size, index, etc) + return null; + } + + private PersisterReference buildPersisterReferenceFromEntity( + EntityPersisterReference source, + String propertyName, + String alias ) { + Type type = null; + PersisterReference ref = null; + try { + type = source.getEntityPersister().getPropertyType( propertyName ); + } + catch( Throwable t ) { + throw new QueryException( "could not resolve property [" + propertyName + "] on " + source.getEntityPersister().getEntityName() ); + } + + if ( type.isEntityType() ) { + EntityType entityType = ( EntityType ) type; + EntityPersisterReference entityPersisterReference = ( EntityPersisterReference ) + astFactory.create( HqlRTokenTypes.ENTITY_PERSISTER_REF, entityType.getAssociatedEntityName() ); + entityPersisterReference.initialize( entityType.getAssociatedEntityName(), alias ); + ref = entityPersisterReference; + } + else if ( type.isCollectionType() ) { + CollectionType collectionType = ( CollectionType ) type; + CollectionPersisterReference collectionPersisterReference = ( CollectionPersisterReference ) + astFactory.create( HqlRTokenTypes.COLLECTION_PERSISTER_REF, "" ); + collectionPersisterReference.initialize( collectionType.getRole(), alias ); + ref = collectionPersisterReference; + } + else { + throw new QueryException( + "cannot dereference property [" + propertyName + + "] from persister [" + source.getEntityPersister().getEntityName() + + "] as part of path expression" + ); + } + + persisterReferenceBuilt( alias, ref ); + return ref; + } + + private void persisterReferenceBuilt(String alias, PersisterReference reference) { + persisterReferen... [truncated message content] |
Author: max...@jb... Date: 2006-05-02 07:07:06 -0400 (Tue, 02 May 2006) New Revision: 9850 Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashEquals.hbm.xml trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashcodeEqualsTest.java trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Group.java trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/ManyToManyTest.java trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/User.java trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/UserGroup.hbm.xml Modified: trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/pojo/BasicPOJOClass.java Log: HBX-652 generated equals method doesn't work with byte[] + Initial many-to-many tests Modified: trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/pojo/BasicPOJOClass.java =================================================================== --- trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/pojo/BasicPOJOClass.java 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/pojo/BasicPOJOClass.java 2006-05-02 11:07:06 UTC (rev 9850) @@ -251,10 +251,12 @@ else { if(useCompareTo( typeName )) { return "( (" + lh + "==" + rh + ") || ( " + lh + "!=null && " + rh + "!=null && " + lh + ".compareTo(" + rh + ")==0 ) )"; - } else if ( c2j.isArray( typeName ) ) { - return "( java.util.Arrays.equals(" + lh + "," + rh + ") )"; } else { - return "( (" + lh + "==" + rh + ") || ( " + lh + "!=null && " + rh + "!=null && " + lh + ".equals(" + rh + ") ) )"; + if(typeName.endsWith("[]")) { + return "( (" + lh + "==" + rh + ") || ( " + lh + "!=null && " + rh + "!=null && " + importType("java.util.Arrays") + ".equals(" + lh + ", " + rh + ") ) )"; + } else { + return "( (" + lh + "==" + rh + ") || ( " + lh + "!=null && " + rh + "!=null && " + lh + ".equals(" + rh + ") ) )"; + } } } @@ -568,32 +570,16 @@ } } - public String generateHashCode(Property property, String result, String thisName, boolean useGenerics) { + public String generateHashCode(Property property, String result, String thisName, boolean jdk5) { StringBuffer buf = new StringBuffer(); if ( c2j.getMetaAsBool( property, "use-in-equals" ) ) { - String javaTypeName = c2j.getJavaTypeName( property, useGenerics, this ); + String javaTypeName = c2j.getJavaTypeName( property, jdk5, this ); boolean isPrimitive = c2j.isPrimitive( javaTypeName ); - if ( !isPrimitive ) { + if ( isPrimitive ) { buf.append( result ) .append( " = 37 * " ) .append( result ) .append( " + " ); - buf.append( "( " ) - .append( getGetterSignature( property ) ) - .append( "() == null ? 0 : " ) - .append( thisName ) - .append( "." ) - .append( getGetterSignature( property ) ) - .append( "()" ) - .append( ".hashCode()" ) - .append( " )" ) - .append(";"); - } - else { - buf.append( result ) - .append( " = 37 * " ) - .append( result ) - .append( " + " ); String thisValue = thisName + "." + getGetterSignature( property ) + "()"; if("char".equals(javaTypeName)||"int".equals(javaTypeName)||"short".equals(javaTypeName)||"byte".equals(javaTypeName)) { buf.append( thisValue ); @@ -605,10 +591,170 @@ } buf.append(";"); } + else { + if(javaTypeName.endsWith("[]")) { + if(jdk5) { + buf.append( result ) + .append( " = 37 * " ) + .append( result ) + .append( " + " ); + buf.append( "( " ) + .append( getGetterSignature( property ) ) + .append( "() == null ? 0 : " + importType("java.util.Arrays") + ".hashCode(" ) + .append( thisName ) + .append( "." ) + .append( getGetterSignature( property ) ) + .append( "())" ) + .append( " )" ) + .append(";"); + } + else { + buf.append(internalGenerateArrayHashcode(property, javaTypeName, result, thisName)); + } + } else { + buf.append( result ) + .append( " = 37 * " ) + .append( result ) + .append( " + " ); + buf.append( "( " ) + .append( getGetterSignature( property ) ) + .append( "() == null ? 0 : " ) + .append( thisName ) + .append( "." ) + .append( getGetterSignature( property ) ) + .append( "()" ) + .append( ".hashCode()" ) + .append( " )" ) + .append(";"); + } + } } return buf.toString(); } + + private String internalGenerateArrayHashcode(Property property, String javaTypeName, String result, String thisName) + { + StringBuffer buf = new StringBuffer(); + + String propertyHashVarName = property.getName() + "Hashcode"; + String propertyArrayName = property.getName() + "Property"; + +// int propertyHash = 0; + buf.append( "int ") + .append( propertyHashVarName ) + .append( " = 0;\n" ); + +// type[] proterty = getProperty(); + buf.append( " " ) + .append( javaTypeName ) + .append( " " ) + .append( propertyArrayName ) + .append( " = " ) + .append( thisName ) + .append( "." ) + .append( getGetterSignature( property ) ) + .append( "();\n"); + +// if(property != null) { + buf.append( " if(" ) + .append( propertyArrayName ) + .append( " != null) {\n" ); + +// propertyHash = 1; + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 1;\n" ); + +// for (int i=0; i<property.length; i++) + String elementType = javaTypeName.replaceAll("\\[\\]", ""); + buf.append( " for (int i=0; i<" ) + .append( propertyArrayName ) + .append( ".length; i++) {\n" ); + + if(javaTypeName.startsWith("long")) { +// int elementHash = (int)(propertyArray[i] ^ (propertyArray[i] >>> 32)); + buf.append( " int elementHash = (int)(" ) + .append( propertyArrayName ) + .append( "[i] ^ (" ) + .append( propertyArrayName ) + .append( "[i] >>> 32));\n" ); + +// propertyHash = 37 * propertyHash + elementHash; + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 37 * " ) + .append( propertyHashVarName ) + .append( " + elementHash;\n" ); + } else if(javaTypeName.startsWith("boolean")) { +// propertyHash = 37 * propertyHash + (propertyArray[i] ? 1231 : 1237); + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 37 * " ) + .append( propertyHashVarName ) + .append( " + (" ) + .append( propertyArrayName ) + .append( "[i] ? 1231 : 1237);\n" ); + } else if(javaTypeName.startsWith("float")) { +// propertyHash = 37 * propertyHash + Float.floatToIntBits(propertyArray[i]); + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 37 * " ) + .append( propertyHashVarName ) + .append( " + Float.floatToIntBits(" ) + .append( propertyArrayName ) + .append( "[i]);\n" ); + } else if(javaTypeName.startsWith("double")) { +// long bits = Double.doubleToLongBits(propertyArray[i]); + buf.append( " long bits = Double.doubleToLongBits(" ) + .append( propertyArrayName ) + .append( "[i]);\n" ); + +// propertyHash = 37 * propertyHash + (int)(bits ^ (bits >>> 32)); + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 37 * " ) + .append( propertyHashVarName ) + .append( " + (int)(bits ^ (bits >>> 32));\n" ); + } else if(javaTypeName.startsWith("int") + || javaTypeName.startsWith("short") + || javaTypeName.startsWith("char") + || javaTypeName.startsWith("byte")) { +// propertyHash = 37 * propertyHash + propertyArray[i]; + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 37 * " ) + .append( propertyHashVarName ) + .append( " + " ) + .append( propertyArrayName ) + .append( "[i];\n" ); + } else {// Object[] +// propertyHash = 37 * propertyHash + propertyArray[i].hashCode(); + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 37 * " ) + .append( propertyHashVarName ) + .append( " + " ) + .append( propertyArrayName ) + .append( "[i].hashCode();\n" ); + } + + buf.append( " }\n" ); + buf.append( " }\n\n" ); + +// result = 37 * result + arrayHashcode; + buf.append( " " ) + .append( result ) + .append( " = 37 * " ) + .append( result ) + .append( " + " ) + .append( propertyHashVarName ) + .append( ";\n" ); + + return buf.toString(); + } + + public String getFieldModifiers(Property property) { return getModifiers( property, "scope-field", "private" ); } Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashEquals.hbm.xml =================================================================== --- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashEquals.hbm.xml 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashEquals.hbm.xml 2006-05-02 11:07:06 UTC (rev 9850) @@ -0,0 +1,55 @@ +<?xml version="1.0"?> +<!DOCTYPE hibernate-mapping PUBLIC + "-//Hibernate/Hibernate Mapping DTD 3.0//EN" + "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> + +<!-- + + This mapping demonstrates how to map a collection + <key> to one of the primary key columns of an + associated child class with a composite key. This + is very useful for legacy data! + +--> + +<hibernate-mapping package="org.hibernate.tool.hbm2x"> + + <class name="HashEquals"> + <!-- Normally *bad* practice to put global use-in-equals. Only here for testing --> + <meta attribute="use-in-equals">true</meta> + <id name="id" type="string"/> + + <property name="name" type="java.lang.String[]"/> + <property name="byteArray" type="byte[]"/> + <property name="floatArray" type="float[]"/> + <property name="intArray" type="int[]"/> + <property name="shortArray" type="int[]"/> + <property name="booleanArray" type="boolean[]"/> + + <component name="addressComponent" class="Address"> + <property name="streetAddress1" type="string" + column="StreetAddress1" not-null="true"> + <meta attribute="use-in-equals">true</meta> + </property> + <property name="streetAddress2" type="string" + column="StreetAddress2" /> + <property name="city" type="short" column="City" + not-null="true"> + <meta attribute="use-in-tostring">true</meta> + <meta attribute="use-in-equals">true</meta> + <meta attribute="property-type">short</meta> + </property> + <property name="postcode" type="java.lang.String[]" column="postcode" + not-null="true" /> + <!-- <many-to-one name="state" class="au.com.groupware.model.State" column="StateId" + foreign-key="FK_Address_State" not-null="true" /> --> + <property name="verified" type="boolean"> + <meta attribute="use-in-equals">true</meta> + </property> + </component> + + + </class> + + +</hibernate-mapping> Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashcodeEqualsTest.java =================================================================== --- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashcodeEqualsTest.java 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashcodeEqualsTest.java 2006-05-02 11:07:06 UTC (rev 9850) @@ -0,0 +1,112 @@ +/* + * Created on 2004-12-01 + * + */ +package org.hibernate.tool.hbm2x; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.hibernate.mapping.Component; +import org.hibernate.mapping.MetaAttribute; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.mapping.Property; +import org.hibernate.mapping.RootClass; +import org.hibernate.mapping.SingleTableSubclass; +import org.hibernate.mapping.Value; +import org.hibernate.tool.NonReflectiveTestCase; +import org.hibernate.tool.hbm2x.pojo.BasicPOJOClass; +import org.hibernate.tool.hbm2x.pojo.ImportContext; +import org.hibernate.tool.hbm2x.pojo.ImportContextImpl; +import org.hibernate.tool.hbm2x.pojo.NoopImportContext; +import org.hibernate.tool.hbm2x.pojo.POJOClass; +import org.hibernate.tool.test.TestHelper; + +/** + * @author max + * + */ +public class HashcodeEqualsTest extends NonReflectiveTestCase { + + private ArtifactCollector artifactCollector; + + public HashcodeEqualsTest(String name) { + super( name, "hashcodeequals" ); + } + + protected void tearDown() throws Exception { + // TODO Auto-generated method stub + // super.tearDown(); + } + protected void setUp() throws Exception { + super.setUp(); + + Exporter exporter = new POJOExporter( getCfg(), getOutputDir() ); + artifactCollector = new ArtifactCollector(); + exporter.setArtifactCollector(artifactCollector); + exporter.start(); + } + + + public void testJDK5FailureExpectedOnJDK4() { + + POJOExporter exporter = new POJOExporter( getCfg(), getOutputDir() ); + exporter.getProperties().setProperty("jdk5", "true"); + + artifactCollector = new ArtifactCollector(); + exporter.setArtifactCollector(artifactCollector); + exporter.start(); + + testFileExistence(); + testNoVelocityLeftOvers(); + testCompilable(); + + } + + + public void testFileExistence() { + + assertFileAndExists( new File( getOutputDir(), + "org/hibernate/tool/hbm2x/HashEquals.java" ) ); + assertFileAndExists( new File( getOutputDir(), + "org/hibernate/tool/hbm2x/Address.java" ) ); + + assertEquals(2, artifactCollector.getFileCount("java")); + } + + public void testCompilable() { + + File file = new File( "compilable" ); + file.mkdir(); + + ArrayList list = new ArrayList(); + TestHelper.compile( getOutputDir(), file, TestHelper.visitAllFiles( + getOutputDir(), list ) ); + + TestHelper.deleteDir( file ); + } + + + + public void testNoVelocityLeftOvers() { + + assertEquals( null, findFirstString( "$", new File( getOutputDir(), + "org/hibernate/tool/hbm2x/HashEquals.java" ) ) ); + assertEquals( null, findFirstString( "$", new File( getOutputDir(), + "org/hibernate/tool/hbm2x/Address.java" ) ) ); + + } + + protected String getBaseForMappings() { + return "org/hibernate/tool/hbm2x/"; + } + + protected String[] getMappings() { + return new String[] { "HashEquals.hbm.xml" }; + } + +} Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Group.java =================================================================== --- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Group.java 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Group.java 2006-05-02 11:07:06 UTC (rev 9850) @@ -0,0 +1,56 @@ +//$Id: Group.java 7085 2005-06-08 17:59:47Z oneovthafew $ +package org.hibernate.tool.hbm2x.hbm2hbmxml; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +public class Group implements Serializable { + + private String org; + private String name; + private String description; + + private Set users = new HashSet(); + + public Group(String name, String org) { + this.org = org; + this.name = name; + } + + public Group() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getOrg() { + return org; + } + + public void setOrg(String org) { + this.org = org; + } + + public Set getUsers() { + return users; + } + + public void setUsers(Set users) { + this.users = users; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/ManyToManyTest.java =================================================================== --- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/ManyToManyTest.java 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/ManyToManyTest.java 2006-05-02 11:07:06 UTC (rev 9850) @@ -0,0 +1,86 @@ +//$Id$ + +/* + * Tests for generating the HBM documents from the Configuration data structure. + * The generated XML document will be validated and queried to make sure the + * basic structure is correct in each test. + */ +package org.hibernate.tool.hbm2x.hbm2hbmxml; + +import java.io.File; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.dom4j.io.SAXReader; +import org.hibernate.cfg.Configuration; +import org.hibernate.tool.NonReflectiveTestCase; +import org.hibernate.tool.hbm2x.Exporter; +import org.hibernate.tool.hbm2x.HibernateMappingExporter; +import org.hibernate.util.DTDEntityResolver; + +public class ManyToManyTest extends NonReflectiveTestCase { + + private Exporter hbmexporter; + + public ManyToManyTest(String name) { + super( name, "cfg2hbmoutput" ); + } + + protected void setUp() throws Exception { + super.setUp(); + + hbmexporter = new HibernateMappingExporter(getCfg(), getOutputDir() ); + hbmexporter.start(); + } + + public void testAllFilesExistence() { + + assertFalse(new File(getOutputDir().getAbsolutePath() + "/GeneralHbmSettings.hbm.xml").exists() ); + assertFileAndExists(new File(getOutputDir().getAbsolutePath() + "/org/hibernate/tool/hbm2x/hbm2hbmxml/User.hbm.xml") ); + assertFileAndExists(new File(getOutputDir().getAbsolutePath() + "/org/hibernate/tool/hbm2x/hbm2hbmxml/Group.hbm.xml") ); + } + + public void testArtifactCollection() { + + assertEquals(2,hbmexporter.getArtifactCollector().getFileCount("hbm.xml")); + + } + + public void testReadable() { + Configuration cfg = new Configuration(); + + cfg.addFile(new File(getOutputDir(), getBaseForMappings() + "User.hbm.xml")); + cfg.addFile(new File(getOutputDir(), getBaseForMappings() + "Group.hbm.xml")); + + cfg.buildMappings(); + + } + + protected void tearDown() throws Exception { + // TODO Auto-generated method stub + // super.tearDown(); + } + + private SAXReader getSAXReader() { + SAXReader xmlReader = new SAXReader(); + xmlReader.setEntityResolver(new DTDEntityResolver() ); + xmlReader.setValidation(true); + return xmlReader; + } + + protected String getBaseForMappings() { + return "org/hibernate/tool/hbm2x/hbm2hbmxml/"; + } + + protected String[] getMappings() { + return new String[] { + "UserGroup.hbm.xml" + }; + } + + public static Test suite() { + return new TestSuite(ManyToManyTest.class); + } + +} Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/User.java =================================================================== --- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/User.java 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/User.java 2006-05-02 11:07:06 UTC (rev 9850) @@ -0,0 +1,46 @@ +//$Id: User.java 7085 2005-06-08 17:59:47Z oneovthafew $ +package org.hibernate.tool.hbm2x.hbm2hbmxml; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +public class User implements Serializable { + + private String org; + private String name; + private Set groups = new HashSet(); + + public User(String name, String org) { + this.org = org; + this.name = name; + } + + public User() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getOrg() { + return org; + } + + public void setOrg(String org) { + this.org = org; + } + + public Set getGroups() { + return groups; + } + + public void setGroups(Set groups) { + this.groups = groups; + } + +} Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/UserGroup.hbm.xml =================================================================== --- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/UserGroup.hbm.xml 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/UserGroup.hbm.xml 2006-05-02 11:07:06 UTC (rev 9850) @@ -0,0 +1,52 @@ +<?xml version="1.0"?> +<!DOCTYPE hibernate-mapping PUBLIC + "-//Hibernate/Hibernate Mapping DTD 3.0//EN" + "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> + +<!-- + + This mapping demonstrates how to map a many-to-many + association with a shared attribute in the primary keys + of the associated entities. + +--> + +<hibernate-mapping + package="org.hibernate.tool.hbm2x.hbm2hbmxml"> + + <class name="User" table="`User`"> + <composite-id> + <key-property name="name"/> + <key-property name="org"/> + </composite-id> + <set name="groups" table="UserGroup"> + <key> + <column name="userName"/> + <column name="org"/> + </key> + <many-to-many class="Group"> + <column name="groupName"/> + <formula>org</formula> + </many-to-many> + </set> + </class> + + <class name="Group" table="`Group`"> + <composite-id> + <key-property name="name"/> + <key-property name="org"/> + </composite-id> + <property name="description"/> + <set name="users" table="UserGroup" inverse="true"> + <key> + <column name="groupName"/> + <column name="org"/> + </key> + <many-to-many class="User"> + <column name="userName"/> + <formula>org</formula> + </many-to-many> + </set> + </class> + +</hibernate-mapping> |
From: <hib...@li...> - 2006-05-02 11:06:24
|
Author: max...@jb... Date: 2006-05-02 07:06:09 -0400 (Tue, 02 May 2006) New Revision: 9849 Modified: trunk/HibernateExt/tools/doc/reference/en/modules/ant.xml trunk/HibernateExt/tools/doc/reference/en/modules/reverseengineering.xml Log: noop Modified: trunk/HibernateExt/tools/doc/reference/en/modules/ant.xml =================================================================== --- trunk/HibernateExt/tools/doc/reference/en/modules/ant.xml 2006-05-02 03:21:21 UTC (rev 9848) +++ trunk/HibernateExt/tools/doc/reference/en/modules/ant.xml 2006-05-02 11:06:09 UTC (rev 9849) @@ -37,8 +37,7 @@ hibernate tools dependencies as well as the jdbc driver.</para> <para>Notice that to use the annotation based Configuration you must get - a release from <link - linkend="???">http://annotations.hibernate.org</link>.</para> + a release from http://annotations.hibernate.org.</para> <para></para> @@ -51,11 +50,13 @@ <area coords="3 55" id="ht2" /> - <area coords="5 55" id="ht3" /> + <area coords="4 55" id="ht3" /> <area coords="7 55" id="ht4" /> - <area coords="9 55" id="config" /> + <area coords="8 55" id="ht5" /> + + <area coords="10 55" id="ht6" /> </areaspec> <programlisting><![CDATA[<hibernatetool @@ -72,7 +73,7 @@ <calloutlist> <callout arearefs="ht1"> - <para><literal>destdir</literal> (requiredl): destination + <para><literal>destdir</literal> (required): destination directory for files generated with exporters.</para> </callout> @@ -94,12 +95,12 @@ providing custom properties to user defined templates.</para> </callout> - <callout arearefs="config"> + <callout arearefs="ht5"> <para>One of 4 different ways of configuring the Hibernate Meta Model must be specified.</para> </callout> - <callout arearefs="???"> + <callout arearefs="ht6"> <para>One or more of the exporters must be specified</para> </callout> </calloutlist> @@ -184,7 +185,7 @@ <area coords="5 55" id="cfg4" /> - <area coords="6 55" id="cfg5" /> + <area coords="7 55" id="cfg5" /> </areaspec> <programlisting><![CDATA[<configuration @@ -338,23 +339,24 @@ <title>JDBC Configuration for reverse engineering (<jdbcconfiguration>)</title> - <para>A <jdbcconfiguration> is used to perform reverse - engineering of the database from a JDBC connection.</para> + <para>A <literal><jdbcconfiguration></literal> is used to + perform reverse engineering of the database from a JDBC + connection.</para> <para>This configuration works by reading the connection properties from</para> - <para>The <jdbcconfiguration> has the same attributes as a - <configuration> plus the following additional attributes:</para> + <para>The <literal><jdbcconfiguration></literal> has the same + attributes as a <literal><configuration></literal> plus the + following additional attributes:</para> <para><programlistingco> <areaspec> - <area coords="4 57" id="xcfg1" /> + <area coords="3 57" id="xcfg1" /> - <area coords="5 57" id="xcfg2" /> + <area coords="4 57" id="xcfg2" /> - <area coords="6 57" id="xcfg3" /> - + <area coords="5 57" id="xcfg3" /> </areaspec> <programlisting><![CDATA[<jdbcconfiguration Modified: trunk/HibernateExt/tools/doc/reference/en/modules/reverseengineering.xml =================================================================== --- trunk/HibernateExt/tools/doc/reference/en/modules/reverseengineering.xml 2006-05-02 03:21:21 UTC (rev 9848) +++ trunk/HibernateExt/tools/doc/reference/en/modules/reverseengineering.xml 2006-05-02 11:06:09 UTC (rev 9849) @@ -31,13 +31,16 @@ <para>To have fine control over the process a hibernate.reveng.xml file can be provided. In this file you can specify type mappings and table - filtering. This file can be created by hand (its just basic XML) or - you</para> + filtering. This file can be created by hand (its just basic XML) or you + can use the Hibernate plugins which have a specialized editor.</para> - <para>can use the Hibernate plugins which have a specialized - editor.</para> + <para>Note: many databases is case-sensitive with their names and thus if + you cannot make some table match and you are sure it is not excluded by a + <table-filter> then check if the case matches; most databases stores + table names in uppercase.</para> - <para>The following is an example of such a file.</para> + <para>The following is an example of a reveng.xml. Following the example + is more details about the format.</para> <programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-reverse-engineering @@ -45,7 +48,6 @@ <hibernate-reverse-engineering> -<schema-selection <type-mapping> <!-- jdbc-type is name fom java.sql.Types --> <sql-type jdbc-type="VARCHAR" length='20' hibernate-type="SomeUserType" /> @@ -394,10 +396,7 @@ configuration on how a table should be reverse engineered. Amongst other things it allow control over the naming of a class for the table, specify which identifier generator should be used for the primary key - etc. Note: many databases is case-sensitive with their names and thus if - you cannot make the table match and you are sure it is not excluded by a - <table-filter> then check if the case matches; most databases - stores table names in uppercase.</para> + etc.</para> <programlistingco> <areaspec> @@ -427,7 +426,7 @@ </callout> <callout arearefs="tablefilter-matchschema"> - <para>schema (Optionl): Schema name for table</para> + <para>schema (Optional): Schema name for table</para> </callout> <callout arearefs="tablefilter-matchname"> @@ -436,7 +435,7 @@ <callout arearefs="tablefilter-exclude"> <para>clase (Optional): The class name for table. Default name is - camelcase version of the table name. </para> + camelcase version of the table name.</para> </callout> </calloutlist> </programlistingco> @@ -444,43 +443,200 @@ <section> <title><primary-key></title> - <para></para> + <para>A <literal><primary-key></literal> allows you to define a + primary-key for tables that does not have such defined in the + database, and probably more importantly it allows you to define which + identifier strategy that should be used (even for already existing + primary-key's).</para> - <programlisting><![CDATA[<primary-key + <programlistingco> + <areaspec> + <area coords="2 55" id="pk-generatorclass" /> + + <area coords="3 55" id="pk-generatorparam" /> + + <area coords="5 55" id="pk-keycolumn" /> + </areaspec> + + <programlisting><![CDATA[<primary-key <generator class="generatorname"> <param name="param_name">parameter value</param> </generator> <key-column...> </primary-key>]]></programlisting> + + <calloutlist> + <callout arearefs="pk-generatorclass"> + <para>generator/class (Optional): defines which identifier + generator should be used. The class name is any hibernate short + hand name or fully quailfied class name for an identifier + strategy.</para> + </callout> + + <callout arearefs="pk-generatorparam"> + <para>generator/param (Optional): Allows to specify which + parameter with name and value should be passed to the identifier + generator</para> + </callout> + + <callout arearefs="pk-keycolumn"> + <para>key-column (Optional): Specifies which column(s ) the + primary-key consists of. A key-column is same as column, but + does not have the exclude property.</para> + </callout> + </calloutlist> + </programlistingco> </section> <section> <title><column></title> - <para></para> + <para>With a <column> it is possible to explicitly name the + resulting property for a column. It is also possible to redefine what + jdbc and/or hibernate type a column should be processed and finally it + is possible to completely exclude a column from processing.</para> - <programlisting><![CDATA[<column + <para><programlistingco> + <areaspec> + <area coords="2 55" id="column-name" /> + + <area coords="3 55" id="column-jdbctype" /> + + <area coords="4 55" id="column-type" /> + + <area coords="5 55" id="column-propertytype" /> + + <area coords="6 55" id="column-exclude" /> + </areaspec> + + <programlisting><![CDATA[<column name="column_name" jdbc-type="java.sql.Types type" type="hibernate_type" property="propertyName" exclude="true|false" />]]></programlisting> + + <calloutlist> + <callout arearefs="column-name"> + <para>name (Required): Column name</para> + </callout> + + <callout arearefs="column-jdbctype"> + <para>jdbc-type (Optional): Which jdbc-type this column should + be processed as. A value from java.sql.Types, either numerical + (93) or the constant name (TIMESTAMP).</para> + </callout> + + <callout arearefs="column-type"> + <para>type (Optional): Which hibernate-type to use for this + specific column.</para> + </callout> + + <callout arearefs="column-propertytype"> + <para>property (Optional): What property name will be + generated for this column.</para> + </callout> + + <callout arearefs="column-exclude"> + <para>exclude (default: false): set to true if this column + should be ignored.</para> + </callout> + </calloutlist> + </programlistingco></para> </section> <section> <title><foreign-key></title> - <para></para> + <para>The <foreign-key> has two purposes. One for allowing to + define foreign-keys in databases that does not support them or does + not have them defined in their schema. Secondly, to allow defining the + name of the resulting properties (many-to-one and + one-to-many's).</para> - <programlisting><![CDATA[<foreign-key + <para>Note</para> + + <para><programlistingco> + <areaspec> + <area coords="2 55" id="foreignkey-name" /> + + <area coords="3 55" id="foreignkey-catalog" /> + + <area coords="4 55" id="foreignkey-schema" /> + + <area coords="5 55" id="foreignkey-table" /> + + <area coords="7 55" id="foreignkey-columnref" /> + + <area coords="8 55" id="foreignkey-manytoone" /> + + <area coords="10 55" id="foreignkey-set" /> + </areaspec> + + <programlisting><![CDATA[<foreign-key constraint-name="foreignKeyName" foreign-catalog="catalogName" foreign-schema="schemaName" foreign-table="tableName" > <column-ref local-column="columnName" foreign-column="foreignColumnName"/> + <many-to-one + property="aPropertyName" + exclude="true|false"/> + <set + property="aCollectionName" + exclude="true|false"/> </foreign-key>]]></programlisting> + + <calloutlist> + <callout arearefs="foreignkey-name"> + <para>constraint-name (Required): Name of the foreign key + constraint. Important when naming many-to-one and set. It is + the constraint-name that is used to link the processed + foreign-keys with the resulting property names.</para> + </callout> + + <callout arearefs="foreignkey-catalog"> + <para>foreign-catalog (Optional): Name of the foreign table's + catalog. (Only relevant if you want to explicitly define a + foreign key)</para> + </callout> + + <callout arearefs="foreignkey-schema"> + <para>foreign-schema (Optional): Name of the foreign table's + schema. (Only relevant if you want to explicitly define a + foreign key)</para> + </callout> + + <callout arearefs="foreignkey-table"> + <para>foreign-table (Optional): Name of the foreign table. + (Only relevant if you want to explicitly define a foreign + key)</para> + </callout> + + <callout arearefs="foreignkey-columnref"> + <para>column-ref (Optional): Defines that the foreign-key + constraint between a local-column and foreign-column name. + (Only relevant if you want to explicitly define a foreign + key)</para> + </callout> + + <callout arearefs="foreignkey-manytoone"> + <para>many-to-one (Optional): Defines that a many-to-one + should be created and the property attribute specifies the + name of the resulting property. Exclude can be used to + explicitly define that it should be created or not.</para> + </callout> + + <callout arearefs="foreignkey-set"> + <para>set (Optional): Defines that a set should be created + based on this foreign-key and the property attribute specifies + the name of the resulting (set) property. Exclude can be used + to explicitly define that it should be created or not.</para> + </callout> + </calloutlist> + </programlistingco></para> </section> </section> </section> |
Author: epbernard Date: 2006-05-01 23:21:21 -0400 (Mon, 01 May 2006) New Revision: 9848 Modified: trunk/HibernateExt/metadata/build.xml trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/xml/XMLContext.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/Ejb3XmlTest.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/orm3.xml Log: ANN-325 XML entity are part of the persistence unit Modified: trunk/HibernateExt/metadata/build.xml =================================================================== --- trunk/HibernateExt/metadata/build.xml 2006-05-01 23:28:45 UTC (rev 9847) +++ trunk/HibernateExt/metadata/build.xml 2006-05-02 03:21:21 UTC (rev 9848) @@ -120,15 +120,15 @@ </junit> </target> - <target name="report"> + <!-- target name="report"> <mkdir dir="test_output"/> <junitreport todir="test_output"> <fileset dir="test_output"> <include name="TEST-*.xml"/> </fileset> - <report format="frames" todir="./report/html"/> + <report format="frames" todir="test_output/report"/> </junitreport> - </target> + </target --> <target name="jar" depends="compile" description="Build the distribution .jar file"> <mkdir dir="${classes.dir}/META-INF"/> Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java 2006-05-01 23:28:45 UTC (rev 9847) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java 2006-05-02 03:21:21 UTC (rev 9848) @@ -221,10 +221,19 @@ protected void secondPassCompile() throws MappingException { log.debug( "Execute first pass mapping processing" ); //build annotatedClassEntities - for ( XClass clazz : annotatedClasses ) { - if ( clazz.isAnnotationPresent( Entity.class ) ) { - annotatedClassEntities.put( clazz.getName(), clazz ); + { + List<XClass> tempAnnotatedClasses = new ArrayList<XClass>( annotatedClasses.size() ); + for ( XClass clazz : annotatedClasses ) { + if ( clazz.isAnnotationPresent( Entity.class ) ) { + annotatedClassEntities.put( clazz.getName(), clazz ); + tempAnnotatedClasses.add(clazz); + } + else if (clazz.isAnnotationPresent( MappedSuperclass.class ) ) { + tempAnnotatedClasses.add(clazz); + } + //only keep MappedSuperclasses and Entity in this list } + annotatedClasses = tempAnnotatedClasses; } if ( precedence == null ) precedence = getProperties().getProperty( ARTEFACT ); if ( precedence == null ) precedence = DEFAULT_PRECEDENCE; @@ -457,7 +466,15 @@ hbmDocuments.add( doc ); } else { - ( (JavaXFactory) reflectionManager ).getXMLContext().addDocument( doc ); + List<String> classnames = ( (JavaXFactory) reflectionManager ).getXMLContext().addDocument( doc ); + for (String classname : classnames) { + try { + annotatedClasses.add( reflectionManager.classForName( classname, this.getClass() ) ); + } + catch (ClassNotFoundException e) { + throw new AnnotationException( "Unable to load class defined in XML: " + classname, e ); + } + } } } } Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/xml/XMLContext.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/xml/XMLContext.java 2006-05-01 23:28:45 UTC (rev 9847) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/xml/XMLContext.java 2006-05-02 03:21:21 UTC (rev 9848) @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.ArrayList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -20,7 +21,10 @@ private Map<String, Element> classOverriding = new HashMap<String, Element>(); private Map<String, Default> defaultsOverriding = new HashMap<String, Default>(); - public void addDocument(Document doc) { + /** + * Add a document and return the list of added classes names + */ + public List<String> addDocument(Document doc) { Element root = doc.getRootElement(); //global defaults Element metadata = root.element( "persistence-unit-metadata" ); @@ -62,24 +66,26 @@ unitElement = root.element( "access" ); entityMappingDefault.setAccess( unitElement != null ? unitElement.getTextTrim() : null ); - + List<String> addedClasses = new ArrayList<String>(); List<Element> entities = (List<Element>) root.elements( "entity" ); - addClass( entities, packageName, entityMappingDefault ); + addClass( entities, packageName, entityMappingDefault, addedClasses ); entities = (List<Element>) root.elements( "mapped-superclass" ); - addClass( entities, packageName, entityMappingDefault ); + addClass( entities, packageName, entityMappingDefault, addedClasses ); entities = (List<Element>) root.elements( "embeddable" ); - addClass( entities, packageName, entityMappingDefault ); + addClass( entities, packageName, entityMappingDefault, addedClasses ); + return addedClasses; } - private void addClass(List<Element> entities, String packageName, Default defaults) { + private void addClass(List<Element> entities, String packageName, Default defaults, List<String> addedClasses) { for ( Element element : entities ) { String className = buildSafeClassName( element.attributeValue( "class" ), packageName ); if ( classOverriding.containsKey( className ) ) { //maybe switch it to warn? throw new IllegalStateException( "Duplicate XML entry for " + className ); } + addedClasses.add( className ); classOverriding.put( className, element ); Default localDefault = new Default(); localDefault.override( defaults ); Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/Ejb3XmlTest.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/Ejb3XmlTest.java 2006-05-01 23:28:45 UTC (rev 9847) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/Ejb3XmlTest.java 2006-05-02 03:21:21 UTC (rev 9848) @@ -43,13 +43,25 @@ s.close(); } + public void testXMLEntityHandled() throws Exception { + Session s = openSession(); + s.getTransaction().begin(); + Lighter l = new Lighter(); + l.name = "Blue"; + l.power = "400F"; + s.persist( l ); + s.flush(); + s.getTransaction().rollback(); + s.close(); + } + protected Class[] getMappings() { return new Class[]{ CarModel.class, Manufacturer.class, Model.class, - Light.class, - Lighter.class + Light.class + //Lighter.class xml only entuty }; } Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/orm3.xml =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/orm3.xml 2006-05-01 23:28:45 UTC (rev 9847) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/ejb3/orm3.xml 2006-05-02 03:21:21 UTC (rev 9848) @@ -5,7 +5,7 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd" version="1.0" > - <package>org.hibernate.ejb.test.pack.defaultpar</package> + <package>org.hibernate.test.annotations.xml.ejb3</package> <entity class="Lighter" access="FIELD" metadata-complete="true"> <attributes> <id name="name"> |
From: <hib...@li...> - 2006-05-01 23:28:50
|
Author: epbernard Date: 2006-05-01 19:28:45 -0400 (Mon, 01 May 2006) New Revision: 9847 Added: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/OneToOneSecondPass.java Removed: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ToOneMappedBySecondPass.java Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/BinderHelper.java trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java Log: Refactor true OneToOne processing Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-05-01 21:40:41 UTC (rev 9846) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-05-01 23:28:45 UTC (rev 9847) @@ -71,6 +71,7 @@ import org.hibernate.annotations.Index; import org.hibernate.annotations.LazyToOne; import org.hibernate.annotations.LazyToOneOption; +import org.hibernate.annotations.MapKeyManyToMany; import org.hibernate.annotations.NotFound; import org.hibernate.annotations.NotFoundAction; import org.hibernate.annotations.OnDelete; @@ -85,7 +86,6 @@ import org.hibernate.annotations.TypeDef; import org.hibernate.annotations.TypeDefs; import org.hibernate.annotations.Where; -import org.hibernate.annotations.MapKeyManyToMany; import org.hibernate.cfg.annotations.CollectionBinder; import org.hibernate.cfg.annotations.EntityBinder; import org.hibernate.cfg.annotations.Nullability; @@ -121,7 +121,6 @@ import org.hibernate.reflection.XClass; import org.hibernate.reflection.XPackage; import org.hibernate.reflection.XProperty; -import org.hibernate.type.ForeignKeyDirection; import org.hibernate.type.TypeFactory; import org.hibernate.util.StringHelper; @@ -1766,7 +1765,7 @@ propertyHolder.addProperty( prop, columns ); } - private static void defineFetchingStrategy(ToOne toOne, XProperty property) { + protected static void defineFetchingStrategy(ToOne toOne, XProperty property) { LazyToOne lazy = property.getAnnotation( LazyToOne.class ); Fetch fetch = property.getAnnotation( Fetch.class ); ManyToOne manyToOne = property.getAnnotation( ManyToOne.class ); @@ -1814,7 +1813,7 @@ private static void bindOneToOne( String cascadeStrategy, - Ejb3JoinColumn[] columns, + Ejb3JoinColumn[] joinColumns, boolean optional, FetchMode fetchMode, boolean ignoreNotFound, @@ -1838,7 +1837,7 @@ currentColumn = (org.hibernate.mapping.Column) idColumns.next(); idColumnNames.add( currentColumn.getName() ); } - for ( Ejb3JoinColumn col : columns ) { + for ( Ejb3JoinColumn col : joinColumns ) { if ( ! idColumnNames.contains( col.getMappingColumn().getName() ) ) { mapToPK = false; break; @@ -1848,66 +1847,20 @@ if ( trueOneToOne || mapToPK || ! isDefault( mappedBy ) ) { //is a true one-to-one //FIXME referencedColumnName ignored => ordering may fail. - - org.hibernate.mapping.OneToOne value = new org.hibernate.mapping.OneToOne( - propertyHolder.getTable(), propertyHolder.getPersistentClass() + mappings.addSecondPass( + new OneToOneSecondPass( + mappedBy, + propertyHolder.getEntityName(), + propertyName, + propertyHolder, inferredData, targetEntity, ignoreNotFound, cascadeOnDelete, + optional, cascadeStrategy, joinColumns, mappings + ) ); - value.setPropertyName( propertyName ); - String referencedEntityName; - if ( isDefault( targetEntity, mappings ) ) { - referencedEntityName = inferredData.getClassOrElementName(); - } - else { - referencedEntityName = targetEntity.getName(); - } - value.setReferencedEntityName( referencedEntityName ); - defineFetchingStrategy( value, inferredData.getProperty() ); - //value.setFetchMode( fetchMode ); - value.setCascadeDeleteEnabled( cascadeOnDelete ); - //value.setLazy( fetchMode != FetchMode.JOIN ); - - if ( !optional ) value.setConstrained( true ); - value.setForeignKeyType( - value.isConstrained() ? - ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT : - ForeignKeyDirection.FOREIGN_KEY_TO_PARENT - ); - PropertyBinder binder = new PropertyBinder(); - binder.setName( propertyName ); - binder.setValue( value ); - binder.setCascade( cascadeStrategy ); - binder.setPropertyAccessorName( inferredData.getDefaultAccess() ); - Property prop = binder.make(); - if ( ! isDefault( mappedBy ) ) { - mappings.addSecondPass( - new ToOneMappedBySecondPass( - mappedBy, - value, - propertyHolder.getEntityName(), - propertyName, - prop, propertyHolder, ignoreNotFound, mappings - ) - ); - } - else { - String path = propertyHolder.getPath() + "." + propertyName; - mappings.addSecondPass( - new FkSecondPass( - value, columns, - !optional, //cannot have nullabe and unique on certain DBs - path, mappings - ) - ); - //no column associated since its a one to one - propertyHolder.addProperty( prop ); - } - - } else { //has a FK on the table bindManyToOne( - cascadeStrategy, columns, optional, ignoreNotFound, cascadeOnDelete, + cascadeStrategy, joinColumns, optional, ignoreNotFound, cascadeOnDelete, targetEntity, propertyHolder, inferredData, true, isIdentifierMapper, mappings ); Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/BinderHelper.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/BinderHelper.java 2006-05-01 21:40:41 UTC (rev 9846) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/BinderHelper.java 2006-05-01 23:28:45 UTC (rev 9847) @@ -78,8 +78,9 @@ //associated entity only used for more precise exception, yuk! if ( columns[0].isImplicit() || StringHelper.isNotEmpty( columns[0].getMappedBy() ) ) return; int fkEnum = Ejb3JoinColumn.checkReferencedColumnsType( columns, ownerEntity, mappings ); - PersistentClass associatedClass = columns[0].getPropertyHolder() == null ? null : columns[0].getPropertyHolder() - .getPersistentClass(); + PersistentClass associatedClass = columns[0].getPropertyHolder() != null ? + columns[0].getPropertyHolder().getPersistentClass() : + null; if ( Ejb3JoinColumn.NON_PK_REFERENCE == fkEnum ) { /** * Create a synthetic property to refer to including an Copied: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/OneToOneSecondPass.java (from rev 9833, trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ToOneMappedBySecondPass.java) =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ToOneMappedBySecondPass.java 2006-04-30 04:08:48 UTC (rev 9833) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/OneToOneSecondPass.java 2006-05-01 23:28:45 UTC (rev 9847) @@ -0,0 +1,242 @@ +//$Id$ +package org.hibernate.cfg; + +import java.util.Iterator; +import java.util.Map; + +import org.hibernate.AnnotationException; +import org.hibernate.MappingException; +import org.hibernate.cfg.annotations.PropertyBinder; +import org.hibernate.mapping.Column; +import org.hibernate.mapping.DependantValue; +import org.hibernate.mapping.Join; +import org.hibernate.mapping.ManyToOne; +import org.hibernate.mapping.OneToOne; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.mapping.Property; +import org.hibernate.mapping.SimpleValue; +import org.hibernate.reflection.XClass; +import org.hibernate.type.ForeignKeyDirection; +import org.hibernate.util.StringHelper; + +/** + * We have to handle OneToOne in a second pass because: + * - + */ +public class OneToOneSecondPass implements SecondPass { + private String mappedBy; + private ExtendedMappings mappings; + private String ownerEntity; + private String ownerProperty; + private PropertyHolder propertyHolder; + private boolean ignoreNotFound; + private PropertyData inferredData; + private XClass targetEntity; + private boolean cascadeOnDelete; + private boolean optional; + private String cascadeStrategy; + private Ejb3JoinColumn[] joinColumns; + + //that suck, we should read that from the property mainly + public OneToOneSecondPass( + String mappedBy, String ownerEntity, String ownerProperty, + PropertyHolder propertyHolder, PropertyData inferredData, XClass targetEntity, boolean ignoreNotFound, + boolean cascadeOnDelete, boolean optional, String cascadeStrategy, Ejb3JoinColumn[] columns, + ExtendedMappings mappings + ) { + this.ownerEntity = ownerEntity; + this.ownerProperty = ownerProperty; + this.mappedBy = mappedBy; + this.propertyHolder = propertyHolder; + this.mappings = mappings; + this.ignoreNotFound = ignoreNotFound; + this.inferredData = inferredData; + this.targetEntity = targetEntity; + this.cascadeOnDelete = cascadeOnDelete; + this.optional = optional; + this.cascadeStrategy = cascadeStrategy; + this.joinColumns = columns; + } + + //TODO refactor this code, there is a lot of duplication in this method + public void doSecondPass(Map persistentClasses, Map inheritedMetas) throws MappingException { + org.hibernate.mapping.OneToOne value = new org.hibernate.mapping.OneToOne( + propertyHolder.getTable(), propertyHolder.getPersistentClass() + ); + final String propertyName = inferredData.getPropertyName(); + value.setPropertyName( propertyName ); + String referencedEntityName; + if ( AnnotationBinder.isDefault( targetEntity, mappings ) ) { + referencedEntityName = inferredData.getClassOrElementName(); + } + else { + referencedEntityName = targetEntity.getName(); + } + value.setReferencedEntityName( referencedEntityName ); + AnnotationBinder.defineFetchingStrategy( value, inferredData.getProperty() ); + //value.setFetchMode( fetchMode ); + value.setCascadeDeleteEnabled( cascadeOnDelete ); + //value.setLazy( fetchMode != FetchMode.JOIN ); + + if ( !optional ) value.setConstrained( true ); + value.setForeignKeyType( + value.isConstrained() ? + ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT : + ForeignKeyDirection.FOREIGN_KEY_TO_PARENT + ); + PropertyBinder binder = new PropertyBinder(); + binder.setName( propertyName ); + binder.setValue( value ); + binder.setCascade( cascadeStrategy ); + binder.setPropertyAccessorName( inferredData.getDefaultAccess() ); + Property prop = binder.make(); + if ( AnnotationBinder.isDefault( mappedBy ) ) { + /* + * we need to check if the columns are in the right order + * if not, then we need to create a many to one and formula + * but actually, since entities linked by a one to one need + * to share the same composite id class, this cannot happen in hibernate + */ + boolean rightOrder = true; + + if (rightOrder) { + String path = StringHelper.qualify( propertyHolder.getPath(), propertyName ); + ( new FkSecondPass( + value, joinColumns, + !optional, //cannot have nullabe and unique on certain DBs + path, mappings + ) ).doSecondPass( persistentClasses, inheritedMetas ); + //no column associated since its a one to one + propertyHolder.addProperty( prop ); + } + else { + //this is a many to one with Formula + + } + } + else { + PersistentClass otherSide = (PersistentClass) persistentClasses.get( value.getReferencedEntityName() ); + Property otherSideProperty; + try { + if ( otherSide == null ) { + throw new MappingException( "Unable to find entity: " + value.getReferencedEntityName() ); + } + otherSideProperty = otherSide.getProperty( mappedBy ); + } + catch (MappingException e) { + throw new AnnotationException( + "Unknown mappedBy in: " + StringHelper.qualify( ownerEntity, ownerProperty ) + + ", referenced property unknown: " + + StringHelper.qualify( value.getReferencedEntityName(), mappedBy ) + ); + } + if ( otherSideProperty.getValue() instanceof OneToOne ) { + propertyHolder.addProperty( prop ); + } + else if ( otherSideProperty.getValue() instanceof ManyToOne ) { + Iterator it = otherSide.getJoinIterator(); + Join otherSideJoin = null; + while ( it.hasNext() ) { + otherSideJoin = (Join) it.next(); + if ( otherSideJoin.containsProperty( otherSideProperty ) ) { + break; + } + } + if ( otherSideJoin != null ) { + //@OneToOne @JoinTable + Join mappedByJoin = buildJoin( + (PersistentClass) persistentClasses.get( ownerEntity ), otherSideProperty, otherSideJoin + ); + ManyToOne manyToOne = new ManyToOne( mappedByJoin.getTable() ); + //FIXME use ignore not found here + manyToOne.setIgnoreNotFound( ignoreNotFound ); + manyToOne.setCascadeDeleteEnabled( value.isCascadeDeleteEnabled() ); + manyToOne.setEmbedded( value.isEmbedded() ); + manyToOne.setFetchMode( value.getFetchMode() ); + manyToOne.setLazy( value.isLazy() ); + manyToOne.setReferencedEntityName( value.getReferencedEntityName() ); + manyToOne.setUnwrapProxy( value.isUnwrapProxy() ); + prop.setValue( manyToOne ); + Iterator otherSideJoinKeyColumns = otherSideJoin.getKey().getColumnIterator(); + while ( otherSideJoinKeyColumns.hasNext() ) { + Column column = (Column) otherSideJoinKeyColumns.next(); + Column copy = new Column(); + copy.setLength( column.getLength() ); + copy.setScale( column.getScale() ); + copy.setValue( manyToOne ); + copy.setName( column.getQuotedName() ); + copy.setNullable( column.isNullable() ); + copy.setPrecision( column.getPrecision() ); + copy.setUnique( column.isUnique() ); + copy.setSqlType( column.getSqlType() ); + copy.setCheckConstraint( column.getCheckConstraint() ); + copy.setComment( column.getComment() ); + copy.setDefaultValue( column.getDefaultValue() ); + manyToOne.addColumn( copy ); + } + mappedByJoin.addProperty( prop ); + } + else { + propertyHolder.addProperty( prop ); + } + + value.setReferencedPropertyName( mappedBy ); + + String propertyRef = value.getReferencedPropertyName(); + if ( propertyRef != null ) { + mappings.addUniquePropertyReference( + value.getReferencedEntityName(), + propertyRef + ); + } + } + else { + throw new AnnotationException( + "Referenced property not a (One|Many)ToOne: " + + StringHelper.qualify( + value.getReferencedEntityName(), value.getReferencedPropertyName() + ) + + " in mappedBy of " + + StringHelper.qualify( ownerEntity, ownerProperty ) + ); + } + } + } + + //dirty dupe of EntityBinder.bindSecondaryTable + private Join buildJoin(PersistentClass persistentClass, Property otherSideProperty, Join originalJoin) { + Join join = new Join(); + join.setPersistentClass( persistentClass ); + + //no check constraints available on joins + join.setTable( originalJoin.getTable() ); + join.setInverse( true ); + SimpleValue key = new DependantValue( join.getTable(), persistentClass.getIdentifier() ); + join.setKey( key ); + join.setSequentialSelect( false ); + join.setOptional( true ); //perhaps not quite per-spec, but a Good Thing anyway + key.setCascadeDeleteEnabled( false ); + Iterator mappedByColumns = otherSideProperty.getValue().getColumnIterator(); + while ( mappedByColumns.hasNext() ) { + Column column = (Column) mappedByColumns.next(); + Column copy = new Column(); + copy.setLength( column.getLength() ); + copy.setScale( column.getScale() ); + copy.setValue( key ); + copy.setName( column.getQuotedName() ); + copy.setNullable( column.isNullable() ); + copy.setPrecision( column.getPrecision() ); + copy.setUnique( column.isUnique() ); + copy.setSqlType( column.getSqlType() ); + copy.setCheckConstraint( column.getCheckConstraint() ); + copy.setComment( column.getComment() ); + copy.setDefaultValue( column.getDefaultValue() ); + key.addColumn( copy ); + } + join.createPrimaryKey(); + join.createForeignKey(); + persistentClass.addJoin( join ); + return join; + } +} + Property changes on: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/OneToOneSecondPass.java ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Deleted: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ToOneMappedBySecondPass.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ToOneMappedBySecondPass.java 2006-05-01 21:40:41 UTC (rev 9846) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/ToOneMappedBySecondPass.java 2006-05-01 23:28:45 UTC (rev 9847) @@ -1,166 +0,0 @@ -//$Id$ -package org.hibernate.cfg; - -import java.util.Iterator; -import java.util.Map; - -import org.hibernate.AnnotationException; -import org.hibernate.MappingException; -import org.hibernate.mapping.Column; -import org.hibernate.mapping.DependantValue; -import org.hibernate.mapping.Join; -import org.hibernate.mapping.ManyToOne; -import org.hibernate.mapping.OneToOne; -import org.hibernate.mapping.PersistentClass; -import org.hibernate.mapping.Property; -import org.hibernate.mapping.SimpleValue; -import org.hibernate.mapping.ToOne; -import org.hibernate.util.StringHelper; - -public class ToOneMappedBySecondPass implements SecondPass { - private String mappedBy; - private ToOne value; - private ExtendedMappings mappings; - private String ownerEntity; - private String ownerProperty; - private PropertyHolder propertyHolder; - private Property property; - private boolean ignoreNotFound; - - public ToOneMappedBySecondPass( - String mappedBy, ToOne value, String ownerEntity, String ownerProperty, Property property, - PropertyHolder propertyHolder, boolean ignoreNotFound, - ExtendedMappings mappings - ) { - this.ownerEntity = ownerEntity; - this.ownerProperty = ownerProperty; - this.mappedBy = mappedBy; - this.value = value; - this.propertyHolder = propertyHolder; - this.mappings = mappings; - this.property = property; - this.ignoreNotFound = ignoreNotFound; - } - - public void doSecondPass(Map persistentClasses, Map inheritedMetas) throws MappingException { - PersistentClass otherSide = (PersistentClass) persistentClasses.get( value.getReferencedEntityName() ); - Property otherSideProperty; - try { - if ( otherSide == null ) { - throw new MappingException( "Unable to find entity: " + value.getReferencedEntityName() ); - } - otherSideProperty = otherSide.getProperty( mappedBy ); - } - catch (MappingException e) { - throw new AnnotationException( - "Unknown mappedBy in: " + StringHelper.qualify( ownerEntity, ownerProperty ) - + ", referenced property unknown: " - + StringHelper.qualify( value.getReferencedEntityName(), mappedBy ) - ); - } - if ( otherSideProperty.getValue() instanceof OneToOne ) { - propertyHolder.addProperty( property ); - } - else if ( otherSideProperty.getValue() instanceof ManyToOne ) { - Iterator it = otherSide.getJoinIterator(); - Join otherSideJoin = null; - while ( it.hasNext() ) { - otherSideJoin = (Join) it.next(); - if ( otherSideJoin.containsProperty( otherSideProperty ) ) { - break; - } - } - if ( otherSideJoin != null ) { - //@OneToOne @JoinTable - Join mappedByJoin = buildJoin( - (PersistentClass) persistentClasses.get( ownerEntity ), otherSideProperty, otherSideJoin - ); - ManyToOne manyToOne = new ManyToOne( mappedByJoin.getTable() ); - //FIXME use ignore not found here - manyToOne.setIgnoreNotFound( ignoreNotFound ); - manyToOne.setCascadeDeleteEnabled( value.isCascadeDeleteEnabled() ); - manyToOne.setEmbedded( value.isEmbedded() ); - manyToOne.setFetchMode( value.getFetchMode() ); - manyToOne.setLazy( value.isLazy() ); - manyToOne.setReferencedEntityName( value.getReferencedEntityName() ); - manyToOne.setUnwrapProxy( value.isUnwrapProxy() ); - property.setValue( manyToOne ); - Iterator otherSideJoinKeyColumns = otherSideJoin.getKey().getColumnIterator(); - while ( otherSideJoinKeyColumns.hasNext() ) { - Column column = (Column) otherSideJoinKeyColumns.next(); - Column copy = new Column(); - copy.setLength( column.getLength() ); - copy.setScale( column.getScale() ); - copy.setValue( manyToOne ); - copy.setName( column.getQuotedName() ); - copy.setNullable( column.isNullable() ); - copy.setPrecision( column.getPrecision() ); - copy.setUnique( column.isUnique() ); - copy.setSqlType( column.getSqlType() ); - copy.setCheckConstraint( column.getCheckConstraint() ); - copy.setComment( column.getComment() ); - copy.setDefaultValue( column.getDefaultValue() ); - manyToOne.addColumn( copy ); - } - mappedByJoin.addProperty( property ); - } - else { - propertyHolder.addProperty( property ); - } - - value.setReferencedPropertyName( mappedBy ); - - String propertyRef = value.getReferencedPropertyName(); - if ( propertyRef != null ) { - mappings.addUniquePropertyReference( - value.getReferencedEntityName(), - propertyRef - ); - } - } - else { - throw new AnnotationException( - "Referenced property not a (One|Many)ToOne: " - + StringHelper.qualify( value.getReferencedEntityName(), value.getReferencedPropertyName() ) - + " in mappedBy of " - + StringHelper.qualify( ownerEntity, ownerProperty ) - ); - } - } - - //dirty dupe of EntityBinder.bindSecondaryTable - private Join buildJoin(PersistentClass persistentClass, Property otherSideProperty, Join originalJoin) { - Join join = new Join(); - join.setPersistentClass( persistentClass ); - - //no check constraints available on joins - join.setTable( originalJoin.getTable() ); - join.setInverse( true ); - SimpleValue key = new DependantValue( join.getTable(), persistentClass.getIdentifier() ); - join.setKey( key ); - join.setSequentialSelect( false ); - join.setOptional( true ); //perhaps not quite per-spec, but a Good Thing anyway - key.setCascadeDeleteEnabled( false ); - Iterator mappedByColumns = otherSideProperty.getValue().getColumnIterator(); - while ( mappedByColumns.hasNext() ) { - Column column = (Column) mappedByColumns.next(); - Column copy = new Column(); - copy.setLength( column.getLength() ); - copy.setScale( column.getScale() ); - copy.setValue( key ); - copy.setName( column.getQuotedName() ); - copy.setNullable( column.isNullable() ); - copy.setPrecision( column.getPrecision() ); - copy.setUnique( column.isUnique() ); - copy.setSqlType( column.getSqlType() ); - copy.setCheckConstraint( column.getCheckConstraint() ); - copy.setComment( column.getComment() ); - copy.setDefaultValue( column.getDefaultValue() ); - key.addColumn( copy ); - } - join.createPrimaryKey(); - join.createForeignKey(); - persistentClass.addJoin( join ); - return join; - } -} Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java 2006-05-01 21:40:41 UTC (rev 9846) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java 2006-05-01 23:28:45 UTC (rev 9847) @@ -81,6 +81,7 @@ Ejb3JoinColumn[] mapKeyManyToManyColumns ) { if ( mapKeyPropertyName != null ) { + //this is an EJB3 @MapKey PersistentClass associatedClass = (PersistentClass) persistentClasses.get( collType ); if ( associatedClass == null ) throw new AnnotationException( "Associated class not found: " + collType ); Property mapProperty = BinderHelper.findPropertyByName( associatedClass, mapKeyPropertyName ); @@ -94,7 +95,7 @@ map.setIndex( indexValue ); } else { - //throw new AnnotationException( "A Map must declare a @MapKey element" ); + //this is a true Map mapping //TODO ugly copy/pastle from CollectionBinder.bindManyToManySecondPass String mapKeyType = property.getMapKey().getName(); PersistentClass collectionEntity = (PersistentClass) persistentClasses.get( mapKeyType ); |
From: <hib...@li...> - 2006-05-01 21:40:44
|
Author: epbernard Date: 2006-05-01 17:40:41 -0400 (Mon, 01 May 2006) New Revision: 9846 Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java Log: ANN-336 partial implementation, does not work for indexes and ignore the "element" thing Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java 2006-05-01 20:12:39 UTC (rev 9845) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java 2006-05-01 21:40:41 UTC (rev 9846) @@ -533,7 +533,7 @@ isEmbedded, collType, ignoreNotFound, unique, cascadeDeleteEnabled, - associationTableBinder, property, mappings + associationTableBinder, property, hqlOrderBy, mappings ); return false; } @@ -768,7 +768,7 @@ String collType, boolean ignoreNotFound, boolean unique, boolean cascadeDeleteEnabled, - TableBinder associationTableBinder, XProperty property, ExtendedMappings mappings + TableBinder associationTableBinder, XProperty property, String hqlOrderBy, ExtendedMappings mappings ) throws MappingException { PersistentClass collectionEntity = (PersistentClass) persistentClasses.get( collType ); @@ -803,6 +803,10 @@ } } } + if ( ! isCollectionOfEntities && StringHelper.isNotEmpty( hqlOrderBy ) ) { + //@ManyToMany can't handle order by on the target table + collValue.setOrderBy( hqlOrderBy ); + } boolean mappedBy = ! AnnotationBinder.isDefault( joinColumns[0].getMappedBy() ); if ( mappedBy ) { if ( ! isCollectionOfEntities ) { |
From: <hib...@li...> - 2006-05-01 20:12:52
|
Author: epbernard Date: 2006-05-01 16:12:39 -0400 (Mon, 01 May 2006) New Revision: 9845 Added: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/MapKeyManyToMany.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/GasKey.java Modified: trunk/HibernateExt/metadata/build.xml trunk/HibernateExt/metadata/doc/reference/en/modules/entity.xml trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/ListBinder.java trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/Atmosphere.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/IndexedCollectionTest.java Log: ANN-327 support Map<Entity, ...> Modified: trunk/HibernateExt/metadata/build.xml =================================================================== --- trunk/HibernateExt/metadata/build.xml 2006-05-01 19:07:55 UTC (rev 9844) +++ trunk/HibernateExt/metadata/build.xml 2006-05-01 20:12:39 UTC (rev 9845) @@ -120,6 +120,16 @@ </junit> </target> + <target name="report"> + <mkdir dir="test_output"/> + <junitreport todir="test_output"> + <fileset dir="test_output"> + <include name="TEST-*.xml"/> + </fileset> + <report format="frames" todir="./report/html"/> + </junitreport> + </target> + <target name="jar" depends="compile" description="Build the distribution .jar file"> <mkdir dir="${classes.dir}/META-INF"/> <manifest file="${classes.dir}/META-INF/MANIFEST.MF"> Modified: trunk/HibernateExt/metadata/doc/reference/en/modules/entity.xml =================================================================== --- trunk/HibernateExt/metadata/doc/reference/en/modules/entity.xml 2006-05-01 19:07:55 UTC (rev 9844) +++ trunk/HibernateExt/metadata/doc/reference/en/modules/entity.xml 2006-05-01 20:12:39 UTC (rev 9845) @@ -1270,7 +1270,7 @@ <entry>(@org.hibernate.annotations.CollectionOfElements or @OneToMany or @ManyToMany) and (nothing or - @org.hibernate.annotations.MapKey for true map support, OR + @org.hibernate.annotations.MapKey/MapKeyManyToMany for true map support, OR @javax.persistence.MapKey</entry> </row> </tbody> @@ -2801,12 +2801,14 @@ semantic is applied</para> </note> - <para>Hibernate Annotations also supports true Map mappings (except - Map<Entity, Entity>), if + <para>Hibernate Annotations also supports true Map mappings, if <literal>@javax.persistence.MapKey</literal> is not set, hibernate will map the key element or embeddable object in its/their own columns. To overrides the default columns, you can use - <literal>@org.hibernate.annotations.MapKey</literal>.</para> + <literal>@org.hibernate.annotations.MapKey</literal> if your key is a basic type + or an embeddable object, or you canh use + <literal>@org.hibernate.annotations.MapKey</literal> if your key is an entity. + </para> <para>Hibernate Annotations also supports collections of core types (Integer, String, Enums, ...), collections of embeddable objects and Added: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/MapKeyManyToMany.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/MapKeyManyToMany.java 2006-05-01 19:07:55 UTC (rev 9844) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/MapKeyManyToMany.java 2006-05-01 20:12:39 UTC (rev 9845) @@ -0,0 +1,21 @@ +//$Id: $ +package org.hibernate.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.persistence.JoinColumn; + +/** + * Define the map key columns as an explicit column holding the map key + * This is completly different from {@link javax.persistence.MapKey} which use an existing column + * This annotation and {@link javax.persistence.MapKey} are mutually exclusive + * + * @author Emmanuel Bernard + */ +@Target({ElementType.METHOD, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface MapKeyManyToMany { + JoinColumn[] joinColumns() default {}; +} Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-05-01 19:07:55 UTC (rev 9844) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-05-01 20:12:39 UTC (rev 9845) @@ -85,6 +85,7 @@ import org.hibernate.annotations.TypeDef; import org.hibernate.annotations.TypeDefs; import org.hibernate.annotations.Where; +import org.hibernate.annotations.MapKeyManyToMany; import org.hibernate.cfg.annotations.CollectionBinder; import org.hibernate.cfg.annotations.EntityBinder; import org.hibernate.cfg.annotations.Nullability; @@ -1351,6 +1352,14 @@ ); collectionBinder.setMapKeyColumns( mapColumns ); + MapKeyManyToMany mapKeyManyToMany = property.getAnnotation( MapKeyManyToMany.class ); + Ejb3JoinColumn[] mapJoinColumns = Ejb3JoinColumn.buildJoinColumns( + mapKeyManyToMany != null ? mapKeyManyToMany.joinColumns() : null, + null, entityBinder.getSecondaryTables(), + propertyHolder, wrappedInferredData.getPropertyName(), mappings + ); + collectionBinder.setMapKeyManyToManyColumns( mapJoinColumns ); + //potential element collectionBinder.setEmbedded( property.isAnnotationPresent( Embedded.class ) ); collectionBinder.setElementColumns( elementColumns ); Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java 2006-05-01 19:07:55 UTC (rev 9844) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java 2006-05-01 20:12:39 UTC (rev 9845) @@ -107,6 +107,7 @@ private boolean ignoreNotFound; private TableBinder tableBinder; private Ejb3Column[] mapKeyColumns; + private Ejb3JoinColumn[] mapKeyManyToManyColumns; public void setUpdatable(boolean updatable) { this.updatable = updatable; @@ -348,7 +349,7 @@ joinColumns, inverseJoinColumns, elementColumns, - mapKeyColumns, isEmbedded, + mapKeyColumns, mapKeyManyToManyColumns, isEmbedded, property, collType, ignoreNotFound, oneToMany, tableBinder, mappings @@ -454,7 +455,7 @@ final Ejb3JoinColumn[] fkJoinColumns, final Ejb3JoinColumn[] keyColumns, final Ejb3JoinColumn[] inverseColumns, final Ejb3Column[] elementColumns, - final Ejb3Column[] mapKeyColumns, final boolean isEmbedded, + final Ejb3Column[] mapKeyColumns, final Ejb3JoinColumn[] mapKeyManyToManyColumns, final boolean isEmbedded, final XProperty property, final String collType, final boolean ignoreNotFound, final boolean unique, final TableBinder assocTableBinder, final ExtendedMappings mappings @@ -1101,4 +1102,8 @@ public void setMapKeyColumns(Ejb3Column[] mapKeyColumns) { this.mapKeyColumns = mapKeyColumns; } + + public void setMapKeyManyToManyColumns(Ejb3JoinColumn[] mapJoinColumns) { + this.mapKeyManyToManyColumns = mapJoinColumns; + } } \ No newline at end of file Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/ListBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/ListBinder.java 2006-05-01 19:07:55 UTC (rev 9844) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/ListBinder.java 2006-05-01 20:12:39 UTC (rev 9845) @@ -53,7 +53,7 @@ final Ejb3JoinColumn[] fkJoinColumns, final Ejb3JoinColumn[] keyColumns, final Ejb3JoinColumn[] inverseColumns, final Ejb3Column[] elementColumns, - Ejb3Column[] mapKeyColumns, final boolean isEmbedded, + Ejb3Column[] mapKeyColumns, final Ejb3JoinColumn[] mapKeyManyToManyColumns, final boolean isEmbedded, final XProperty property, final String collType, final boolean ignoreNotFound, final boolean unique, final TableBinder assocTableBinder, final ExtendedMappings mappings Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java 2006-05-01 19:07:55 UTC (rev 9844) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java 2006-05-01 20:12:39 UTC (rev 9845) @@ -55,7 +55,7 @@ final Ejb3JoinColumn[] fkJoinColumns, final Ejb3JoinColumn[] keyColumns, final Ejb3JoinColumn[] inverseColumns, final Ejb3Column[] elementColumns, - final Ejb3Column[] mapKeyColumns, final boolean isEmbedded, + final Ejb3Column[] mapKeyColumns, final Ejb3JoinColumn[] mapKeyManyToManyColumns, final boolean isEmbedded, final XProperty property, final String collType, final boolean ignoreNotFound, final boolean unique, final TableBinder assocTableBinder, final ExtendedMappings mappings @@ -68,8 +68,8 @@ isEmbedded, property, unique, assocTableBinder, ignoreNotFound, mappings ); bindKeyFromAssociationTable( - collType, persistentClasses, mapKeyPropertyName, property, ignoreNotFound, isEmbedded, mappings, - mapKeyColumns + collType, persistentClasses, mapKeyPropertyName, property, isEmbedded, mappings, + mapKeyColumns, mapKeyManyToManyColumns ); } }; @@ -77,7 +77,8 @@ private void bindKeyFromAssociationTable( String collType, Map persistentClasses, String mapKeyPropertyName, XProperty property, - boolean ignoreNotFound, boolean isEmbedded, ExtendedMappings mappings, Ejb3Column[] mapKeyColumns + boolean isEmbedded, ExtendedMappings mappings, Ejb3Column[] mapKeyColumns, + Ejb3JoinColumn[] mapKeyManyToManyColumns ) { if ( mapKeyPropertyName != null ) { PersistentClass associatedClass = (PersistentClass) persistentClasses.get( collType ); @@ -110,7 +111,7 @@ //make the second join non lazy element.setFetchMode( FetchMode.JOIN ); element.setLazy( false ); - element.setIgnoreNotFound( ignoreNotFound ); + //does not make sense for a map key element.setIgnoreNotFound( ignoreNotFound ); } else { XClass elementClass; @@ -211,7 +212,7 @@ } //FIXME pass the Index Entity JoinColumns if ( isIndexOfEntities ) { - //bindManytoManyInverseFk( collectionEntity, indexJoinColumns, element, unique, mappings ); + bindManytoManyInverseFk( collectionEntity, mapKeyManyToManyColumns, element, true, mappings ); } } } Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/Atmosphere.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/Atmosphere.java 2006-05-01 19:07:55 UTC (rev 9844) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/Atmosphere.java 2006-05-01 20:12:39 UTC (rev 9845) @@ -9,6 +9,7 @@ import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Column; +import javax.persistence.JoinTable; import org.hibernate.annotations.MapKey; @@ -20,7 +21,12 @@ @Id @GeneratedValue public Integer id; + @ManyToMany(cascade = CascadeType.ALL) @MapKey(columns = {@Column(name="gas_name")}) public Map<String, Gas> gases = new HashMap<String, Gas>(); + + @ManyToMany(cascade = CascadeType.ALL) + @JoinTable(name = "Gas_per_key") + public Map<GasKey, Gas> gasesPerKey = new HashMap<GasKey, Gas>(); } Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/GasKey.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/GasKey.java 2006-05-01 19:07:55 UTC (rev 9844) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/GasKey.java 2006-05-01 20:12:39 UTC (rev 9845) @@ -0,0 +1,21 @@ +//$Id: $ +package org.hibernate.test.annotations.indexcoll; + +import javax.persistence.Entity; +import javax.persistence.Id; + +/** + * @author Emmanuel Bernard + */ +@Entity +public class GasKey { + @Id private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/IndexedCollectionTest.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/IndexedCollectionTest.java 2006-05-01 19:07:55 UTC (rev 9844) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/IndexedCollectionTest.java 2006-05-01 20:12:39 UTC (rev 9845) @@ -371,20 +371,23 @@ Session s = openSession(); Transaction tx = s.beginTransaction(); Atmosphere atm = new Atmosphere(); + GasKey key = new GasKey(); + key.setName( "O2" ); Gas o2 = new Gas(); o2.name = "oxygen"; atm.gases.put( "100%", o2 ); + atm.gasesPerKey.put(key, o2); + s.persist( key ); s.persist( atm ); - tx.commit(); - s.close(); + s.flush(); + s.clear(); - s = openSession(); - tx = s.beginTransaction(); atm = (Atmosphere) s.get( Atmosphere.class, atm.id ); + key = (GasKey) s.get( GasKey.class, key.getName() ); assertEquals( 1, atm.gases.size() ); assertEquals( o2.name, atm.gases.get( "100%" ).name ); - s.delete( atm ); - tx.commit(); + assertEquals( o2.name, atm.gasesPerKey.get(key).name ); + tx.rollback(); s.close(); } @@ -409,7 +412,8 @@ Painting.class, Atmosphere.class, Gas.class, - AlphabeticalDirectory.class + AlphabeticalDirectory.class, + GasKey.class }; } } |
From: <hib...@li...> - 2006-05-01 19:07:59
|
Author: epbernard Date: 2006-05-01 15:07:55 -0400 (Mon, 01 May 2006) New Revision: 9844 Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/AlphabeticalDirectory.java Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/AddressBook.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/AddressEntry.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/IndexedCollectionTest.java Log: ANN-281 support @javax.persistence.MapKey referencing an entity Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java 2006-05-01 18:11:06 UTC (rev 9843) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java 2006-05-01 19:07:55 UTC (rev 9844) @@ -237,16 +237,28 @@ newProperty.setPersistentClass( current.getPersistentClass() ); newProperty.setPropertyAccessorName( current.getPropertyAccessorName() ); newProperty.setSelectable( current.isSelectable() ); - newProperty.setValue( createFormulatedValue( current.getValue(), collection ) ); + newProperty.setValue( createFormulatedValue( current.getValue(), collection) ); indexComponent.addProperty( newProperty ); } return indexComponent; } - else { + else if ( value instanceof SimpleValue ) { SimpleValue sourceValue = (SimpleValue) value; - SimpleValue targetValue = new SimpleValue( collection.getCollectionTable() ); - targetValue.setTypeName( sourceValue.getTypeName() ); - targetValue.setTypeParameters( sourceValue.getTypeParameters() ); + SimpleValue targetValue; + if( value instanceof ManyToOne ) { + ManyToOne sourceManyToOne = (ManyToOne) sourceValue; + ManyToOne targetManyToOne = new ManyToOne( collection.getCollectionTable() ); + targetManyToOne.setFetchMode( FetchMode.DEFAULT ); + targetManyToOne.setLazy( true ); + //targetValue.setIgnoreNotFound( ); does not make sense for a map key + targetManyToOne.setReferencedEntityName( sourceManyToOne.getReferencedEntityName() ); + targetValue = targetManyToOne; + } + else { + targetValue = new SimpleValue( collection.getCollectionTable() ); + targetValue.setTypeName( sourceValue.getTypeName() ); + targetValue.setTypeParameters( sourceValue.getTypeParameters() ); + } Iterator columns = sourceValue.getColumnIterator(); while ( columns.hasNext() ) { Object current = columns.next(); @@ -266,5 +278,8 @@ } return targetValue; } + else { + throw new AssertionFailure( "Unknown type encounters for map key: " + value.getClass() ); + } } } Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/AddressBook.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/AddressBook.java 2006-05-01 18:11:06 UTC (rev 9843) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/AddressBook.java 2006-05-01 19:07:55 UTC (rev 9844) @@ -19,6 +19,7 @@ private String owner; private Map<AddressEntryPk, AddressEntry> entries = new HashMap<AddressEntryPk, AddressEntry>(); private Map<String, AddressEntry> lastNameEntries = new HashMap<String, AddressEntry>(); + private Map<AlphabeticalDirectory, AddressEntry> directoryEntries = new HashMap<AlphabeticalDirectory, AddressEntry>(); @Id @GeneratedValue @@ -58,4 +59,14 @@ this.lastNameEntries = lastNameEntries; } + @MapKey(name = "directory") + @OneToMany(mappedBy = "book") + public Map<AlphabeticalDirectory, AddressEntry> getDirectoryEntries() { + return directoryEntries; + } + + public void setDirectoryEntries(Map<AlphabeticalDirectory, AddressEntry> directoryEntries) { + this.directoryEntries = directoryEntries; + } + } Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/AddressEntry.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/AddressEntry.java 2006-05-01 18:11:06 UTC (rev 9843) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/AddressEntry.java 2006-05-01 19:07:55 UTC (rev 9844) @@ -14,6 +14,7 @@ private String street; private String city; private AddressBook book; + private AlphabeticalDirectory directory; public boolean equals(Object o) { if ( this == o ) return true; @@ -63,4 +64,13 @@ public void setBook(AddressBook book) { this.book = book; } + + @ManyToOne + public AlphabeticalDirectory getDirectory() { + return directory; + } + + public void setDirectory(AlphabeticalDirectory directory) { + this.directory = directory; + } } Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/AlphabeticalDirectory.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/AlphabeticalDirectory.java 2006-05-01 18:11:06 UTC (rev 9843) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/AlphabeticalDirectory.java 2006-05-01 19:07:55 UTC (rev 9844) @@ -0,0 +1,31 @@ +//$Id: $ +package org.hibernate.test.annotations.indexcoll; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +/** + * @author Emmanuel Bernard + */ +@Entity +public class AlphabeticalDirectory { + @Id @GeneratedValue private Integer id; + private String name; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/IndexedCollectionTest.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/IndexedCollectionTest.java 2006-05-01 18:11:06 UTC (rev 9843) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/indexcoll/IndexedCollectionTest.java 2006-05-01 19:07:55 UTC (rev 9844) @@ -201,6 +201,50 @@ s.close(); } + public void testMapKeyToEntity() throws Exception { + Session s; + Transaction tx; + s = openSession(); + tx = s.beginTransaction(); + AlphabeticalDirectory m = new AlphabeticalDirectory(); + m.setName("M"); + AlphabeticalDirectory v = new AlphabeticalDirectory(); + v.setName("V"); + s.persist(m); + s.persist(v); + + AddressBook book = new AddressBook(); + book.setOwner( "Emmanuel" ); + AddressEntryPk helene = new AddressEntryPk( "Helene", "Michau" ); + AddressEntry heleneEntry = new AddressEntry(); + heleneEntry.setBook( book ); + heleneEntry.setCity( "Levallois" ); + heleneEntry.setStreet( "Louis Blanc" ); + heleneEntry.setPerson( helene ); + heleneEntry.setDirectory( m ); + AddressEntryPk primeMinister = new AddressEntryPk( "Dominique", "Villepin" ); + AddressEntry primeMinisterEntry = new AddressEntry(); + primeMinisterEntry.setBook( book ); + primeMinisterEntry.setCity( "Paris" ); + primeMinisterEntry.setStreet( "Hotel Matignon" ); + primeMinisterEntry.setPerson( primeMinister ); + primeMinisterEntry.setDirectory( v ); + book.getEntries().put( helene, heleneEntry ); + book.getEntries().put( primeMinister, primeMinisterEntry ); + s.persist( book ); + s.flush(); + s.clear(); + + book = (AddressBook) s.get( AddressBook.class, book.getId() ); + assertEquals( 2, book.getEntries().size() ); + assertEquals( heleneEntry.getCity(), book.getEntries().get( helene ).getCity() ); + assertEquals( "M", book.getEntries().get( helene ).getDirectory().getName() ); + + s.delete( book ); + tx.rollback(); + s.close(); + } + public void testComponentSubPropertyMapKey() throws Exception { Session s; Transaction tx; @@ -364,7 +408,8 @@ Painter.class, Painting.class, Atmosphere.class, - Gas.class + Gas.class, + AlphabeticalDirectory.class }; } } |
From: <hib...@li...> - 2006-05-01 18:11:09
|
Author: epbernard Date: 2006-05-01 14:11:06 -0400 (Mon, 01 May 2006) New Revision: 9843 Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/Music.java Log: ANN-95 working test on uniqueconstraint referencing a superclass column Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/Music.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/Music.java 2006-05-01 17:26:45 UTC (rev 9842) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/Music.java 2006-05-01 18:11:06 UTC (rev 9843) @@ -5,6 +5,8 @@ import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; import org.hibernate.annotations.DiscriminatorFormula; @@ -13,6 +15,7 @@ */ @Entity @DiscriminatorFormula("case when zik_type is null then 0 else zik_type end") +@Table(uniqueConstraints = @UniqueConstraint(columnNames = {"avgBeat", "starred"} )) public abstract class Music { private Integer id; private int avgBeat; |
From: <hib...@li...> - 2006-05-01 17:26:50
|
Author: epbernard Date: 2006-05-01 13:26:45 -0400 (Mon, 01 May 2006) New Revision: 9842 Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java Log: ANN-331 extra element concatenated to default columns in collection of elements Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java 2006-05-01 03:56:56 UTC (rev 9841) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java 2006-05-01 17:26:45 UTC (rev 9842) @@ -906,7 +906,7 @@ holder = PropertyHolderBuilder.buildPropertyHolder( collValue, - collValue.getRole() + "element", + collValue.getRole(), // + ".element", elementClass, property, mappings ); |
From: <hib...@li...> - 2006-05-01 03:57:05
|
Author: epbernard Date: 2006-04-30 23:56:56 -0400 (Sun, 30 Apr 2006) New Revision: 9841 Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java Log: ANN-335 proper exception when trying to map an tomany association on a non collection Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java 2006-05-01 03:25:02 UTC (rev 9840) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java 2006-05-01 03:56:56 UTC (rev 9841) @@ -208,12 +208,15 @@ else { throw new AnnotationException( returnedClass.getName() + " collection not yet supported: " - + entityName + property.getName() + + StringHelper.qualify( entityName, property.getName() ) ); } } else { - return null; + throw new AnnotationException( + "Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: " + + StringHelper.qualify( entityName, property.getName() ) + ); } } |
From: <hib...@li...> - 2006-05-01 03:25:12
|
Author: epbernard Date: 2006-04-30 23:25:02 -0400 (Sun, 30 Apr 2006) New Revision: 9840 Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/collectionelement/Boy.java Log: ANN-289 add some safety belts for Gavin on @ToOne and @column(s) Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-05-01 01:05:59 UTC (rev 9839) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-05-01 03:25:02 UTC (rev 9840) @@ -1180,6 +1180,14 @@ } else if ( property.isAnnotationPresent( ManyToOne.class ) ) { ManyToOne ann = property.getAnnotation( ManyToOne.class ); + + //check validity + if ( property.isAnnotationPresent( Column.class ) + || property.isAnnotationPresent( Columns.class ) ) { + throw new AnnotationException( "@Column(s) not allowed on a @ManyToOne property: " + + StringHelper.qualify( propertyHolder.getPath(), inferredData.getPropertyName() ) ); + } + Cascade hibernateCascade = property.getAnnotation( Cascade.class ); NotFound notFound = property.getAnnotation( NotFound.class ); boolean ignoreNotFound = notFound != null && notFound.action().equals( NotFoundAction.IGNORE ); @@ -1204,6 +1212,14 @@ } else if ( property.isAnnotationPresent( OneToOne.class ) ) { OneToOne ann = property.getAnnotation( OneToOne.class ); + + //check validity + if ( property.isAnnotationPresent( Column.class ) + || property.isAnnotationPresent( Columns.class ) ) { + throw new AnnotationException( "@Column(s) not allowed on a @OneToOne property: " + + StringHelper.qualify( propertyHolder.getPath(), inferredData.getPropertyName() ) ); + } + //FIXME support a proper PKJCs boolean trueOneToOne = property.isAnnotationPresent( PrimaryKeyJoinColumn.class ) || property.isAnnotationPresent( PrimaryKeyJoinColumns.class ); Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/collectionelement/Boy.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/collectionelement/Boy.java 2006-05-01 01:05:59 UTC (rev 9839) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/collectionelement/Boy.java 2006-05-01 03:25:02 UTC (rev 9840) @@ -6,15 +6,16 @@ import java.util.Map; import java.util.Set; import javax.persistence.AttributeOverride; +import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; -import javax.persistence.AttributeOverrides; import org.hibernate.annotations.CollectionOfElements; import org.hibernate.annotations.IndexColumn; @@ -119,7 +120,8 @@ this.characters = characters; } - @CollectionOfElements + @CollectionOfElements(fetch = FetchType.EAGER) + //@Where(clause = "b_likes=false") public Set<CountryAttitude> getCountryAttitudes() { return countryAttitudes; } |
From: <hib...@li...> - 2006-05-01 01:06:09
|
Author: epbernard Date: 2006-04-30 21:05:59 -0400 (Sun, 30 Apr 2006) New Revision: 9839 Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/CloudType.hbm.xml trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/CloudType.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/Sky.java Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/HbmTest.java Log: more tests one hbm / annotations links Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/CloudType.hbm.xml =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/CloudType.hbm.xml 2006-04-30 19:00:59 UTC (rev 9838) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/CloudType.hbm.xml 2006-05-01 01:05:59 UTC (rev 9839) @@ -0,0 +1,15 @@ +<?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.annotations.xml.hbm"> + + <class name="CloudType"> + <id name="id"> + <generator class="native"/> + </id> + <property name="name"/> + </class> + +</hibernate-mapping> \ No newline at end of file Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/CloudType.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/CloudType.java 2006-04-30 19:00:59 UTC (rev 9838) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/CloudType.java 2006-05-01 01:05:59 UTC (rev 9839) @@ -0,0 +1,26 @@ +//$Id: $ +package org.hibernate.test.annotations.xml.hbm; + +/** + * @author Emmanuel Bernard + */ +public class CloudType { + private Integer id; + private String name; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/HbmTest.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/HbmTest.java 2006-04-30 19:00:59 UTC (rev 9838) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/HbmTest.java 2006-05-01 01:05:59 UTC (rev 9839) @@ -49,6 +49,20 @@ s.close(); } + public void testManyToMany() throws Exception { + Session s = openSession(); + s.getTransaction().begin(); + CloudType type = new CloudType(); + type.setName( "Cumulus" ); + Sky sky = new Sky(); + s.persist( type ); + sky.getCloudTypes().add(type); + s.persist( sky ); + s.flush(); + s.getTransaction().rollback(); + s.close(); + } + @Override protected void configure(Configuration cfg) { super.configure( cfg ); @@ -57,14 +71,16 @@ protected Class[] getMappings() { return new Class[]{ - PrimeMinister.class + PrimeMinister.class, + Sky.class }; } @Override protected String[] getXmlFiles() { return new String[]{ - "org/hibernate/test/annotations/xml/hbm/Government.hbm.xml" + "org/hibernate/test/annotations/xml/hbm/Government.hbm.xml", + "org/hibernate/test/annotations/xml/hbm/CloudType.hbm.xml" }; } } Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/Sky.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/Sky.java 2006-04-30 19:00:59 UTC (rev 9838) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/xml/hbm/Sky.java 2006-05-01 01:05:59 UTC (rev 9839) @@ -0,0 +1,47 @@ +//$Id: $ +package org.hibernate.test.annotations.xml.hbm; + +import java.util.HashSet; +import java.util.Set; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; + +/** + * @author Emmanuel Bernard + */ +@Entity(name="EarthSky") +public class Sky { + private Integer id; + private Set<CloudType> cloudTypes = new HashSet<CloudType>(); + private CloudType mainCloud; + + @ManyToMany + public Set<CloudType> getCloudTypes() { + return cloudTypes; + } + + public void setCloudTypes(Set<CloudType> cloudTypes) { + this.cloudTypes = cloudTypes; + } + + @Id @GeneratedValue + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @ManyToOne + public CloudType getMainCloud() { + return mainCloud; + } + + public void setMainCloud(CloudType mainCloud) { + this.mainCloud = mainCloud; + } +} |
Author: epbernard Date: 2006-04-30 15:00:59 -0400 (Sun, 30 Apr 2006) New Revision: 9838 Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/IndexSecondPass.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/EntityTest.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/Flight.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/strategy/Storm.java Log: ANN-305 indexes used the physical column name rather than logical one Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/IndexSecondPass.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/IndexSecondPass.java 2006-04-30 16:56:11 UTC (rev 9837) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/IndexSecondPass.java 2006-04-30 19:00:59 UTC (rev 9838) @@ -41,7 +41,7 @@ } if ( column != null ) { this.table = column.getTable(); - addIndexToColumn( column.getName() ); + addIndexToColumn( mappings.getLogicalColumnName( column.getName(), table ) ); } } Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/EntityTest.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/EntityTest.java 2006-04-30 16:56:11 UTC (rev 9837) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/EntityTest.java 2006-04-30 19:00:59 UTC (rev 9838) @@ -311,6 +311,7 @@ airFrance.setDepartureDate( new Date( 05, 06, 21, 10, 0, 0 ) ); airFrance.setAlternativeDepartureDate( new GregorianCalendar( 2006, 02, 03, 10, 00 ) ); airFrance.getAlternativeDepartureDate().setTimeZone( TimeZone.getTimeZone( "GMT" ) ); + airFrance.setBuyDate( new java.sql.Timestamp(122367443) ); airFrance.setFactor( 25 ); s.persist( airFrance ); tx.commit(); @@ -326,6 +327,7 @@ new Date( 05, 06, 21 ), copyAirFrance.getDepartureDate() ); + assertEquals( airFrance.getBuyDate(), copyAirFrance.getBuyDate()); s.delete( copyAirFrance ); tx.commit(); s.close(); Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/Flight.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/Flight.java 2006-04-30 16:56:11 UTC (rev 9837) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/Flight.java 2006-04-30 19:00:59 UTC (rev 9838) @@ -36,6 +36,7 @@ String triggeredData; long factor; Date departureDate; + java.sql.Timestamp buyDate; Calendar alternativeDepartureDate; @Id @@ -137,4 +138,12 @@ this.alternativeDepartureDate = alternativeDepartureDate; } + public java.sql.Timestamp getBuyDate() { + return buyDate; + } + + public void setBuyDate(java.sql.Timestamp buyDate) { + this.buyDate = buyDate; + } + } \ No newline at end of file Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/strategy/Storm.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/strategy/Storm.java 2006-04-30 16:56:11 UTC (rev 9837) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/strategy/Storm.java 2006-04-30 19:00:59 UTC (rev 9838) @@ -1,13 +1,16 @@ //$Id$ package org.hibernate.test.annotations.strategy; +import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; +import javax.persistence.UniqueConstraint; import javax.persistence.Table; -import javax.persistence.UniqueConstraint; +import org.hibernate.annotations.Index; + /** * @author Emmanuel Bernard */ @@ -17,6 +20,7 @@ private Integer id; private Location start; private Location end; + private String stormName; @Id @GeneratedValue @@ -45,4 +49,14 @@ public void setEnd(Location end) { this.end = end; } + + @Index(name="storm_name_idx") + @Column(unique = true) + public String getStormName() { + return stormName; + } + + public void setStormName(String name) { + this.stormName = name; + } } |
From: <hib...@li...> - 2006-04-30 16:56:13
|
Author: epbernard Date: 2006-04-30 12:56:11 -0400 (Sun, 30 Apr 2006) New Revision: 9837 Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java Log: ANN-293 better user firendly error when annotations are wrongly used Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java 2006-04-30 16:44:28 UTC (rev 9836) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java 2006-04-30 16:56:11 UTC (rev 9837) @@ -14,6 +14,7 @@ import javax.persistence.ManyToMany; import javax.persistence.MapKey; import javax.persistence.OneToMany; +import javax.persistence.JoinTable; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -780,6 +781,24 @@ log.debug( "Binding a collection of element: " + path ); } } + //check for user error + if ( ! isCollectionOfEntities ) { + if ( property.isAnnotationPresent( ManyToMany.class ) || property.isAnnotationPresent( OneToMany.class )) { + String path = collValue.getOwnerEntityName() + "." + joinColumns[0].getPropertyName(); + throw new AnnotationException( + "Use of @OneToMany or @ManyToMany targeting an unmapped class: " + path + "[" + collType + "]" + ); + } + else { + JoinTable joinTableAnn = property.getAnnotation( JoinTable.class ); + if (joinTableAnn != null && joinTableAnn.inverseJoinColumns().length > 0) { + String path = collValue.getOwnerEntityName() + "." + joinColumns[0].getPropertyName(); + throw new AnnotationException( + "Use of @JoinTable.inverseJoinColumns targeting an unmapped class: " + path + "[" + collType + "]" + ); + } + } + } boolean mappedBy = ! AnnotationBinder.isDefault( joinColumns[0].getMappedBy() ); if ( mappedBy ) { if ( ! isCollectionOfEntities ) { |
From: <hib...@li...> - 2006-04-30 16:44:30
|
Author: epbernard Date: 2006-04-30 12:44:28 -0400 (Sun, 30 Apr 2006) New Revision: 9836 Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytoone/Customer.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytoone/Deal.java Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/Company.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytoone/ManyToOneTest.java Log: ANN-307 exclude noop and embedded property accessor when finding the appropriate property per columns Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/Company.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/Company.java 2006-04-30 16:34:04 UTC (rev 9835) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/Company.java 2006-04-30 16:44:28 UTC (rev 9836) @@ -2,6 +2,8 @@ package org.hibernate.test.annotations; import java.io.Serializable; +import java.util.Date; +import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @@ -37,4 +39,8 @@ name = string; } + //should be treated as getter + private int[] getWorkingHoursPerWeek(Set<Date> holidayDays) { + return null; + } } Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytoone/Customer.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytoone/Customer.java 2006-04-30 16:34:04 UTC (rev 9835) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytoone/Customer.java 2006-04-30 16:44:28 UTC (rev 9836) @@ -0,0 +1,16 @@ +//$Id: $ +package org.hibernate.test.annotations.manytoone; + +import java.io.Serializable; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +/** + * @author Emmanuel Bernard + */ +@Entity(name="DealedCustomer") +public class Customer implements Serializable { + @Id @GeneratedValue public Integer id; + public String userId; +} Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytoone/Deal.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytoone/Deal.java 2006-04-30 16:34:04 UTC (rev 9835) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytoone/Deal.java 2006-04-30 16:44:28 UTC (rev 9836) @@ -0,0 +1,19 @@ +//$Id: $ +package org.hibernate.test.annotations.manytoone; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.GeneratedValue; +import javax.persistence.ManyToOne; +import javax.persistence.JoinColumn; + +/** + * @author Emmanuel Bernard + */ +@Entity +public class Deal { + @Id @GeneratedValue public Integer id; + @ManyToOne @JoinColumn(referencedColumnName = "userId") public Customer from; + @ManyToOne @JoinColumn(referencedColumnName = "userId") public Customer to; + +} Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytoone/ManyToOneTest.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytoone/ManyToOneTest.java 2006-04-30 16:34:04 UTC (rev 9835) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytoone/ManyToOneTest.java 2006-04-30 16:44:28 UTC (rev 9836) @@ -261,11 +261,36 @@ s.close(); } + public void testTwoManyToOneNonPk() throws Exception { + //2 many to one non pk pointing to the same referencedColumnName should not fail + Session s = openSession(); + Transaction tx = s.beginTransaction(); + org.hibernate.test.annotations.manytoone.Customer customer = new org.hibernate.test.annotations.manytoone.Customer(); + customer.userId="123"; + org.hibernate.test.annotations.manytoone.Customer customer2 = new org.hibernate.test.annotations.manytoone.Customer(); + customer2.userId="124"; + s.persist( customer2 ); + s.persist( customer ); + Deal deal = new Deal(); + deal.from = customer; + deal.to = customer2; + s.persist( deal ); + s.flush(); + s.clear(); + deal = (Deal) s.get( Deal.class, deal.id ); + assertNotNull( deal.from ); + assertNotNull( deal.to ); + tx.rollback(); + s.close(); + } + /** * @see org.hibernate.test.annotations.TestCase#getMappings() */ protected java.lang.Class[] getMappings() { return new java.lang.Class[]{ + Deal.class, + org.hibernate.test.annotations.manytoone.Customer.class, Car.class, Color.class, Flight.class, |
From: <hib...@li...> - 2006-04-30 16:34:14
|
Author: epbernard Date: 2006-04-30 12:34:04 -0400 (Sun, 30 Apr 2006) New Revision: 9835 Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/BinderHelper.java Log: ANN-307 exclude noop and embedded property accessor when finding the appropriate property per columns Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/BinderHelper.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/BinderHelper.java 2006-04-30 04:21:48 UTC (rev 9834) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/BinderHelper.java 2006-04-30 16:34:04 UTC (rev 9835) @@ -188,7 +188,7 @@ ExtendedMappings mappings ) { Map<Column, Set<Property>> columnsToProperty = new HashMap<Column, Set<Property>>(); - List<Column> orderedColumns = new ArrayList<Column>(); + List<Column> orderedColumns = new ArrayList<Column>( columns.length ); Table referencedTable = null; if ( columnOwner instanceof PersistentClass ) { referencedTable = ( (PersistentClass) columnOwner ).getTable(); @@ -200,9 +200,10 @@ throw new AssertionFailure( columnOwner == null ? "columnOwner is null" : - "columnOwner neither PersistentClass not Join: " + columnOwner.getClass() + "columnOwner neither PersistentClass nor Join: " + columnOwner.getClass() ); } + //build the list of column names for ( int index = 0; index < columns.length ; index++ ) { Column column = new Column( mappings.getPhysicalColumnName( columns[index].getReferencedColumn(), referencedTable ) @@ -215,6 +216,10 @@ ( (Join) columnOwner ).getPropertyIterator(); while ( it.hasNext() ) { Property property = (Property) it.next(); + if ( "noop".equals( property.getPropertyAccessorName() ) + || "embedded".equals( property.getPropertyAccessorName() ) ) { + continue; + } Iterator columnIt = property.getColumnIterator(); while ( columnIt.hasNext() ) { Column column = (Column) columnIt.next(); |