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
+ */
+(a)Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+(a)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
+ */
+(a)Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+(a)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
+ */
+(a)Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+(a)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")
+@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();