|
From: <hib...@li...> - 2006-05-05 18:01:45
|
Author: epbernard
Date: 2006-05-05 14:01:32 -0400 (Fri, 05 May 2006)
New Revision: 9894
Modified:
trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java
trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java
trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/SingleTableTest.java
trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/onetomany/City.java
Log:
ANN-120 support association table MapKey through formula
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-05 16:58:38 UTC (rev 9893)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java 2006-05-05 18:01:32 UTC (rev 9894)
@@ -4,6 +4,7 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.Random;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Embeddable;
@@ -12,6 +13,9 @@
import org.hibernate.AssertionFailure;
import org.hibernate.FetchMode;
import org.hibernate.MappingException;
+import org.hibernate.dialect.HSQLDialect;
+import org.hibernate.sql.Template;
+import org.hibernate.util.StringHelper;
import org.hibernate.annotations.AccessType;
import org.hibernate.cfg.AnnotatedClassType;
import org.hibernate.cfg.AnnotationBinder;
@@ -28,12 +32,16 @@
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
+import org.hibernate.mapping.DependantValue;
import org.hibernate.mapping.Formula;
import org.hibernate.mapping.Join;
import org.hibernate.mapping.ManyToOne;
+import org.hibernate.mapping.OneToMany;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.Table;
+import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.Value;
import org.hibernate.reflection.XAnnotatedElement;
import org.hibernate.reflection.XClass;
@@ -69,7 +77,8 @@
);
bindKeyFromAssociationTable(
collType, persistentClasses, mapKeyPropertyName, property, isEmbedded, mappings,
- mapKeyColumns, mapKeyManyToManyColumns
+ mapKeyColumns, mapKeyManyToManyColumns,
+ inverseColumns != null ? inverseColumns[0].getPropertyName() : null
);
}
};
@@ -78,7 +87,7 @@
private void bindKeyFromAssociationTable(
String collType, Map persistentClasses, String mapKeyPropertyName, XProperty property,
boolean isEmbedded, ExtendedMappings mappings, Ejb3Column[] mapKeyColumns,
- Ejb3JoinColumn[] mapKeyManyToManyColumns
+ Ejb3JoinColumn[] mapKeyManyToManyColumns, String targetPropertyName
) {
if ( mapKeyPropertyName != null ) {
//this is an EJB3 @MapKey
@@ -91,7 +100,7 @@
);
}
org.hibernate.mapping.Map map = (org.hibernate.mapping.Map) this.collection;
- Value indexValue = createFormulatedValue( mapProperty.getValue(), map );
+ Value indexValue = createFormulatedValue( mapProperty.getValue(), map, targetPropertyName, associatedClass );
map.setIndex( indexValue );
}
else {
@@ -218,7 +227,52 @@
}
}
- protected Value createFormulatedValue(Value value, Collection collection) {
+ protected Value createFormulatedValue(
+ Value value, Collection collection, String targetPropertyName, PersistentClass associatedClass
+ ) {
+ Value element = collection.getElement();
+ String fromAndWhere = null;
+ if ( ! ( element instanceof OneToMany ) ) {
+ String referencedPropertyName= null;
+ if ( element instanceof ToOne ) {
+ referencedPropertyName = ( (ToOne) element ).getReferencedPropertyName();
+ }
+ else if ( element instanceof DependantValue ) {
+ //TODO this never happen I think
+ if ( propertyName != null ) {
+ Collection coll = (Collection) associatedClass.getProperty( propertyName )
+ .getValue();
+ referencedPropertyName = collection.getReferencedPropertyName();
+ }
+ else {
+ throw new AnnotationException( "SecondaryTable JoinColumn cannot reference a non primary key" );
+ }
+ }
+ Table table;
+ Iterator referencedEntityColumns;
+ if (referencedPropertyName == null) {
+ table = associatedClass.getTable();
+ referencedEntityColumns = associatedClass.getIdentifier().getColumnIterator();
+ }
+ else {
+ Property referencedProperty = associatedClass.getProperty( referencedPropertyName );
+ table = referencedProperty.getValue().getTable();
+ referencedEntityColumns = referencedProperty.getColumnIterator();
+ }
+ String alias = "$alias$";
+ StringBuilder fromAndWhereSb = new StringBuilder( " from " )
+ .append( associatedClass.getTable().getName() )
+ .append(" as ").append(alias).append(" where ");
+ Iterator collectionTableColumns = element.getColumnIterator();
+ while ( collectionTableColumns.hasNext() ) {
+ Column colColumn = (Column) collectionTableColumns.next();
+ Column refColumn = (Column) referencedEntityColumns.next();
+ fromAndWhereSb.append(alias).append('.').append( refColumn.getQuotedName() )
+ .append('=').append( colColumn.getQuotedName() ).append(',');
+ }
+ fromAndWhere = fromAndWhereSb.substring(0, fromAndWhereSb.length() - 1 );
+ }
+
if ( value instanceof Component ) {
Component component = (Component) value;
Iterator properties = component.getPropertyIterator();
@@ -239,7 +293,9 @@
newProperty.setPersistentClass( current.getPersistentClass() );
newProperty.setPropertyAccessorName( current.getPropertyAccessorName() );
newProperty.setSelectable( current.isSelectable() );
- newProperty.setValue( createFormulatedValue( current.getValue(), collection) );
+ newProperty.setValue( createFormulatedValue( current.getValue(), collection, targetPropertyName,
+ associatedClass
+ ) );
indexComponent.addProperty( newProperty );
}
return indexComponent;
@@ -262,19 +318,31 @@
targetValue.setTypeParameters( sourceValue.getTypeParameters() );
}
Iterator columns = sourceValue.getColumnIterator();
+ Random random = new Random();
while ( columns.hasNext() ) {
Object current = columns.next();
Formula formula = new Formula();
+ String formulaString;
if ( current instanceof Column ) {
- formula.setFormula( ( (Column) current ).getName() );
+ formulaString = ( (Column) current ).getName();
//FIXME support quoted name
}
else if ( current instanceof Formula ) {
- formula.setFormula( ( (Formula) current ).getFormula() );
+ formulaString = ( (Formula) current ).getFormula();
}
else {
throw new AssertionFailure( "Unknown element in column iterator: " + current.getClass() );
}
+ if (fromAndWhere != null) {
+ formulaString = Template.renderWhereStringTemplate( formulaString, "$alias$", new HSQLDialect() );
+ formulaString = "select " + formulaString + fromAndWhere;
+ formulaString = StringHelper.replace(
+ formulaString,
+ "$alias$",
+ "a" + random.nextInt( 16 )
+ );
+ }
+ formula.setFormula( formulaString );
targetValue.addFormula( formula );
}
Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java
===================================================================
--- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java 2006-05-05 16:58:38 UTC (rev 9893)
+++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java 2006-05-05 18:01:32 UTC (rev 9894)
@@ -214,12 +214,12 @@
s = openSession();
tx = s.beginTransaction();
s.enableFilter( "betweenLength" ).setParameter( "minLength", 5 ).setParameter( "maxLength", 50 );
- int count = ( (Integer) s.createQuery( "select count(*) from Forest" ).iterate().next() ).intValue();
+ long count = ( (Long) s.createQuery( "select count(*) from Forest" ).iterate().next() ).intValue();
assertEquals( 1, count );
s.disableFilter( "betweenLength" );
s.enableFilter( "minLength" ).setParameter( "minLength", 5 );
- count = ( (Integer) s.createQuery( "select count(*) from Forest" ).iterate().next() ).intValue();
- assertEquals( 2, count );
+ count = ( (Long) s.createQuery( "select count(*) from Forest" ).iterate().next() ).longValue();
+ assertEquals( 2l, count );
s.disableFilter( "minLength" );
tx.rollback();
s.close();
Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/SingleTableTest.java
===================================================================
--- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/SingleTableTest.java 2006-05-05 16:58:38 UTC (rev 9893)
+++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/SingleTableTest.java 2006-05-05 18:01:32 UTC (rev 9894)
@@ -41,7 +41,7 @@
s = openSession();
tx = s.beginTransaction();
- assertEquals( 1, s.createQuery( "select count(*) from Fruit f where f.class = 'Apple'" ).uniqueResult() );
+ assertEquals( 1l, s.createQuery( "select count(*) from Fruit f where f.class = 'Apple'" ).uniqueResult() );
List result = s.createCriteria( Fruit.class ).list();
assertNotNull( result );
assertEquals( 2, result.size() );
@@ -70,7 +70,7 @@
s = openSession();
tx = s.beginTransaction();
assertEquals(
- 1, s.createQuery( "select count(*) from Trash f where f.class = :disc" )
+ 1l, s.createQuery( "select count(*) from Trash f where f.class = :disc" )
.setString( "disc", String.valueOf( "PaperTrash".hashCode() ) ).uniqueResult()
);
List result = s.createCriteria( Trash.class ).list();
Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/onetomany/City.java
===================================================================
--- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/onetomany/City.java 2006-05-05 16:58:38 UTC (rev 9893)
+++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/onetomany/City.java 2006-05-05 18:01:32 UTC (rev 9894)
@@ -14,7 +14,7 @@
* @author Emmanuel Bernard
*/
@Entity
-public class City {
+class City {
private Integer id;
private String name;
private List<Street> streets;
@@ -40,7 +40,7 @@
@OneToMany(mappedBy = "city")
@OrderBy("streetName, id")
- public List<Street> getStreets() {
+ public synchronized List<Street> getStreets() {
return streets;
}
|