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();
|