HHH-7037 adding custom sql for collections

This commit is contained in:
Hardy Ferentschik 2012-03-07 16:33:22 +01:00
parent 0eb42b3891
commit 3e22da0552
4 changed files with 137 additions and 58 deletions

View File

@ -33,10 +33,12 @@ import org.hibernate.AnnotationException;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.internal.source.annotations.entity.EntityBindingContext;
import org.hibernate.metamodel.internal.source.annotations.util.AnnotationParserHelper;
import org.hibernate.metamodel.internal.source.annotations.util.HibernateDotNames;
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.spi.binding.Caching;
import org.hibernate.metamodel.spi.binding.CustomSQL;
/**
* Represents an collection (collection, list, set, map) association attribute.
@ -48,6 +50,10 @@ public class PluralAssociationAttribute extends AssociationAttribute {
private final String orderBy;
private final Caching caching;
private final String customPersister;
private final CustomSQL customInsert;
private final CustomSQL customUpdate;
private final CustomSQL customDelete;
// Used for the non-owning side of a ManyToMany relationship
private final String inverseForeignKeyName;
@ -88,6 +94,18 @@ public class PluralAssociationAttribute extends AssociationAttribute {
return customPersister;
}
public CustomSQL getCustomInsert() {
return customInsert;
}
public CustomSQL getCustomUpdate() {
return customUpdate;
}
public CustomSQL getCustomDelete() {
return customDelete;
}
private PluralAssociationAttribute(String name,
Class<?> javaType,
AttributeNature associationType,
@ -100,6 +118,15 @@ public class PluralAssociationAttribute extends AssociationAttribute {
this.inverseForeignKeyName = determineInverseForeignKeyName();
this.caching = determineCachingSettings();
this.customPersister = determineCustomPersister();
this.customInsert = AnnotationParserHelper.processCustomSqlAnnotation(
HibernateDotNames.SQL_INSERT, annotations()
);
this.customUpdate = AnnotationParserHelper.processCustomSqlAnnotation(
HibernateDotNames.SQL_UPDATE, annotations()
);
this.customDelete = AnnotationParserHelper.processCustomSqlAnnotation(
HibernateDotNames.SQL_DELETE, annotations()
);
}
private String determineCustomPersister() {

View File

@ -146,17 +146,17 @@ public class PluralAttributeSourceImpl implements PluralAttributeSource {
@Override
public CustomSQL getCustomSqlInsert() {
return null; //To change body of implemented methods use File | Settings | File Templates.
return attribute.getCustomInsert();
}
@Override
public CustomSQL getCustomSqlUpdate() {
return null; //To change body of implemented methods use File | Settings | File Templates.
return attribute.getCustomUpdate();
}
@Override
public CustomSQL getCustomSqlDelete() {
return null; //To change body of implemented methods use File | Settings | File Templates.
return attribute.getCustomDelete();
}
@Override

View File

@ -23,6 +23,15 @@
*/
package org.hibernate.metamodel.internal.source.annotations.entity;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.AccessType;
import javax.persistence.DiscriminatorType;
import javax.persistence.PersistenceException;
@ -33,15 +42,6 @@ import javax.persistence.PostUpdate;
import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
@ -57,13 +57,13 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.OptimisticLockType;
import org.hibernate.annotations.PolymorphismType;
import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.metamodel.internal.source.annotations.AnnotationBindingContext;
import org.hibernate.metamodel.internal.source.annotations.attribute.Column;
import org.hibernate.metamodel.internal.source.annotations.attribute.FormulaValue;
import org.hibernate.metamodel.internal.source.annotations.util.AnnotationParserHelper;
import org.hibernate.metamodel.internal.source.annotations.util.HibernateDotNames;
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.internal.source.annotations.attribute.Column;
import org.hibernate.metamodel.internal.source.annotations.attribute.FormulaValue;
import org.hibernate.metamodel.internal.source.annotations.xml.PseudoJpaDotNames;
import org.hibernate.metamodel.spi.binding.Caching;
import org.hibernate.metamodel.spi.binding.CustomSQL;
@ -103,9 +103,9 @@ public class EntityClass extends ConfiguredClass {
private boolean isSelectBeforeUpdate;
private String customPersister;
private CustomSQL customInsert;
private CustomSQL customUpdate;
private CustomSQL customDelete;
private final CustomSQL customInsert;
private final CustomSQL customUpdate;
private final CustomSQL customDelete;
private boolean isLazy;
private String proxy;
@ -146,8 +146,20 @@ public class EntityClass extends ConfiguredClass {
this.batchSize = determineBatchSize();
this.jpaCallbacks = determineEntityListeners();
this.customInsert = AnnotationParserHelper.processCustomSqlAnnotation(
HibernateDotNames.SQL_INSERT,
getClassInfo().annotations()
);
this.customUpdate = AnnotationParserHelper.processCustomSqlAnnotation(
HibernateDotNames.SQL_UPDATE,
getClassInfo().annotations()
);
this.customDelete = AnnotationParserHelper.processCustomSqlAnnotation(
HibernateDotNames.SQL_DELETE,
getClassInfo().annotations()
);
processHibernateEntitySpecificAnnotations();
processCustomSqlAnnotations();
processProxyGeneration();
processDiscriminator();
}
@ -666,7 +678,11 @@ public class EntityClass extends ConfiguredClass {
JPADotNames.SECONDARY_TABLES
);
if ( secondaryTables != null ) {
for ( AnnotationInstance secondaryTable : JandexHelper.getValue( secondaryTables, "value", AnnotationInstance[].class ) ) {
for ( AnnotationInstance secondaryTable : JandexHelper.getValue(
secondaryTables,
"value",
AnnotationInstance[].class
) ) {
secondaryTableSources.add( createSecondaryTableSource( secondaryTable ) );
}
}
@ -753,44 +769,6 @@ public class EntityClass extends ConfiguredClass {
return customLoader;
}
private CustomSQL createCustomSQL(AnnotationInstance customSqlAnnotation) {
if ( customSqlAnnotation == null ) {
return null;
}
final String sql = customSqlAnnotation.value( "sql" ).asString();
final boolean isCallable = customSqlAnnotation.value( "callable" ) != null
&& customSqlAnnotation.value( "callable" ).asBoolean();
final ExecuteUpdateResultCheckStyle checkStyle = customSqlAnnotation.value( "check" ) == null
? isCallable
? ExecuteUpdateResultCheckStyle.NONE
: ExecuteUpdateResultCheckStyle.COUNT
: ExecuteUpdateResultCheckStyle.valueOf( customSqlAnnotation.value( "check" ).asEnum() );
return new CustomSQL( sql, isCallable, checkStyle );
}
private void processCustomSqlAnnotations() {
// Custom sql insert
final AnnotationInstance sqlInsertAnnotation = JandexHelper.getSingleAnnotation(
getClassInfo(), HibernateDotNames.SQL_INSERT
);
customInsert = createCustomSQL( sqlInsertAnnotation );
// Custom sql update
final AnnotationInstance sqlUpdateAnnotation = JandexHelper.getSingleAnnotation(
getClassInfo(), HibernateDotNames.SQL_UPDATE
);
customUpdate = createCustomSQL( sqlUpdateAnnotation );
// Custom sql delete
final AnnotationInstance sqlDeleteAnnotation = JandexHelper.getSingleAnnotation(
getClassInfo(), HibernateDotNames.SQL_DELETE
);
customDelete = createCustomSQL( sqlDeleteAnnotation );
}
private List<String> determineSynchronizedTableNames() {
final AnnotationInstance synchronizeAnnotation = JandexHelper.getSingleAnnotation(
getClassInfo(), HibernateDotNames.SYNCHRONIZE

View File

@ -0,0 +1,74 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.internal.source.annotations.util;
import java.util.List;
import java.util.Map;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.DotName;
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.metamodel.spi.binding.CustomSQL;
/**
* Some annotation processing is identical between entity and attribute level (aka you can place the annotation on
* entity as well as attribute level. This class tries to avoid code duplication for these cases.
*
* @author Hardy Ferentschik
*/
public class AnnotationParserHelper {
// should not be instantiated
private AnnotationParserHelper() {
}
public static CustomSQL processCustomSqlAnnotation(DotName annotationName, Map<DotName, List<AnnotationInstance>> annotations) {
final AnnotationInstance sqlAnnotation = JandexHelper.getSingleAnnotation(
annotations, annotationName
);
return createCustomSQL( sqlAnnotation );
}
private static CustomSQL createCustomSQL(AnnotationInstance customSqlAnnotation) {
if ( customSqlAnnotation == null ) {
return null;
}
final String sql = customSqlAnnotation.value( "sql" ).asString();
final boolean isCallable = customSqlAnnotation.value( "callable" ) != null
&& customSqlAnnotation.value( "callable" ).asBoolean();
final ExecuteUpdateResultCheckStyle checkStyle = customSqlAnnotation.value( "check" ) == null
? isCallable
? ExecuteUpdateResultCheckStyle.NONE
: ExecuteUpdateResultCheckStyle.COUNT
: ExecuteUpdateResultCheckStyle.valueOf( customSqlAnnotation.value( "check" ).asEnum() );
return new CustomSQL( sql, isCallable, checkStyle );
}
}