diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/PluralAssociationAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/PluralAssociationAttribute.java index b4f6d5d2b1..673cb8f9b0 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/PluralAssociationAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/PluralAssociationAttribute.java @@ -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() { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/PluralAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/PluralAttributeSourceImpl.java index 7f0c72edef..5404560c83 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/PluralAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/PluralAttributeSourceImpl.java @@ -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 diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java index a71d7bbba2..6ffd755721 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java @@ -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 determineSynchronizedTableNames() { final AnnotationInstance synchronizeAnnotation = JandexHelper.getSingleAnnotation( getClassInfo(), HibernateDotNames.SYNCHRONIZE diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/AnnotationParserHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/AnnotationParserHelper.java new file mode 100644 index 0000000000..b618a5527f --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/AnnotationParserHelper.java @@ -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> 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 ); + } +} + +