[hibernate-commits] Hibernate SVN: r10534 - in trunk/HibernateExt/metadata/src: java/org/hibernate/annotations java/org/hibernate/cfg java/org/hibernate/cfg/annotations test/org/hibernate/test/annotations/manytomany

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Thu Sep 28 17:24:46 EDT 2006


Author: epbernard
Date: 2006-09-28 17:24:44 -0400 (Thu, 28 Sep 2006)
New Revision: 10534

Added:
   trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/FilterJoinTable.java
   trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/FilterJoinTables.java
   trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/WhereJoinTable.java
Modified:
   trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Filter.java
   trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Filters.java
   trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Where.java
   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/test/org/hibernate/test/annotations/manytomany/Group.java
   trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytomany/ManyToManyTest.java
Log:
ANN-346
ANN-447
Introduce where clause and filters on association tables

Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Filter.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Filter.java	2006-09-28 15:35:26 UTC (rev 10533)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Filter.java	2006-09-28 21:24:44 UTC (rev 10534)
@@ -7,7 +7,7 @@
 import java.lang.annotation.Target;
 
 /**
- * Add filters to an entity or a collection
+ * Add filters to an entity or a target entity of a collection
  *
  * @author Emmanuel Bernard
  * @author Matthew Inger

Added: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/FilterJoinTable.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/FilterJoinTable.java	2006-09-28 15:35:26 UTC (rev 10533)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/FilterJoinTable.java	2006-09-28 21:24:44 UTC (rev 10534)
@@ -0,0 +1,20 @@
+//$Id: $
+package org.hibernate.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Add filters to a join table collection
+ *
+ * @author Emmanuel Bernard
+ */
+ at Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+ at Retention(RetentionPolicy.RUNTIME)
+public @interface FilterJoinTable {
+	String name();
+
+	String condition() default "";
+}

Added: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/FilterJoinTables.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/FilterJoinTables.java	2006-09-28 15:35:26 UTC (rev 10533)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/FilterJoinTables.java	2006-09-28 21:24:44 UTC (rev 10534)
@@ -0,0 +1,18 @@
+//$Id: $
+package org.hibernate.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Add multiple @FilterJoinTable to a collection
+ *
+ * @author Emmanuel Bernard
+ */
+ at Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+ at Retention(RetentionPolicy.RUNTIME)
+public @interface FilterJoinTables {
+	FilterJoinTable[] value();
+}

Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Filters.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Filters.java	2006-09-28 15:35:26 UTC (rev 10533)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Filters.java	2006-09-28 21:24:44 UTC (rev 10534)
@@ -7,7 +7,7 @@
 import java.lang.annotation.Target;
 
 /**
- * Add multiple filters to an entity or a collection
+ * Add multiple @Filters
  *
  * @author Emmanuel Bernard
  * @author Matthew Inger

Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Where.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Where.java	2006-09-28 15:35:26 UTC (rev 10533)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/Where.java	2006-09-28 21:24:44 UTC (rev 10534)
@@ -6,7 +6,7 @@
 import java.lang.annotation.Target;
 
 /**
- * Where clause to add to the element (Class or Collection)
+ * Where clause to add to the element Entity or target entity of a collection
  *
  * @author Emmanuel Bernard
  */

Added: trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/WhereJoinTable.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/WhereJoinTable.java	2006-09-28 15:35:26 UTC (rev 10533)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/annotations/WhereJoinTable.java	2006-09-28 21:24:44 UTC (rev 10534)
@@ -0,0 +1,18 @@
+//$Id: $
+package org.hibernate.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Where clause to add to the colleciton join table
+ *
+ * @author Emmanuel Bernard
+ */
+ at Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+ at Retention(RetentionPolicy.RUNTIME)
+public @interface WhereJoinTable {
+	String clause();
+}

Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java	2006-09-28 15:35:26 UTC (rev 10533)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java	2006-09-28 21:24:44 UTC (rev 10534)
@@ -1327,19 +1327,7 @@
 			collectionBinder.setSort( sortAnn );
 			Cache cachAnn = property.getAnnotation( Cache.class );
 			collectionBinder.setCache( cachAnn );
-			Filter filterAnn = property.getAnnotation( Filter.class );
-			if ( filterAnn != null ) {
-				collectionBinder.addFilter( filterAnn.name(), filterAnn.condition() );
-			}
-			Filters filtersAnn = property.getAnnotation( Filters.class );
-			if ( filtersAnn != null ) {
-				for ( Filter filter : filtersAnn.value() ) {
-					collectionBinder.addFilter( filter.name(), filter.condition() );
-				}
-			}
 			collectionBinder.setPropertyHolder( propertyHolder );
-			Where whereAnn = property.getAnnotation( Where.class );
-			collectionBinder.setWhere( whereAnn );
 			Cascade hibernateCascade = property.getAnnotation( Cascade.class );
 			NotFound notFound = property.getAnnotation( NotFound.class );
 			boolean ignoreNotFound = notFound != null && notFound.action().equals( NotFoundAction.IGNORE );

Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java	2006-09-28 15:35:26 UTC (rev 10533)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java	2006-09-28 21:24:44 UTC (rev 10534)
@@ -35,6 +35,11 @@
 import org.hibernate.annotations.Sort;
 import org.hibernate.annotations.SortType;
 import org.hibernate.annotations.Where;
+import org.hibernate.annotations.Filter;
+import org.hibernate.annotations.Filters;
+import org.hibernate.annotations.FilterJoinTable;
+import org.hibernate.annotations.FilterJoinTables;
+import org.hibernate.annotations.WhereJoinTable;
 import org.hibernate.cfg.AnnotatedClassType;
 import org.hibernate.cfg.AnnotationBinder;
 import org.hibernate.cfg.BinderHelper;
@@ -82,7 +87,6 @@
 	protected String propertyName;
 	PropertyHolder propertyHolder;
 	int batchSize;
-	String where;
 	private String mappedBy;
 	private XClass collectionType;
 	private XClass targetEntity;
@@ -90,7 +94,6 @@
 	private Ejb3JoinColumn[] inverseJoinColumns;
 	private String cascadeStrategy;
 	String cacheConcurrencyStrategy;
-	Map<String, String> filters = new HashMap<String, String>();
 	String cacheRegionName;
 	private boolean oneToMany;
 	protected IndexColumn indexColumn;
@@ -329,25 +332,6 @@
 			collection.setCacheRegionName( cacheRegionName );
 		}
 
-		//set filtering
-		Iterator<Map.Entry<String, String>> iter = filters.entrySet().iterator();
-		if ( StringHelper.isNotEmpty( where ) ) collection.setWhere( where );
-		while ( iter.hasNext() ) {
-			Map.Entry<String, String> filter = iter.next();
-			String name = filter.getKey();
-			String cond = filter.getValue();
-			if ( BinderHelper.isDefault( cond ) ) {
-				cond = mappings.getFilterDefinition( name ).getDefaultFilterCondition();
-				if ( StringHelper.isEmpty( cond ) ) {
-					throw new AnnotationException(
-							"no filter condition found for filter " + name + " in "
-									+ StringHelper.qualify( propertyHolder.getPath(), propertyName )
-					);
-				}
-			}
-			collection.addFilter( name, cond );
-		}
-
 		//work on association
 		boolean isMappedBy = ! BinderHelper.isDefault( mappedBy );
 		collection.setInverse( isMappedBy );
@@ -594,7 +578,7 @@
 		log.info(
 				"Mapping collection: " + collection.getRole() + " -> " + collection.getCollectionTable().getName()
 		);
-
+		bindFilters(false);
 		bindCollectionSecondPass( collection, null, fkJoinColumns, cascadeDeleteEnabled, property, mappings );
 		if ( !collection.isInverse()
 				&& !collection.getKey().isNullable() ) {
@@ -612,6 +596,119 @@
 		}
 	}
 
+	private void bindFilters(boolean hasAssociationTable) {
+		Filter simpleFilter = property.getAnnotation( Filter.class );
+		//set filtering
+		//test incompatible choices
+		//if ( StringHelper.isNotEmpty( where ) ) collection.setWhere( where );
+		if (simpleFilter != null) {
+			if (hasAssociationTable) {
+				collection.addManyToManyFilter( simpleFilter.name(), getCondition( simpleFilter ) );
+			}
+			else {
+				collection.addFilter( simpleFilter.name(), getCondition( simpleFilter ) );
+			}
+		}
+		Filters filters = property.getAnnotation( Filters.class );
+		if (filters != null) {
+			for ( Filter filter : filters.value() ) {
+				if (hasAssociationTable) {
+					collection.addManyToManyFilter( filter.name(), getCondition( filter ) );
+				}
+				else {
+					collection.addFilter( filter.name(), getCondition( filter ) );
+				}
+			}
+		}
+		FilterJoinTable simpleFilterJoinTable = property.getAnnotation( FilterJoinTable.class );
+		if (simpleFilterJoinTable != null) {
+			if (hasAssociationTable) {
+				collection.addFilter( simpleFilterJoinTable.name(), getCondition( simpleFilterJoinTable ) );
+			}
+			else {
+				throw new AnnotationException(
+						"Illegal use of @FilterJoinTable on an association without join table:"
+								+ StringHelper.qualify( propertyHolder.getPath(), propertyName )
+				);
+			}
+		}
+		FilterJoinTables filterJoinTables = property.getAnnotation( FilterJoinTables.class );
+		if (filterJoinTables != null) {
+			for ( FilterJoinTable filter : filterJoinTables.value() ) {
+				if (hasAssociationTable) {
+					collection.addFilter( filter.name(), getCondition( filter ) );
+				}
+				else {
+					throw new AnnotationException(
+							"Illegal use of @FilterJoinTable on an association without join table:"
+									+ StringHelper.qualify( propertyHolder.getPath(), propertyName )
+					);
+				}
+			}
+		}
+
+		Where where = property.getAnnotation( Where.class );
+		String whereClause = where == null ? null : where.clause();
+		if ( StringHelper.isNotEmpty( whereClause ) ) {
+			if (hasAssociationTable) {
+				collection.setManyToManyWhere( whereClause );
+			}
+			else {
+				collection.setWhere( whereClause );
+			}
+		}
+
+		WhereJoinTable whereJoinTable = property.getAnnotation( WhereJoinTable.class );
+		String whereJoinTableClause = whereJoinTable == null ? null : whereJoinTable.clause();
+		if ( StringHelper.isNotEmpty( whereJoinTableClause ) ) {
+			if (hasAssociationTable) {
+				collection.setWhere( whereJoinTableClause );
+			}
+			else {
+				throw new AnnotationException(
+						"Illegal use of @WhereJoinTable on an association without join table:"
+								+ StringHelper.qualify( propertyHolder.getPath(), propertyName )
+				);
+			}
+		}
+//		This cannot happen in annotations since the second fetch is hardcoded to join
+//		if ( ( ! collection.getManyToManyFilterMap().isEmpty() || collection.getManyToManyWhere() != null ) &&
+//		        collection.getFetchMode() == FetchMode.JOIN &&
+//		        collection.getElement().getFetchMode() != FetchMode.JOIN ) {
+//			throw new MappingException(
+//			        "association with join table  defining filter or where without join fetching " +
+//			        "not valid within collection using join fetching [" + collection.getRole() + "]"
+//				);
+//		}
+	}
+
+	private String getCondition(FilterJoinTable filter) {
+		//set filtering
+		String name = filter.name();
+		String cond = filter.condition();
+		return getCondition( cond, name );
+	}
+
+	private String getCondition(Filter filter) {
+		//set filtering
+		String name = filter.name();
+		String cond = filter.condition();
+		return getCondition( cond, name );
+	}
+
+	private String getCondition(String cond, String name) {
+		if ( BinderHelper.isDefault( cond ) ) {
+			cond = mappings.getFilterDefinition( name ).getDefaultFilterCondition();
+			if ( StringHelper.isEmpty( cond ) ) {
+				throw new AnnotationException(
+						"no filter condition found for filter " + name + " in "
+								+ StringHelper.qualify( propertyHolder.getPath(), propertyName )
+				);
+			}
+		}
+		return cond;
+	}
+
 	public void setCache(Cache cacheAnn) {
 		if ( cacheAnn != null ) {
 			cacheRegionName = BinderHelper.isDefault( cacheAnn.region() ) ? null : cacheAnn.region();
@@ -623,16 +720,6 @@
 		}
 	}
 
-	public void addFilter(String name, String condition) {
-		filters.put( name, condition );
-	}
-
-	public void setWhere(Where whereAnn) {
-		if ( whereAnn != null ) {
-			where = whereAnn.clause();
-		}
-	}
-
 	public void setOneToMany(boolean oneToMany) {
 		this.oneToMany = oneToMany;
 	}
@@ -854,7 +941,7 @@
 		return key;
 	}
 
-	protected static void bindManyToManySecondPass(
+	protected void bindManyToManySecondPass(
 			Collection collValue,
 			Map persistentClasses,
 			Ejb3JoinColumn[] joinColumns,
@@ -970,7 +1057,7 @@
 			}
 			collValue.setCollectionTable( associationTableBinder.bind() );
 		}
-
+		bindFilters( isCollectionOfEntities );
 		bindCollectionSecondPass( collValue, collectionEntity, joinColumns, cascadeDeleteEnabled, property, mappings );
 
 		ManyToOne element = null;

Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytomany/Group.java
===================================================================
--- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytomany/Group.java	2006-09-28 15:35:26 UTC (rev 10533)
+++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytomany/Group.java	2006-09-28 21:24:44 UTC (rev 10534)
@@ -8,15 +8,22 @@
 import javax.persistence.JoinColumn;
 import javax.persistence.JoinTable;
 import javax.persistence.ManyToMany;
+import javax.persistence.OrderBy;
 import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
-import javax.persistence.OrderBy;
 
+import org.hibernate.annotations.Where;
+import org.hibernate.annotations.FilterDef;
+import org.hibernate.annotations.Filter;
+import org.hibernate.annotations.FilterJoinTable;
+import org.hibernate.annotations.WhereJoinTable;
+
 /**
  * @author Emmanuel Bernard
  */
 @Entity
 @Table(name = "tbl_group")
+ at FilterDef(name="Groupfilter")
 public class Group {
 	private Integer id;
 	private Collection<Permission> permissions;
@@ -37,6 +44,10 @@
 			inverseJoinColumns = @JoinColumn(name = "permission", referencedColumnName = "permission")
 	)
 	@OrderBy("expirationDate")
+	@Where(clause = "1=1")
+	@WhereJoinTable(clause = "2=2")
+	@Filter(name="Groupfilter", condition = "3=3")
+	@FilterJoinTable(name="Groupfilter", condition = "4=4")
 	public Collection<Permission> getPermissions() {
 		return permissions;
 	}

Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytomany/ManyToManyTest.java
===================================================================
--- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytomany/ManyToManyTest.java	2006-09-28 15:35:26 UTC (rev 10533)
+++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/manytomany/ManyToManyTest.java	2006-09-28 21:24:44 UTC (rev 10534)
@@ -441,6 +441,7 @@
 
 	public void testAssociationTableAndOrderBy() throws Exception {
 		Session s = openSession();
+		s.enableFilter( "Groupfilter" );
 		Permission readAccess = new Permission();
 		readAccess.setPermission( "read" );
 		readAccess.setExpirationDate( new Date() );
@@ -458,6 +459,7 @@
 		s.flush();
 		s.clear();
 		group = (Group) s.get( Group.class, group.getId() );
+		s.createQuery( "select g from Group g join fetch g.permissions").list();
 		assertEquals( "write", group.getPermissions().iterator().next().getPermission() );
 		s.getTransaction().rollback();
 		s.close();




More information about the hibernate-commits mailing list