diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java b/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java
new file mode 100644
index 0000000000..19635cd12c
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java
@@ -0,0 +1,44 @@
+/*
+ * 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.annotations;
+
+/**
+ *
+ */
+public class QueryHints {
+
+ public static final String CACHE_MODE = "org.hibernate.cacheMode";
+ public static final String CACHE_REGION = "org.hibernate.cacheRegion";
+ public static final String CACHEABLE = "org.hibernate.cacheable";
+ public static final String CALLABLE = "org.hibernate.callable";
+ public static final String COMMENT = "org.hibernate.comment";
+ public static final String FETCH_SIZE = "org.hibernate.fetchSize";
+ public static final String FLUSH_MODE = "org.hibernate.flushMode";
+ public static final String READ_ONLY = "org.hibernate.readOnly";
+ public static final String TIMEOUT_HIBERNATE = "org.hibernate.timeout";
+ public static final String TIMEOUT_JPA = "javax.persistence.query.timeout";
+
+ private QueryHints() {
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/FetchProfile.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/FetchProfile.java
index 1136f2615c..31b6d5dbc5 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/FetchProfile.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/FetchProfile.java
@@ -22,122 +22,93 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.binding;
-import java.util.LinkedHashSet;
-import org.hibernate.mapping.MetadataSource;
+import java.util.Collections;
+import java.util.Set;
/**
- * A fetch profile allows a user to dynamically modify the fetching strategy used for particular associations at
- * runtime, whereas that information was historically only statically defined in the metadata.
+ * A fetch profile allows a user to dynamically modify the fetching strategy used for particular associations at runtime, whereas
+ * that information was historically only statically defined in the metadata.
*
* This class represent the data as it is defined in their metadata.
*
* @author Steve Ebersole
- *
* @see org.hibernate.engine.profile.FetchProfile
*/
public class FetchProfile {
- private final String name;
- private final MetadataSource source;
- private LinkedHashSet fetches = new LinkedHashSet();
- /**
- * Create a fetch profile representation.
- *
- * @param name The name of the fetch profile.
- * @param source The source of the fetch profile (where was it defined).
- */
- public FetchProfile(String name, MetadataSource source) {
- this.name = name;
- this.source = source;
- }
+ private final String name;
+ private final Set fetches;
- /**
- * Retrieve the name of the fetch profile.
- *
- * @return The profile name
- */
- public String getName() {
- return name;
- }
+ /**
+ * Create a fetch profile representation.
+ *
+ * @param name The name of the fetch profile.
+ * @param fetches
+ */
+ public FetchProfile( String name,
+ Set fetches ) {
+ this.name = name;
+ this.fetches = fetches;
+ }
- /**
- * Retrieve the fetch profile source.
- *
- * @return The profile source.
- */
- public MetadataSource getSource() {
- return source;
- }
+ /**
+ * Retrieve the name of the fetch profile.
+ *
+ * @return The profile name
+ */
+ public String getName() {
+ return name;
+ }
- /**
- * Retrieve the fetches associated with this profile
- *
- * @return The fetches associated with this profile.
- */
- public LinkedHashSet getFetches() {
- return fetches;
- }
+ /**
+ * Retrieve the fetches associated with this profile
+ *
+ * @return The fetches associated with this profile.
+ */
+ public Set getFetches() {
+ return Collections.unmodifiableSet(fetches);
+ }
- /**
- * Adds a fetch to this profile.
- *
- * @param entity The entity which contains the association to be fetched
- * @param association The association to fetch
- * @param style The style of fetch t apply
- */
- public void addFetch(String entity, String association, String style) {
- fetches.add( new Fetch( entity, association, style ) );
- }
+ /**
+ * Adds a fetch to this profile.
+ *
+ * @param entity The entity which contains the association to be fetched
+ * @param association The association to fetch
+ * @param style The style of fetch t apply
+ */
+ public void addFetch( String entity,
+ String association,
+ String style ) {
+ fetches.add(new Fetch(entity, association, style));
+ }
- /**
- * {@inheritDoc}
- */
- public boolean equals(Object o) {
- if ( this == o ) {
- return true;
- }
- if ( o == null || getClass() != o.getClass() ) {
- return false;
- }
+ /**
+ * Defines an individual association fetch within the given profile.
+ */
+ public static class Fetch {
+ private final String entity;
+ private final String association;
+ private final String style;
- FetchProfile that = (FetchProfile) o;
+ public Fetch( String entity,
+ String association,
+ String style ) {
+ this.entity = entity;
+ this.association = association;
+ this.style = style;
+ }
- return name.equals( that.name );
- }
+ public String getEntity() {
+ return entity;
+ }
- /**
- * {@inheritDoc}
- */
- public int hashCode() {
- return name.hashCode();
- }
+ public String getAssociation() {
+ return association;
+ }
-
- /**
- * Defines an individual association fetch within the given profile.
- */
- public static class Fetch {
- private final String entity;
- private final String association;
- private final String style;
-
- public Fetch(String entity, String association, String style) {
- this.entity = entity;
- this.association = association;
- this.style = style;
- }
-
- public String getEntity() {
- return entity;
- }
-
- public String getAssociation() {
- return association;
- }
-
- public String getStyle() {
- return style;
- }
- }
+ public String getStyle() {
+ return style;
+ }
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/IdGenerator.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/IdGenerator.java
index faeb9ca7ab..151a0c68f5 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/IdGenerator.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/IdGenerator.java
@@ -22,52 +22,47 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.binding;
+
import java.io.Serializable;
-import java.util.Properties;
+import java.util.Collections;
+import java.util.Map;
/**
- * Identifier generator container,
- * Useful to keep named generator in annotations
+ * Identifier generator container, Useful to keep named generator in annotations
*
* @author Emmanuel Bernard
*/
public class IdGenerator implements Serializable {
- private String name;
- private String identifierGeneratorStrategy;
- private Properties params = new Properties();
+ private final String name;
+ private final String strategy;
+ private final Map parameters;
+ public IdGenerator( String name,
+ String strategy,
+ Map parameters ) {
+ this.name = name;
+ this.strategy = strategy;
+ this.parameters = parameters;
+ }
- /**
- * @return identifier generator strategy
- */
- public String getIdentifierGeneratorStrategy() {
- return identifierGeneratorStrategy;
- }
+ /**
+ * @return identifier generator strategy
+ */
+ public String getStrategy() {
+ return strategy;
+ }
- /**
- * @return generator name
- */
- public String getName() {
- return name;
- }
-
- /**
- * @return generator configuration parameters
- */
- public Properties getParams() {
- return params;
- }
-
- public void setIdentifierGeneratorStrategy(String string) {
- identifierGeneratorStrategy = string;
- }
-
- public void setName(String string) {
- name = string;
- }
-
- public void addParam(String key, String value) {
- params.setProperty( key, value );
- }
+ /**
+ * @return generator name
+ */
+ public String getName() {
+ return name;
+ }
+ /**
+ * @return generator configuration parameters
+ */
+ public Map getParameters() {
+ return Collections.unmodifiableMap(parameters);
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/TypeDef.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/TypeDef.java
index df746ea001..6378a046b2 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/TypeDef.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/TypeDef.java
@@ -22,27 +22,30 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.binding;
+
import java.io.Serializable;
-import java.util.Properties;
+import java.util.Collections;
+import java.util.Map;
/**
* Placeholder for typedef information
*/
public class TypeDef implements Serializable {
- private String typeClass;
- private Properties parameters;
+ private final String typeClass;
+ private final Map parameters;
- public TypeDef(String typeClass, Properties parameters) {
- this.typeClass = typeClass;
- this.parameters = parameters;
- }
+ public TypeDef( String typeClass,
+ Map parameters ) {
+ this.typeClass = typeClass;
+ this.parameters = parameters;
+ }
- public Properties getParameters() {
- return parameters;
- }
- public String getTypeClass() {
- return typeClass;
- }
+ public Map getParameters() {
+ return Collections.unmodifiableMap(parameters);
+ }
+ public String getTypeClass() {
+ return typeClass;
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java
index 56ecb82edd..25630f1afc 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java
@@ -32,6 +32,10 @@ import org.slf4j.LoggerFactory;
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClass;
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
import org.hibernate.metamodel.source.annotations.entity.EntityBinder;
+import org.hibernate.metamodel.source.annotations.global.FilterDefBinder;
+import org.hibernate.metamodel.source.annotations.global.IdGeneratorBinder;
+import org.hibernate.metamodel.source.annotations.global.QueryBinder;
+import org.hibernate.metamodel.source.annotations.global.TypeDefBinder;
import org.hibernate.metamodel.source.annotations.global.FetchProfileBinder;
import org.hibernate.metamodel.source.annotations.global.TableBinder;
import org.hibernate.metamodel.source.annotations.util.ConfiguredClassHierarchyBuilder;
@@ -45,7 +49,9 @@ import org.hibernate.metamodel.source.internal.MetadataImpl;
* @author Hardy Ferentschik
*/
public class AnnotationBinder {
- private static final Logger log = LoggerFactory.getLogger( AnnotationBinder.class );
+
+ private static final Logger LOG = LoggerFactory.getLogger( AnnotationBinder.class );
+
private final MetadataImpl metadata;
private final Index index;
@@ -64,7 +70,8 @@ public class AnnotationBinder {
* Binds global configuration data prior to entity binding. This includes generators and type definitions.
*/
private void preEntityBindings() {
- FetchProfileBinder.bind( metadata, index );
+ TypeDefBinder.bind(metadata, index);
+ IdGeneratorBinder.bind(metadata, index);
}
/**
@@ -79,7 +86,7 @@ public class AnnotationBinder {
// now we process each hierarchy one at the time
for ( ConfiguredClassHierarchy hierarchy : hierarchies ) {
for ( ConfiguredClass configuredClass : hierarchy ) {
- log.info( "Binding entity from annotated class: {}", configuredClass.getName() );
+ LOG.info( "Binding entity from annotated class: {}", configuredClass.getName() );
EntityBinder entityBinder = new EntityBinder( metadata, configuredClass );
entityBinder.bind();
}
@@ -92,6 +99,9 @@ public class AnnotationBinder {
*/
private void postEntityBindings() {
TableBinder.bind( metadata, index );
+ FetchProfileBinder.bind( metadata, index );
+ QueryBinder.bind(metadata, index);
+ FilterDefBinder.bind(metadata, index);
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/FetchProfileBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/FetchProfileBinder.java
index 92e8b8679f..8e6681d169 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/FetchProfileBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/FetchProfileBinder.java
@@ -23,17 +23,17 @@
*/
package org.hibernate.metamodel.source.annotations.global;
-import java.util.Arrays;
-import java.util.List;
-
+import java.util.HashSet;
+import java.util.Set;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.Index;
-
import org.hibernate.MappingException;
import org.hibernate.annotations.FetchMode;
-import org.hibernate.mapping.MetadataSource;
+import org.hibernate.annotations.FetchProfiles;
import org.hibernate.metamodel.binding.FetchProfile;
+import org.hibernate.metamodel.binding.FetchProfile.Fetch;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
+import org.hibernate.metamodel.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.source.internal.MetadataImpl;
/**
@@ -42,51 +42,42 @@ import org.hibernate.metamodel.source.internal.MetadataImpl;
* @author Hardy Ferentschik
*/
public class FetchProfileBinder {
- private FetchProfileBinder() {
- }
- /**
- * Binds all {@link org.hibernate.annotations.FetchProfiles} and {@link org.hibernate.annotations.FetchProfile}
- * annotations to the specified meta data instance.
- *
- * @param meta the global metadata
- * @param index the annotation index repository
- */
- // TODO how to handle fetch profiles defined in hbm and annotations. Which overrides which?
- // TODO verify that association exists. See former VerifyFetchProfileReferenceSecondPass
- public static void bind(MetadataImpl meta, Index index) {
- // check @FetchProfiles
- List fetchProfilesAnnotations = index.getAnnotations( HibernateDotNames.FETCH_PROFILES );
- for ( AnnotationInstance fetchProfilesAnnotation : fetchProfilesAnnotations ) {
- AnnotationInstance fetchProfiles[] = fetchProfilesAnnotation.value().asNestedArray();
- bindFetchProfileAnnotations( meta, Arrays.asList( fetchProfiles ) );
- }
+ /**
+ * Binds all {@link FetchProfiles} and {@link org.hibernate.annotations.FetchProfile} annotations to the supplied metadata.
+ *
+ * @param metadata the global metadata
+ * @param jandex the jandex index
+ */
+ // TODO verify that association exists. See former VerifyFetchProfileReferenceSecondPass
+ public static void bind( MetadataImpl metadata,
+ Index jandex ) {
+ for (AnnotationInstance fetchProfile : jandex.getAnnotations(HibernateDotNames.FETCH_PROFILE)) {
+ bind(metadata, jandex, fetchProfile);
+ }
+ for (AnnotationInstance fetchProfiles : jandex.getAnnotations(HibernateDotNames.FETCH_PROFILES)) {
+ for (AnnotationInstance fetchProfile : JandexHelper.getValueAsArray(fetchProfiles, "value")) {
+ bind(metadata, jandex, fetchProfile);
+ }
+ }
+ }
- // check @FetchProfile
- List fetchProfileAnnotations = index.getAnnotations( HibernateDotNames.FETCH_PROFILE );
- bindFetchProfileAnnotations( meta, fetchProfileAnnotations );
- }
+ private static void bind( MetadataImpl metadata,
+ Index jandex,
+ AnnotationInstance fetchProfile ) {
+ String name = JandexHelper.getValueAsString(jandex, fetchProfile, "name");
+ Set fetches = new HashSet();
+ for (AnnotationInstance override : JandexHelper.getValueAsArray(fetchProfile, "fetchOverrides")) {
+ FetchMode fetchMode = JandexHelper.getValueAsEnum(jandex, override, "mode", FetchMode.class);
+ if (!fetchMode.equals(org.hibernate.annotations.FetchMode.JOIN)) throw new MappingException(
+ "Only FetchMode.JOIN is currently supported");
+ fetches.add(new Fetch(JandexHelper.getValueAsString(jandex, override, "entity"),
+ JandexHelper.getValueAsString(jandex, override, "association"),
+ fetchMode.toString().toLowerCase()));
+ }
+ metadata.addFetchProfile(new FetchProfile(name, fetches));
+ }
- private static void bindFetchProfileAnnotations(MetadataImpl meta, List fetchProfileAnnotations) {
- for ( AnnotationInstance fetchProfileAnnotation : fetchProfileAnnotations ) {
- String name = fetchProfileAnnotation.value( "name" ).asString();
- FetchProfile profile = meta.findOrCreateFetchProfile( name, MetadataSource.ANNOTATIONS );
-
- AnnotationInstance overrides[] = fetchProfileAnnotation.value( "fetchOverrides" ).asNestedArray();
- for ( AnnotationInstance overrideAnnotation : overrides ) {
- FetchMode fetchMode = Enum.valueOf( FetchMode.class, overrideAnnotation.value( "mode" ).asEnum() );
- if ( !fetchMode.equals( org.hibernate.annotations.FetchMode.JOIN ) ) {
- throw new MappingException( "Only FetchMode.JOIN is currently supported" );
- }
-
- String entityClassName = overrideAnnotation.value( "entity" ).asClass().name().toString();
- String associationName = overrideAnnotation.value( "association" ).asString();
- profile.addFetch(
- entityClassName, associationName, fetchMode.toString().toLowerCase()
- );
- }
- }
- }
+ private FetchProfileBinder() {
+ }
}
-
-
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/FilterDefBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/FilterDefBinder.java
new file mode 100644
index 0000000000..d95801292e
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/FilterDefBinder.java
@@ -0,0 +1,80 @@
+/*
+ * 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.source.annotations.global;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.hibernate.annotations.FilterDef;
+import org.hibernate.annotations.FilterDefs;
+import org.hibernate.engine.spi.FilterDefinition;
+import org.hibernate.internal.CoreMessageLogger;
+import org.hibernate.metamodel.source.annotations.HibernateDotNames;
+import org.hibernate.metamodel.source.annotations.util.JandexHelper;
+import org.hibernate.metamodel.source.internal.MetadataImpl;
+import org.hibernate.type.Type;
+import org.jboss.jandex.AnnotationInstance;
+import org.jboss.jandex.Index;
+import org.jboss.logging.Logger;
+
+/**
+ *
+ */
+public class FilterDefBinder {
+
+ private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, FilterDefBinder.class.getName());
+
+ /**
+ * Binds all {@link FilterDefs} and {@link FilterDef} annotations to the supplied metadata.
+ *
+ * @param metadata the global metadata
+ * @param jandex the jandex index
+ */
+ public static void bind( MetadataImpl metadata,
+ Index jandex ) {
+ for (AnnotationInstance filterDef : jandex.getAnnotations(HibernateDotNames.FILTER_DEF)) {
+ bind(metadata, jandex, filterDef);
+ }
+ for (AnnotationInstance filterDefs : jandex.getAnnotations(HibernateDotNames.FILTER_DEFS)) {
+ for (AnnotationInstance filterDef : JandexHelper.getValueAsArray(filterDefs, "value")) {
+ bind(metadata, jandex, filterDef);
+ }
+ }
+ }
+
+ private static void bind( MetadataImpl metadata,
+ Index jandex,
+ AnnotationInstance filterDef ) {
+ String name = JandexHelper.getValueAsString(jandex, filterDef, "name");
+ Map prms = new HashMap();
+ for (AnnotationInstance prm : JandexHelper.getValueAsArray(filterDef, "parameters")) {
+ prms.put(JandexHelper.getValueAsString(jandex, prm, "name"),
+ metadata.typeResolver().heuristicType(JandexHelper.getValueAsString(jandex, prm, "type")));
+ }
+ metadata.addFilterDef(new FilterDefinition(name, JandexHelper.getValueAsString(jandex, filterDef, "defaultCondition"), prms));
+ LOG.debugf("Binding filter definition: %s", name);
+ }
+
+ private FilterDefBinder() {
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/IdGeneratorBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/IdGeneratorBinder.java
new file mode 100644
index 0000000000..6ce3fb2e9e
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/IdGeneratorBinder.java
@@ -0,0 +1,161 @@
+/*
+ * 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.source.annotations.global;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.SequenceGenerator;
+import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.GenericGenerators;
+import org.hibernate.cfg.AvailableSettings;
+import org.hibernate.id.MultipleHiLoPerTableGenerator;
+import org.hibernate.id.PersistentIdentifierGenerator;
+import org.hibernate.id.SequenceHiLoGenerator;
+import org.hibernate.id.TableHiLoGenerator;
+import org.hibernate.id.enhanced.SequenceStyleGenerator;
+import org.hibernate.id.enhanced.TableGenerator;
+import org.hibernate.internal.CoreMessageLogger;
+import org.hibernate.internal.util.StringHelper;
+import org.hibernate.metamodel.binding.IdGenerator;
+import org.hibernate.metamodel.source.annotations.HibernateDotNames;
+import org.hibernate.metamodel.source.annotations.JPADotNames;
+import org.hibernate.metamodel.source.annotations.util.JandexHelper;
+import org.hibernate.metamodel.source.internal.MetadataImpl;
+import org.jboss.jandex.AnnotationInstance;
+import org.jboss.jandex.Index;
+import org.jboss.logging.Logger;
+
+/**
+ *
+ */
+public class IdGeneratorBinder {
+
+ private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, IdGeneratorBinder.class.getName());
+
+ private static void addStringParameter( Index index,
+ AnnotationInstance annotation,
+ String element,
+ Map parameters,
+ String parameter ) {
+ String string = JandexHelper.getValueAsString(index, annotation, element);
+ if (StringHelper.isNotEmpty(string)) parameters.put(parameter, string);
+ }
+
+ /**
+ * Binds all {@link SequenceGenerator}, {@link javax.persistence.TableGenerator}, {@link GenericGenerator}, and {
+ * {@link GenericGenerators} annotations to the supplied metadata.
+ *
+ * @param metadata the global metadata
+ * @param jandex the jandex index
+ */
+ public static void bind( MetadataImpl metadata,
+ Index jandex ) {
+ for (AnnotationInstance generator : jandex.getAnnotations(JPADotNames.SEQUENCE_GENERATOR)) {
+ bindSequenceGenerator(metadata, jandex, generator);
+ }
+ for (AnnotationInstance generator : jandex.getAnnotations(JPADotNames.TABLE_GENERATOR)) {
+ bindTableGenerator(metadata, jandex, generator);
+ }
+ for (AnnotationInstance generator : jandex.getAnnotations(HibernateDotNames.GENERIC_GENERATOR)) {
+ bindGenericGenerator(metadata, jandex, generator);
+ }
+ for (AnnotationInstance generators : jandex.getAnnotations(HibernateDotNames.GENERIC_GENERATORS)) {
+ for (AnnotationInstance generator : JandexHelper.getValueAsArray(generators, "value")) {
+ bindGenericGenerator(metadata, jandex, generator);
+ }
+ }
+ }
+
+ private static void bindGenericGenerator( MetadataImpl metadata,
+ Index jandex,
+ AnnotationInstance generator ) {
+ String name = JandexHelper.getValueAsString(jandex, generator, "name");
+ Map prms = new HashMap();
+ for (AnnotationInstance prm : JandexHelper.getValueAsArray(generator, "parameters")) {
+ prms.put(JandexHelper.getValueAsString(jandex, prm, "name"), JandexHelper.getValueAsString(jandex, prm, "value"));
+ }
+ metadata.addIdGenerator(new IdGenerator(name, JandexHelper.getValueAsString(jandex, generator, "strategy"), prms));
+ LOG.tracef("Add generic generator with name: %s", name);
+ }
+
+ private static void bindSequenceGenerator( MetadataImpl metadata,
+ Index jandex,
+ AnnotationInstance generator ) {
+ String name = JandexHelper.getValueAsString(jandex, generator, "name");
+ String strategy;
+ Map prms = new HashMap();
+ addStringParameter(jandex, generator, "sequenceName", prms, SequenceStyleGenerator.SEQUENCE_PARAM);
+ if (metadata.getOptions().useNewIdentifierGenerators()) {
+ strategy = SequenceStyleGenerator.class.getName();
+ addStringParameter(jandex, generator, "catalog", prms, PersistentIdentifierGenerator.CATALOG);
+ addStringParameter(jandex, generator, "schema", prms, PersistentIdentifierGenerator.SCHEMA);
+ prms.put(SequenceStyleGenerator.INCREMENT_PARAM,
+ String.valueOf(JandexHelper.getValueAsInt(jandex, generator, "allocationSize")));
+ prms.put(SequenceStyleGenerator.INITIAL_PARAM,
+ String.valueOf(JandexHelper.getValueAsInt(jandex, generator, "initialValue")));
+ } else {
+ strategy = "seqhilo";
+ if (JandexHelper.getValueAsInt(jandex, generator, "initialValue") != 1) LOG.unsupportedInitialValue(AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS);
+ prms.put(SequenceHiLoGenerator.MAX_LO,
+ String.valueOf(JandexHelper.getValueAsInt(jandex, generator, "allocationSize") - 1));
+ }
+ metadata.addIdGenerator(new IdGenerator(name, strategy, prms));
+ LOG.tracef("Add sequence generator with name: %s", name);
+ }
+
+ private static void bindTableGenerator( MetadataImpl metadata,
+ Index jandex,
+ AnnotationInstance generator ) {
+ String name = JandexHelper.getValueAsString(jandex, generator, "name");
+ String strategy;
+ Map prms = new HashMap();
+ addStringParameter(jandex, generator, "catalog", prms, PersistentIdentifierGenerator.CATALOG);
+ addStringParameter(jandex, generator, "schema", prms, PersistentIdentifierGenerator.SCHEMA);
+ if (metadata.getOptions().useNewIdentifierGenerators()) {
+ strategy = TableGenerator.class.getName();
+ prms.put(TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, "true");
+ addStringParameter(jandex, generator, "table", prms, TableGenerator.TABLE_PARAM);
+ addStringParameter(jandex, generator, "pkColumnName", prms, TableGenerator.SEGMENT_COLUMN_PARAM);
+ addStringParameter(jandex, generator, "pkColumnValue", prms, TableGenerator.SEGMENT_VALUE_PARAM);
+ addStringParameter(jandex, generator, "valueColumnName", prms, TableGenerator.VALUE_COLUMN_PARAM);
+ prms.put(TableGenerator.INCREMENT_PARAM,
+ String.valueOf(JandexHelper.getValueAsInt(jandex, generator, "allocationSize")));
+ prms.put(TableGenerator.INITIAL_PARAM,
+ String.valueOf(JandexHelper.getValueAsInt(jandex, generator, "initialValue") + 1));
+ } else {
+ strategy = MultipleHiLoPerTableGenerator.class.getName();
+ addStringParameter(jandex, generator, "table", prms, MultipleHiLoPerTableGenerator.ID_TABLE);
+ addStringParameter(jandex, generator, "pkColumnName", prms, MultipleHiLoPerTableGenerator.PK_COLUMN_NAME);
+ addStringParameter(jandex, generator, "pkColumnValue", prms, MultipleHiLoPerTableGenerator.PK_VALUE_NAME);
+ addStringParameter(jandex, generator, "valueColumnName", prms, MultipleHiLoPerTableGenerator.VALUE_COLUMN_NAME);
+ prms.put(TableHiLoGenerator.MAX_LO, String.valueOf(JandexHelper.getValueAsInt(jandex, generator, "allocationSize") - 1));
+ }
+ if (JandexHelper.getValueAsArray(generator, "uniqueConstraints").length > 0) LOG.ignoringTableGeneratorConstraints(name);
+ metadata.addIdGenerator(new IdGenerator(name, strategy, prms));
+ LOG.tracef("Add table generator with name: %s", name);
+ }
+
+ private IdGeneratorBinder() {
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/QueryBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/QueryBinder.java
index bb8c291976..a3b6636177 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/QueryBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/QueryBinder.java
@@ -23,22 +23,221 @@
*/
package org.hibernate.metamodel.source.annotations.global;
-import org.jboss.jandex.Index;
-
+import java.util.HashMap;
+import javax.persistence.NamedNativeQueries;
+import javax.persistence.NamedNativeQuery;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import org.hibernate.AnnotationException;
+import org.hibernate.CacheMode;
+import org.hibernate.FlushMode;
+import org.hibernate.LockMode;
+import org.hibernate.annotations.QueryHints;
+import org.hibernate.cfg.NotYetImplementedException;
+import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn;
+import org.hibernate.engine.spi.NamedQueryDefinition;
+import org.hibernate.engine.spi.NamedSQLQueryDefinition;
+import org.hibernate.internal.CoreMessageLogger;
+import org.hibernate.internal.util.StringHelper;
+import org.hibernate.metamodel.source.annotations.HibernateDotNames;
+import org.hibernate.metamodel.source.annotations.JPADotNames;
+import org.hibernate.metamodel.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.source.internal.MetadataImpl;
+import org.jboss.jandex.AnnotationInstance;
+import org.jboss.jandex.Index;
+import org.jboss.logging.Logger;
/**
* @author Hardy Ferentschik
*/
public class QueryBinder {
- private QueryBinder() {
- }
- public static void bindNamedQuery(MetadataImpl meta, Index index) {
- }
+ private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, QueryBinder.class.getName());
- public static void bindNativeNamedQuery(MetadataImpl meta, Index index) {
- }
+ /**
+ * Binds all {@link NamedQuery}, {@link NamedQueries}, {@link NamedNativeQuery}, {{@link NamedNativeQueries},
+ * {@link org.hibernate.annotations.NamedQuery} , {@link org.hibernate.annotations.NamedQueries},
+ * {@link org.hibernate.annotations.NamedNativeQuery}, and {@link org.hibernate.annotations.NamedNativeQueries} annotations to
+ * the supplied metadata.
+ *
+ * @param metadata the global metadata
+ * @param jandex the jandex index
+ */
+ public static void bind( MetadataImpl metadata,
+ Index jandex ) {
+ for (AnnotationInstance query : jandex.getAnnotations(JPADotNames.NAMED_QUERY)) {
+ bindNamedQuery(metadata, jandex, query);
+ }
+ for (AnnotationInstance queries : jandex.getAnnotations(JPADotNames.NAMED_QUERIES)) {
+ for (AnnotationInstance query : JandexHelper.getValueAsArray(queries, "value")) {
+ bindNamedQuery(metadata, jandex, query);
+ }
+ }
+ for (AnnotationInstance query : jandex.getAnnotations(JPADotNames.NAMED_NATIVE_QUERY)) {
+ bindNamedNativeQuery(metadata, jandex, query);
+ }
+ for (AnnotationInstance queries : jandex.getAnnotations(JPADotNames.NAMED_NATIVE_QUERIES)) {
+ for (AnnotationInstance query : JandexHelper.getValueAsArray(queries, "value")) {
+ bindNamedNativeQuery(metadata, jandex, query);
+ }
+ }
+ for (AnnotationInstance query : jandex.getAnnotations(HibernateDotNames.NAMED_QUERY)) {
+ bindNamedQuery(metadata, jandex, query);
+ }
+ for (AnnotationInstance queries : jandex.getAnnotations(HibernateDotNames.NAMED_QUERIES)) {
+ for (AnnotationInstance query : JandexHelper.getValueAsArray(queries, "value")) {
+ bindNamedQuery(metadata, jandex, query);
+ }
+ }
+ for (AnnotationInstance query : jandex.getAnnotations(HibernateDotNames.NAMED_NATIVE_QUERY)) {
+ bindNamedNativeQuery(metadata, jandex, query);
+ }
+ for (AnnotationInstance queries : jandex.getAnnotations(HibernateDotNames.NAMED_NATIVE_QUERIES)) {
+ for (AnnotationInstance query : JandexHelper.getValueAsArray(queries, "value")) {
+ bindNamedNativeQuery(metadata, jandex, query);
+ }
+ }
+ }
+
+ private static void bindNamedQuery( MetadataImpl metadata,
+ Index jandex,
+ AnnotationInstance annotation ) {
+ String name = JandexHelper.getValueAsString(jandex, annotation, "name");
+ if (StringHelper.isEmpty(name)) throw new AnnotationException(
+ "A named query must have a name when used in class or package level");
+ String query = JandexHelper.getValueAsString(jandex, annotation, "query");
+ AnnotationInstance[] hints = JandexHelper.getValueAsArray(annotation, "hints");
+ String cacheRegion = getString(jandex, hints, QueryHints.CACHE_REGION);
+ if (StringHelper.isEmpty(cacheRegion)) cacheRegion = null;
+ Integer timeout = getTimeout(jandex, hints, query);
+ if (timeout != null && timeout < 0) timeout = null;
+ Integer fetchSize = getInteger(jandex, hints, QueryHints.FETCH_SIZE, name);
+ if (fetchSize != null && fetchSize < 0) fetchSize = null;
+ String comment = getString(jandex, hints, QueryHints.COMMENT);
+ if (StringHelper.isEmpty(comment)) comment = null;
+ metadata.addNamedQuery(name,
+ new NamedQueryDefinition(query, getBoolean(jandex, hints, QueryHints.CACHEABLE, name), cacheRegion,
+ timeout, fetchSize,
+ getFlushMode(jandex, hints, QueryHints.FLUSH_MODE, name),
+ getCacheMode(jandex, hints, QueryHints.CACHE_MODE, name),
+ getBoolean(jandex, hints, QueryHints.READ_ONLY, name), comment, null));
+ LOG.debugf("Binding named query: %s => %s", name, query);
+ }
+
+ private static void bindNamedNativeQuery( MetadataImpl metadata,
+ Index jandex,
+ AnnotationInstance annotation ) {
+ String name = JandexHelper.getValueAsString(jandex, annotation, "name");
+ if (StringHelper.isEmpty(name)) throw new AnnotationException(
+ "A named native query must have a name when used in class or package level");
+ String query = JandexHelper.getValueAsString(jandex, annotation, "query");
+ String resultSetMapping = JandexHelper.getValueAsString(jandex, annotation, "resultSetMapping");
+ AnnotationInstance[] hints = JandexHelper.getValueAsArray(annotation, "hints");
+ boolean cacheable = getBoolean(jandex, hints, "org.hibernate.cacheable", name);
+ String cacheRegion = getString(jandex, hints, QueryHints.CACHE_REGION);
+ if (StringHelper.isEmpty(cacheRegion)) cacheRegion = null;
+ Integer timeout = getTimeout(jandex, hints, query);
+ if (timeout != null && timeout < 0) timeout = null;
+ Integer fetchSize = getInteger(jandex, hints, QueryHints.FETCH_SIZE, name);
+ if (fetchSize != null && fetchSize < 0) fetchSize = null;
+ FlushMode flushMode = getFlushMode(jandex, hints, QueryHints.FLUSH_MODE, name);
+ CacheMode cacheMode = getCacheMode(jandex, hints, QueryHints.CACHE_MODE, name);
+ boolean readOnly = getBoolean(jandex, hints, QueryHints.READ_ONLY, name);
+ String comment = getString(jandex, hints, QueryHints.COMMENT);
+ if (StringHelper.isEmpty(comment)) comment = null;
+ boolean callable = getBoolean(jandex, hints, QueryHints.CALLABLE, name);
+ NamedSQLQueryDefinition def;
+ if (StringHelper.isNotEmpty(resultSetMapping)) def = new NamedSQLQueryDefinition(query, resultSetMapping, null, cacheable,
+ cacheRegion, timeout, fetchSize,
+ flushMode, cacheMode, readOnly, comment,
+ null, callable);
+ else {
+ String resultClass = JandexHelper.getValueAsString(jandex, annotation, "resultClass");
+ if (void.class.equals(resultClass)) throw new NotYetImplementedException(
+ "Pure native scalar queries are not yet supported");
+ def = new NamedSQLQueryDefinition(query, new NativeSQLQueryRootReturn[] {new NativeSQLQueryRootReturn("alias1",
+ resultClass,
+ new HashMap(),
+ LockMode.READ)},
+ null, cacheable, cacheRegion, timeout, fetchSize, flushMode, cacheMode, readOnly,
+ comment, null, callable);
+
+ }
+ metadata.addNamedNativeQuery(name, def);
+ LOG.debugf("Binding named native query: %s => %s", name, query);
+ }
+
+ private static boolean getBoolean( Index jandex,
+ AnnotationInstance[] hints,
+ String element,
+ String query ) {
+ String val = getString(jandex, hints, element);
+ if (val == null || val.equalsIgnoreCase("false")) return false;
+ if (val.equalsIgnoreCase("true")) return true;
+ throw new AnnotationException("Not a boolean in hint: " + query + ":" + element);
+ }
+
+ private static CacheMode getCacheMode( Index jandex,
+ AnnotationInstance[] hints,
+ String element,
+ String query ) {
+ String val = getString(jandex, hints, element);
+ if (val == null) return null;
+ if (val.equalsIgnoreCase(CacheMode.GET.toString())) return CacheMode.GET;
+ if (val.equalsIgnoreCase(CacheMode.IGNORE.toString())) return CacheMode.IGNORE;
+ if (val.equalsIgnoreCase(CacheMode.NORMAL.toString())) return CacheMode.NORMAL;
+ if (val.equalsIgnoreCase(CacheMode.PUT.toString())) return CacheMode.PUT;
+ if (val.equalsIgnoreCase(CacheMode.REFRESH.toString())) return CacheMode.REFRESH;
+ throw new AnnotationException("Unknown CacheMode in hint: " + query + ":" + element);
+ }
+
+ private static FlushMode getFlushMode( Index jandex,
+ AnnotationInstance[] hints,
+ String element,
+ String query ) {
+ String val = getString(jandex, hints, element);
+ if (val == null) return null;
+ if (val.equalsIgnoreCase(FlushMode.ALWAYS.toString())) return FlushMode.ALWAYS;
+ else if (val.equalsIgnoreCase(FlushMode.AUTO.toString())) return FlushMode.AUTO;
+ else if (val.equalsIgnoreCase(FlushMode.COMMIT.toString())) return FlushMode.COMMIT;
+ else if (val.equalsIgnoreCase(FlushMode.NEVER.toString())) return FlushMode.MANUAL;
+ else if (val.equalsIgnoreCase(FlushMode.MANUAL.toString())) return FlushMode.MANUAL;
+ else throw new AnnotationException("Unknown FlushMode in hint: " + query + ":" + element);
+
+ }
+
+ private static Integer getInteger( Index jandex,
+ AnnotationInstance[] hints,
+ String element,
+ String query ) {
+ String val = getString(jandex, hints, element);
+ if (val == null) return null;
+ try {
+ return Integer.decode(val);
+ } catch (NumberFormatException nfe) {
+ throw new AnnotationException("Not an integer in hint: " + query + ":" + element, nfe);
+ }
+ }
+
+ private static String getString( Index jandex,
+ AnnotationInstance[] hints,
+ String element ) {
+ for (AnnotationInstance hint : hints) {
+ if (element.equals(JandexHelper.getValue(jandex, hint, "name"))) return JandexHelper.getValueAsString(jandex,
+ hint,
+ "value");
+ }
+ return null;
+ }
+
+ private static Integer getTimeout( Index jandex,
+ AnnotationInstance[] hints,
+ String query ) {
+ Integer timeout = getInteger(jandex, hints, QueryHints.TIMEOUT_JPA, query);
+ if (timeout == null) return getInteger(jandex, hints, QueryHints.TIMEOUT_HIBERNATE, query); // timeout is already in seconds
+ return new Integer((int)Math.round(timeout.doubleValue() / 1000.0)); // convert milliseconds to seconds
+ }
+
+ private QueryBinder() {
+ }
}
-
-
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/TableBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/TableBinder.java
index ed0eb386d6..d009eee9a0 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/TableBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/TableBinder.java
@@ -23,21 +23,19 @@
*/
package org.hibernate.metamodel.source.annotations.global;
-import java.util.Arrays;
-import java.util.List;
-
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.Index;
import org.jboss.logging.Logger;
-
import org.hibernate.AnnotationException;
import org.hibernate.internal.CoreMessageLogger;
+import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.ObjectName;
import org.hibernate.metamodel.relational.Schema;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.Table;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
+import org.hibernate.metamodel.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.source.internal.MetadataImpl;
/**
@@ -46,93 +44,77 @@ import org.hibernate.metamodel.source.internal.MetadataImpl;
* @author Hardy Ferentschik
*/
public class TableBinder {
- private static final CoreMessageLogger LOG = Logger.getMessageLogger(
- CoreMessageLogger.class, TableBinder.class.getName()
- );
- private TableBinder() {
- }
+ private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, TableBinder.class.getName());
- /**
- * Binds {@link org.hibernate.annotations.Tables} and {@link org.hibernate.annotations.Table}
- * annotations to the specified meta data instance.
- *
- * @param meta the global metadata
- * @param index the annotation index repository
- */
- public static void bind(MetadataImpl meta, Index index) {
- // check @o.h.a.Tables
- List tablesAnnotations = index.getAnnotations( HibernateDotNames.TABLES );
- for ( AnnotationInstance tableAnnotation : tablesAnnotations ) {
- AnnotationInstance tables[] = tableAnnotation.value().asNestedArray();
- bindTablesAnnotation( meta, Arrays.asList( tables ) );
- }
+ /**
+ * Binds {@link org.hibernate.annotations.Tables} and {@link org.hibernate.annotations.Table} annotations to the supplied
+ * metadata.
+ *
+ * @param metadata the global metadata
+ * @param jandex the annotation index repository
+ */
+ public static void bind( MetadataImpl metadata,
+ Index jandex ) {
+ for (AnnotationInstance tableAnnotation : jandex.getAnnotations(HibernateDotNames.TABLE)) {
+ bind(metadata, jandex, tableAnnotation);
+ }
+ for (AnnotationInstance tables : jandex.getAnnotations(HibernateDotNames.TABLES)) {
+ for (AnnotationInstance table : JandexHelper.getValueAsArray(tables, "value")) {
+ bind(metadata, jandex, table);
+ }
+ }
+ }
- // check @o.h.a.Table
- List tableAnnotations = index.getAnnotations( HibernateDotNames.TABLE );
- bindTablesAnnotation( meta, tableAnnotations );
- }
+ private static void bind( MetadataImpl metadata,
+ Index jandex,
+ AnnotationInstance tableAnnotation ) {
+ String tableName = JandexHelper.getValueAsString(jandex, tableAnnotation, "appliesTo");
+ ObjectName objectName = new ObjectName(tableName);
+ Schema schema = metadata.getDatabase().getSchema(objectName.getSchema(), objectName.getCatalog());
+ Table table = schema.getTable(objectName.getName());
+ if (table != null) bindHibernateTableAnnotation(jandex, table, tableAnnotation);
+ }
- private static void bindTablesAnnotation(MetadataImpl meta, List tableAnnotations) {
- for ( AnnotationInstance tableAnnotation : tableAnnotations ) {
- String tableName = tableAnnotation.value( "appliesTo" ).asString();
- ObjectName objectName = new ObjectName( tableName );
- Schema schema = meta.getDatabase().getSchema( objectName.getSchema(), objectName.getCatalog() );
- Table table = schema.getTable( objectName.getName() );
- if ( table == null ) {
- continue;
- }
- bindHibernateTableAnnotation( table, tableAnnotation );
- }
- }
+ private static void bindHibernateTableAnnotation( Index jandex,
+ Table table,
+ AnnotationInstance tableAnnotation ) {
+ for (AnnotationInstance indexAnnotation : JandexHelper.getValueAsArray(tableAnnotation, "indexes")) {
+ bindIndexAnnotation(jandex, table, indexAnnotation);
+ }
+ String comment = JandexHelper.getValueAsString(jandex, tableAnnotation, "comment");
+ if (StringHelper.isNotEmpty(comment)) table.addComment(comment.trim());
+ }
- private static void bindHibernateTableAnnotation(Table table, AnnotationInstance tableAnnotation) {
- if ( tableAnnotation.value( "indexes" ) != null ) {
- AnnotationInstance[] indexAnnotations = tableAnnotation.value( "indexes" ).asNestedArray();
- for ( AnnotationInstance indexAnnotation : indexAnnotations ) {
- bindIndexAnnotation( table, indexAnnotation );
- }
- }
+ private static void bindIndexAnnotation( Index jandex,
+ Table table,
+ AnnotationInstance indexAnnotation ) {
+ String indexName = JandexHelper.getValueAsString(jandex, indexAnnotation, "appliesTo");
+ String[] columnNames = (String[])JandexHelper.getValue(jandex, indexAnnotation, "columnNames");
+ if (columnNames == null) {
+ LOG.noColumnsSpecifiedForIndex(indexName, table.toLoggableString());
+ return;
+ }
+ org.hibernate.metamodel.relational.Index index = table.getOrCreateIndex(indexName);
+ for (String columnName : columnNames) {
+ Column column = findColumn(table, columnName);
+ if (column == null) throw new AnnotationException("@Index references a unknown column: " + columnName);
+ index.addColumn(column);
+ }
+ }
- if ( tableAnnotation.value( "comment" ) != null ) {
- table.addComment( tableAnnotation.value( "comment" ).asString().trim() );
- }
+ private static Column findColumn( Table table,
+ String columnName ) {
+ Column column = null;
+ for (SimpleValue value : table.values()) {
+ if (value instanceof Column && ((Column)value).getName().equals(columnName)) {
+ column = (Column)value;
+ break;
+ }
+ }
+ return column;
+ }
-
-
- }
-
- private static void bindIndexAnnotation(Table table, AnnotationInstance indexAnnotation) {
- String indexName = indexAnnotation.value( "name" ).asString();
- if ( indexAnnotation.value( "columnNames" ) == null ) {
- LOG.noColumnsSpecifiedForIndex( indexName, table.toLoggableString() );
- return;
- }
-
- org.hibernate.metamodel.relational.Index index = table.getOrCreateIndex( indexName );
-
- String[] columnNames = indexAnnotation.value( "columnNames" ).asStringArray();
- for ( String columnName : columnNames ) {
- Column column = findColumn( table, columnName );
- if ( column == null ) {
- throw new AnnotationException(
- "@Index references a unknown column: " + columnName
- );
- }
- index.addColumn( column );
- }
- }
-
- private static Column findColumn(Table table, String columnName) {
- Column column = null;
- for ( SimpleValue value : table.values() ) {
- if ( value instanceof Column && ( (Column) value ).getName().equals( columnName ) ) {
- column = (Column) value;
- break;
- }
- }
- return column;
- }
+ private TableBinder() {
+ }
}
-
-
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/TypeDefBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/TypeDefBinder.java
new file mode 100644
index 0000000000..f53fe497e4
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/TypeDefBinder.java
@@ -0,0 +1,94 @@
+/*
+ * 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.source.annotations.global;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.hibernate.AnnotationException;
+import org.hibernate.annotations.TypeDefs;
+import org.hibernate.internal.CoreMessageLogger;
+import org.hibernate.internal.util.StringHelper;
+import org.hibernate.metamodel.binding.TypeDef;
+import org.hibernate.metamodel.source.annotations.HibernateDotNames;
+import org.hibernate.metamodel.source.annotations.util.JandexHelper;
+import org.hibernate.metamodel.source.internal.MetadataImpl;
+import org.jboss.jandex.AnnotationInstance;
+import org.jboss.jandex.Index;
+import org.jboss.logging.Logger;
+
+/**
+ *
+ */
+public class TypeDefBinder {
+
+ private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, TypeDefBinder.class.getName());
+
+ /**
+ * Binds all {@link org.hibernate.annotations.TypeDef} and {@link TypeDefs} annotations to the supplied metadata.
+ *
+ * @param metadata the global metadata
+ * @param jandex the jandex jandex
+ */
+ public static void bind( MetadataImpl metadata,
+ Index jandex ) {
+ for (AnnotationInstance typeDef : jandex.getAnnotations(HibernateDotNames.TYPE_DEF)) {
+ bind(metadata, jandex, typeDef);
+ }
+ for (AnnotationInstance typeDefs : jandex.getAnnotations(HibernateDotNames.TYPE_DEFS)) {
+ for (AnnotationInstance typeDef : JandexHelper.getValueAsArray(typeDefs, "value")) {
+ bind(metadata, jandex, typeDef);
+ }
+ }
+ }
+
+ private static void bind( String name,
+ String typeClass,
+ Map prms,
+ MetadataImpl metadata ) {
+ LOG.debugf("Binding type definition: %s", name);
+ metadata.addTypeDef(name, new TypeDef(typeClass, prms));
+ }
+
+ private static void bind( MetadataImpl metadata,
+ Index jandex,
+ AnnotationInstance typeDef ) {
+ String name = JandexHelper.getValueAsString(jandex, typeDef, "name");
+ String defaultForType = JandexHelper.getValueAsString(jandex, typeDef, "defaultForType");
+ String typeClass = JandexHelper.getValueAsString(jandex, typeDef, "typeClass");
+ boolean noName = StringHelper.isEmpty(name);
+ boolean noDefaultForType = defaultForType == null || defaultForType.equals(void.class.getName());
+ if (noName && noDefaultForType) throw new AnnotationException(
+ "Either name or defaultForType (or both) attribute should be set in TypeDef having typeClass "
+ + typeClass);
+ Map prms = new HashMap();
+ for (AnnotationInstance prm : JandexHelper.getValueAsArray(typeDef, "parameters")) {
+ prms.put(JandexHelper.getValueAsString(jandex, prm, "name"), JandexHelper.getValueAsString(jandex, prm, "value"));
+ }
+ if (!noName) bind(name, typeClass, prms, metadata);
+ if (!noDefaultForType) bind(defaultForType, typeClass, prms, metadata);
+ }
+
+ private TypeDefBinder() {
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/util/JandexHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/util/JandexHelper.java
index 0b1d9e6e54..452f3c65f8 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/util/JandexHelper.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/util/JandexHelper.java
@@ -33,6 +33,7 @@ import java.util.Map;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
+import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.FieldInfo;
@@ -40,6 +41,7 @@ import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer;
import org.jboss.jandex.MethodInfo;
+import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.service.classloading.spi.ClassLoaderService;
@@ -50,172 +52,285 @@ import org.hibernate.service.classloading.spi.ClassLoaderService;
* @author Hardy Ferentschik
*/
public class JandexHelper {
- private JandexHelper() {
- }
- /**
- * Expects a method or field annotation target and returns the property name for this target
- *
- * @param target the annotation target
- *
- * @return the property name of the target. For a field it is the field name and for a method name it is
- * the method name stripped of 'is', 'has' or 'get'
- */
- public static String getPropertyName(AnnotationTarget target) {
- if ( !( target instanceof MethodInfo || target instanceof FieldInfo ) ) {
- throw new AssertionFailure( "Unexpected annotation target " + target.toString() );
- }
+ private static final AnnotationInstance[] EMPTY_ANNOTATIONS_ARRAY = new AnnotationInstance[0];
- if ( target instanceof FieldInfo ) {
- return ( (FieldInfo) target ).name();
- }
- else {
- String methodName = ( (MethodInfo) target ).name();
- if ( methodName.startsWith( "is" ) ) {
- methodName = Introspector.decapitalize( methodName.substring( 2 ) );
- }
- else if ( methodName.startsWith( "has" ) ) {
- methodName = Introspector.decapitalize( methodName.substring( 3 ) );
- }
- else if ( methodName.startsWith( "get" ) ) {
- methodName = Introspector.decapitalize( methodName.substring( 3 ) );
- }
- else {
- throw new AssertionFailure( "Expected a method following the Java Bean notation" );
- }
- return methodName;
- }
- }
+ private static final Map DEFAULT_VALUES_BY_ELEMENT = new HashMap();
- /**
- * @param classInfo the class info from which to retrieve the annotation instance
- * @param annotationName the annotation to retrieve from the class info
- *
- * @return the single annotation defined on the class or {@code null} in case the annotation is not specified at all
- *
- * @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type.
- */
- public static AnnotationInstance getSingleAnnotation(ClassInfo classInfo, DotName annotationName)
- throws AssertionFailure {
- return getSingleAnnotation( classInfo.annotations(), annotationName );
- }
+ private static Object getDefaultValue( Index index,
+ AnnotationInstance annotation,
+ String element ) {
+ String name = annotation.name().toString();
+ String fqElement = name + '.' + element;
+ Object val = DEFAULT_VALUES_BY_ELEMENT.get(fqElement);
+ if (val != null) return val;
+ try {
+ val = Index.class.getClassLoader().loadClass(name).getMethod(element).getDefaultValue();
+ DEFAULT_VALUES_BY_ELEMENT.put(fqElement, val);
+ return val == null ? null : val;
+ } catch (RuntimeException error) {
+ throw error;
+ } catch (Exception error) {
+ throw new AnnotationException(error);
+ }
+ }
- /**
- * @param annotations List of annotation instances keyed against their dot name.
- * @param annotationName the annotation to retrieve from map
- *
- * @return the single annotation of the specified dot name or {@code null} in case the annotation is not specified at all
- *
- * @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type.
- */
- public static AnnotationInstance getSingleAnnotation(Map> annotations, DotName annotationName)
- throws AssertionFailure {
- List annotationList = annotations.get( annotationName );
- if ( annotationList == null ) {
- return null;
- }
- else if ( annotationList.size() == 1 ) {
- return annotationList.get( 0 );
- }
- else {
- throw new AssertionFailure(
- "Found more than one instance of the annotation "
- + annotationList.get( 0 ).name().toString()
- + ". Expected was one."
- );
- }
- }
+ /**
+ * Expects a method or field annotation target and returns the property name for this target
+ *
+ * @param target the annotation target
+ *
+ * @return the property name of the target. For a field it is the field name and for a method name it is
+ * the method name stripped of 'is', 'has' or 'get'
+ */
+ public static String getPropertyName(AnnotationTarget target) {
+ if ( !( target instanceof MethodInfo || target instanceof FieldInfo ) ) {
+ throw new AssertionFailure( "Unexpected annotation target " + target.toString() );
+ }
- /**
- * Creates a jandex index for the specified classes
- *
- * @param classLoaderService class loader service
- * @param classes the classes to index
- *
- * @return an annotation repository w/ all the annotation discovered in the specified classes
- */
- public static Index indexForClass(ClassLoaderService classLoaderService, Class>... classes) {
- Indexer indexer = new Indexer();
- for ( Class> clazz : classes ) {
- InputStream stream = classLoaderService.locateResourceStream(
- clazz.getName().replace( '.', '/' ) + ".class"
- );
- try {
- indexer.index( stream );
- }
- catch ( IOException e ) {
- StringBuilder builder = new StringBuilder();
- builder.append( "[" );
- int count = 0;
- for ( Class> c : classes ) {
- builder.append( c.getName() );
- if ( count < classes.length - 1 ) {
- builder.append( "," );
- }
- count++;
- }
- builder.append( "]" );
- throw new HibernateException( "Unable to create annotation index for " + builder.toString() );
- }
- }
- return indexer.complete();
- }
+ if ( target instanceof FieldInfo ) {
+ return ( (FieldInfo) target ).name();
+ }
+ else {
+ String methodName = ( (MethodInfo) target ).name();
+ if ( methodName.startsWith( "is" ) ) {
+ methodName = Introspector.decapitalize( methodName.substring( 2 ) );
+ }
+ else if ( methodName.startsWith( "has" ) ) {
+ methodName = Introspector.decapitalize( methodName.substring( 3 ) );
+ }
+ else if ( methodName.startsWith( "get" ) ) {
+ methodName = Introspector.decapitalize( methodName.substring( 3 ) );
+ }
+ else {
+ throw new AssertionFailure( "Expected a method following the Java Bean notation" );
+ }
+ return methodName;
+ }
+ }
- public static Map> getMemberAnnotations(ClassInfo classInfo, String name) {
- if ( classInfo == null ) {
- throw new IllegalArgumentException( "classInfo cannot be null" );
- }
+ /**
+ * @param classInfo the class info from which to retrieve the annotation instance
+ * @param annotationName the annotation to retrieve from the class info
+ *
+ * @return the single annotation defined on the class or {@code null} in case the annotation is not specified at all
+ *
+ * @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type.
+ */
+ public static AnnotationInstance getSingleAnnotation(ClassInfo classInfo, DotName annotationName)
+ throws AssertionFailure {
+ return getSingleAnnotation( classInfo.annotations(), annotationName );
+ }
- if ( name == null ) {
- throw new IllegalArgumentException( "name cannot be null" );
- }
+ /**
+ * @param annotations List of annotation instances keyed against their dot name.
+ * @param annotationName the annotation to retrieve from map
+ *
+ * @return the single annotation of the specified dot name or {@code null} in case the annotation is not specified at all
+ *
+ * @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type.
+ */
+ public static AnnotationInstance getSingleAnnotation(Map> annotations, DotName annotationName)
+ throws AssertionFailure {
+ List annotationList = annotations.get( annotationName );
+ if ( annotationList == null ) {
+ return null;
+ }
+ else if ( annotationList.size() == 1 ) {
+ return annotationList.get( 0 );
+ }
+ else {
+ throw new AssertionFailure(
+ "Found more than one instance of the annotation "
+ + annotationList.get( 0 ).name().toString()
+ + ". Expected was one."
+ );
+ }
+ }
- Map> annotations = new HashMap>();
- for ( List annotationList : classInfo.annotations().values() ) {
- for ( AnnotationInstance instance : annotationList ) {
- String targetName = null;
- if ( instance.target() instanceof FieldInfo ) {
- targetName = ( (FieldInfo) instance.target() ).name();
- }
- else if ( instance.target() instanceof MethodInfo ) {
- targetName = ( (MethodInfo) instance.target() ).name();
- }
- if ( targetName != null && name.equals( targetName ) ) {
- addAnnotationToMap( instance, annotations );
- }
- }
- }
- return annotations;
- }
+ /**
+ * Retrieves a jandex annotation element value. If the value is null
, the default value specified in the
+ * annotation class is retrieved instead. Note, {@link #getValueAsEnum(Index, AnnotationInstance, String, Class)} must be
+ * called to retrieve an enumerated value, and {@link #getValueAsArray(AnnotationInstance, String)} must be called to retrieve
+ * an object array (other than a String array).
+ *
+ * @param index the jandex index containing the supplied annotation
+ * @param annotation the annotation containing the element with the supplied name
+ * @param element the name of the element value to be retrieve
+ * @return the value if not null
, else the default value if not
+ * null
, else null
.
+ */
+ public static Object getValue( Index index,
+ AnnotationInstance annotation,
+ String element ) {
+ AnnotationValue val = annotation.value(element);
+ if (val == null) return getDefaultValue(index, annotation, element);
+ return val.asNested();
+ }
- public static Map> getTypeAnnotations(ClassInfo classInfo) {
- if ( classInfo == null ) {
- throw new IllegalArgumentException( "classInfo cannot be null" );
- }
+ /**
+ * Retrieves a jandex annotation element array. Note, {@link #getValue(Index, AnnotationInstance, String)} may be
+ * called to retrieve a String array (or a non-array value).
+ *
+ * @param annotation the jandex annotation containing the element with the supplied name
+ * @param element the name of the element array
+ * @return the element array if not null
, else an empty array
+ */
+ public static AnnotationInstance[] getValueAsArray( AnnotationInstance annotation,
+ String element ) {
+ AnnotationValue val = annotation.value(element);
+ return val == null ? EMPTY_ANNOTATIONS_ARRAY : val.asNestedArray();
+ }
- Map> annotations = new HashMap>();
- for ( List annotationList : classInfo.annotations().values() ) {
- for ( AnnotationInstance instance : annotationList ) {
- if ( instance.target() instanceof ClassInfo ) {
- addAnnotationToMap( instance, annotations );
- }
- }
- }
- return annotations;
- }
+ /**
+ * Retrieves a jandex annotation element value, converting it to the supplied enumerated type. If the value is
+ * null
, the default value specified in the annotation class is retrieved instead.
+ *
+ * @param an enumerated type
+ * @param index the jandex index containing the supplied annotation
+ * @param annotation the annotation containing the enumerated element with the supplied name
+ * @param element the name of the enumerated element value to be retrieve
+ * @param type the type to which to convert the value before being returned
+ * @return the value converted to the supplied enumerated type if the value is not null
, else the default value if
+ * not null
, else null
.
+ * @see #getValue(Index, AnnotationInstance, String)
+ */
+ public static > T getValueAsEnum( Index index,
+ AnnotationInstance annotation,
+ String element,
+ Class type ) {
+ AnnotationValue val = annotation.value(element);
+ if (val == null) return (T)getDefaultValue(index, annotation, element);
+ return Enum.valueOf(type, val.asEnum());
+ }
- private static void addAnnotationToMap(AnnotationInstance instance, Map> annotations) {
- DotName dotName = instance.name();
- List list;
- if ( annotations.containsKey( dotName ) ) {
- list = annotations.get( dotName );
- }
- else {
- list = new ArrayList();
- annotations.put( dotName, list );
- }
- list.add( instance );
- }
+ /**
+ * Retrieves a jandex annotation element value as an Integer. If the value is null
, the default value specified in
+ * the annotation class is retrieved instead.
+ *
+ * @param index the jandex index containing the supplied annotation
+ * @param annotation the annotation containing the element with the supplied name
+ * @param element the name of the element value to be retrieve
+ * @return the value converted to an int if the value is not null
, else the default value if not
+ * null
, else 0
.
+ */
+ public static int getValueAsInt( Index index,
+ AnnotationInstance annotation,
+ String element ) {
+ AnnotationValue val = annotation.value(element);
+ if (val == null) return (Integer)getDefaultValue(index, annotation, element);
+ return val.asInt();
+ }
+
+ /**
+ * Retrieves a jandex annotation element value as a String. If the value is null
, the default value specified in
+ * the annotation class is retrieved instead.
+ *
+ * @param index the jandex index containing the supplied annotation
+ * @param annotation the annotation containing the element with the supplied name
+ * @param element the name of the element value to be retrieve
+ * @return the value converted to a String if the value is not null
, else the default value if not
+ * null
, else null
.
+ */
+ public static String getValueAsString( Index index,
+ AnnotationInstance annotation,
+ String element ) {
+ AnnotationValue val = annotation.value(element);
+ if (val == null) return (String)getDefaultValue(index, annotation, element);
+ return val.asString();
+ }
+
+ /**
+ * Creates a jandex index for the specified classes
+ *
+ * @param classLoaderService class loader service
+ * @param classes the classes to index
+ *
+ * @return an annotation repository w/ all the annotation discovered in the specified classes
+ */
+ public static Index indexForClass(ClassLoaderService classLoaderService, Class>... classes) {
+ Indexer indexer = new Indexer();
+ for ( Class> clazz : classes ) {
+ InputStream stream = classLoaderService.locateResourceStream(
+ clazz.getName().replace( '.', '/' ) + ".class"
+ );
+ try {
+ indexer.index( stream );
+ }
+ catch ( IOException e ) {
+ StringBuilder builder = new StringBuilder();
+ builder.append( "[" );
+ int count = 0;
+ for ( Class> c : classes ) {
+ builder.append( c.getName() );
+ if ( count < classes.length - 1 ) {
+ builder.append( "," );
+ }
+ count++;
+ }
+ builder.append( "]" );
+ throw new HibernateException( "Unable to create annotation index for " + builder.toString() );
+ }
+ }
+ return indexer.complete();
+ }
+
+ public static Map> getMemberAnnotations(ClassInfo classInfo, String name) {
+ if ( classInfo == null ) {
+ throw new IllegalArgumentException( "classInfo cannot be null" );
+ }
+
+ if ( name == null ) {
+ throw new IllegalArgumentException( "name cannot be null" );
+ }
+
+ Map> annotations = new HashMap>();
+ for ( List annotationList : classInfo.annotations().values() ) {
+ for ( AnnotationInstance instance : annotationList ) {
+ String targetName = null;
+ if ( instance.target() instanceof FieldInfo ) {
+ targetName = ( (FieldInfo) instance.target() ).name();
+ }
+ else if ( instance.target() instanceof MethodInfo ) {
+ targetName = ( (MethodInfo) instance.target() ).name();
+ }
+ if ( targetName != null && name.equals( targetName ) ) {
+ addAnnotationToMap( instance, annotations );
+ }
+ }
+ }
+ return annotations;
+ }
+
+ public static Map> getTypeAnnotations(ClassInfo classInfo) {
+ if ( classInfo == null ) {
+ throw new IllegalArgumentException( "classInfo cannot be null" );
+ }
+
+ Map> annotations = new HashMap>();
+ for ( List annotationList : classInfo.annotations().values() ) {
+ for ( AnnotationInstance instance : annotationList ) {
+ if ( instance.target() instanceof ClassInfo ) {
+ addAnnotationToMap( instance, annotations );
+ }
+ }
+ }
+ return annotations;
+ }
+
+ private static void addAnnotationToMap(AnnotationInstance instance, Map> annotations) {
+ DotName dotName = instance.name();
+ List list;
+ if ( annotations.containsKey( dotName ) ) {
+ list = annotations.get( dotName );
+ }
+ else {
+ list = new ArrayList();
+ annotations.put( dotName, list );
+ }
+ list.add( instance );
+ }
+
+ private JandexHelper() {
+ }
}
-
-
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/HibernateMappingBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/HibernateMappingBinder.java
index 9a9b43dbac..419cbf39f5 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/HibernateMappingBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/HibernateMappingBinder.java
@@ -23,18 +23,19 @@
*/
package org.hibernate.metamodel.source.hbm;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
-
+import java.util.Set;
import org.dom4j.Attribute;
-
import org.hibernate.MappingException;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.internal.util.StringHelper;
-import org.hibernate.mapping.MetadataSource;
+import org.hibernate.metamodel.binding.FetchProfile;
+import org.hibernate.metamodel.binding.FetchProfile.Fetch;
import org.hibernate.metamodel.domain.MetaAttribute;
import org.hibernate.metamodel.source.Origin;
-import org.hibernate.metamodel.source.internal.JaxbRoot;
+import org.hibernate.metamodel.source.hbm.util.MappingHelper;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLFetchProfileElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLFetchProfileElement.XMLFetch;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping;
@@ -45,7 +46,7 @@ import org.hibernate.metamodel.source.hbm.xml.mapping.XMLQueryElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSqlQueryElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSubclassElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLUnionSubclassElement;
-import org.hibernate.metamodel.source.hbm.util.MappingHelper;
+import org.hibernate.metamodel.source.internal.JaxbRoot;
import org.hibernate.service.ServiceRegistry;
/**
@@ -225,14 +226,15 @@ public class HibernateMappingBinder implements MappingDefaults {
protected void parseFetchProfiles(List fetchProfiles, String containingEntityName) {
for ( XMLFetchProfileElement fetchProfile : fetchProfiles ) {
String profileName = fetchProfile.getName();
- org.hibernate.metamodel.binding.FetchProfile profile = hibernateXmlBinder.getMetadata().findOrCreateFetchProfile( profileName, MetadataSource.HBM );
+ Set fetches = new HashSet();
for ( XMLFetch fetch : fetchProfile.getFetch() ) {
String entityName = fetch.getEntity() == null ? containingEntityName : fetch.getEntity();
if ( entityName == null ) {
throw new MappingException( "could not determine entity for fetch-profile fetch [" + profileName + "]:[" + fetch.getAssociation() + "]" );
}
- profile.addFetch( entityName, fetch.getAssociation(), fetch.getStyle() );
+ fetches.add(new Fetch(entityName, fetch.getAssociation(), fetch.getStyle()));
}
+ hibernateXmlBinder.getMetadata().addFetchProfile( new FetchProfile(profileName, fetches));
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java
index 54b2b39597..1089c00de8 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java
@@ -30,21 +30,21 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-
import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer;
import org.jboss.logging.Logger;
-
import org.hibernate.DuplicateMappingException;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
+import org.hibernate.engine.spi.FilterDefinition;
+import org.hibernate.engine.spi.NamedQueryDefinition;
+import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.internal.CoreMessageLogger;
-import org.hibernate.mapping.MetadataSource;
-import org.hibernate.metamodel.Metadata;
import org.hibernate.metamodel.MetadataSources;
import org.hibernate.metamodel.SourceProcessingOrder;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile;
+import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.relational.Database;
@@ -56,6 +56,7 @@ import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping;
import org.hibernate.metamodel.source.spi.MetadataImplementor;
import org.hibernate.service.BasicServiceRegistry;
import org.hibernate.service.classloading.spi.ClassLoaderService;
+import org.hibernate.type.TypeResolver;
/**
* Container for configuration data collected during binding the metamodel.
@@ -63,15 +64,15 @@ import org.hibernate.service.classloading.spi.ClassLoaderService;
* @author Steve Ebersole
* @author Hardy Ferentschik
*/
-public class MetadataImpl implements Metadata, MetadataImplementor, Serializable {
- private static final CoreMessageLogger LOG = Logger.getMessageLogger(
- CoreMessageLogger.class, MetadataImpl.class.getName()
- );
+public class MetadataImpl implements MetadataImplementor, Serializable {
+
+ private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, MetadataImpl.class.getName());
private final BasicServiceRegistry serviceRegistry;
private final Options options;
private final Database database = new Database();
+ private TypeResolver typeResolver = new TypeResolver();
/**
* Maps the fully qualified class name of an entity to its entity binding
@@ -79,8 +80,12 @@ public class MetadataImpl implements Metadata, MetadataImplementor, Serializable
private Map entityBindingMap = new HashMap();
private Map collectionBindingMap = new HashMap();
private Map fetchProfiles = new HashMap();
- private Map typeDefs = new HashMap();
private Map imports;
+ private Map typeDefs = new HashMap();
+ private Map idGenerators = new HashMap();
+ private Map namedQueryDefs = new HashMap();
+ private Map namedNativeQueryDefs = new HashMap();
+ private Map filterDefs = new HashMap();
public MetadataImpl(MetadataSources metadataSources, Options options) {
this.serviceRegistry = metadataSources.getServiceRegistry();
@@ -99,6 +104,33 @@ public class MetadataImpl implements Metadata, MetadataImplementor, Serializable
new EntityReferenceResolver( this ).resolve();
}
+ public void addFetchProfile( FetchProfile profile ) {
+ fetchProfiles.put(profile.getName(), profile);
+ }
+
+ public void addFilterDef( FilterDefinition def ) {
+ filterDefs.put(def.getFilterName(), def);
+ }
+
+ public void addIdGenerator( IdGenerator generator ) {
+ idGenerators.put(generator.getName(), generator);
+ }
+
+ public void addNamedNativeQuery( String name,
+ NamedSQLQueryDefinition def ) {
+ namedNativeQueryDefs.put(name, def);
+ }
+
+ public void addNamedQuery( String name,
+ NamedQueryDefinition def ) {
+ namedQueryDefs.put(name, def);
+ }
+
+ public void addTypeDef(String name, TypeDef typeDef) {
+ // TODO - should we check whether the typedef already exists? Log it? Exception? (HF)
+ typeDefs.put( name, typeDef );
+ }
+
private void applyHibernateMappings(MetadataSources metadataSources, List processedEntityNames) {
final HibernateXmlBinder hibernateXmlBinder = new HibernateXmlBinder( this );
for ( JaxbRoot jaxbRoot : metadataSources.getJaxbRootList() ) {
@@ -223,25 +255,15 @@ public class MetadataImpl implements Metadata, MetadataImplementor, Serializable
}
}
- public Iterable getFetchProfiles() {
- return fetchProfiles.values();
- }
-
- public void addTypeDef(String name, TypeDef typeDef) {
- // TODO - should we check whether the typedef already exists? Log it? Exception? (HF)
- typeDefs.put( name, typeDef );
- }
-
public TypeDef getTypeDef(String name) {
return typeDefs.get( name );
}
- public FetchProfile findOrCreateFetchProfile(String profileName, MetadataSource source) {
- FetchProfile profile = fetchProfiles.get( profileName );
- if ( profile == null ) {
- profile = new FetchProfile( profileName, source );
- fetchProfiles.put( profileName, profile );
- }
- return profile;
- }
+ public Iterable getFetchProfiles() {
+ return fetchProfiles.values();
+ }
+
+ public TypeResolver typeResolver() {
+ return typeResolver;
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/spi/MetadataImplementor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/spi/MetadataImplementor.java
index 291f4bf888..2b254004fb 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/spi/MetadataImplementor.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/spi/MetadataImplementor.java
@@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.source.spi;
-import org.hibernate.mapping.MetadataSource;
import org.hibernate.metamodel.Metadata;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile;
@@ -47,5 +46,5 @@ public interface MetadataImplementor extends Metadata {
public void addCollection(PluralAttributeBinding collectionBinding);
- public FetchProfile findOrCreateFetchProfile(String profileName, MetadataSource hbm);
+ public void addFetchProfile( FetchProfile profile );
}
diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/JandexHelperTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/JandexHelperTest.java
index 4aba7db158..90378a102d 100644
--- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/JandexHelperTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/JandexHelperTest.java
@@ -23,10 +23,17 @@
*/
package org.hibernate.metamodel.source.annotations.util;
+import static org.hamcrest.core.Is.is;
+
+import static org.junit.Assert.assertThat;
+
import java.util.List;
import java.util.Map;
import javax.persistence.Basic;
import javax.persistence.Column;
+import javax.persistence.LockModeType;
+import javax.persistence.NamedQuery;
+import javax.persistence.SequenceGenerator;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.ClassInfo;
@@ -36,6 +43,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.service.ServiceRegistryBuilder;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.internal.BasicServiceRegistryImpl;
@@ -88,6 +96,49 @@ public class JandexHelperTest extends BaseUnitTestCase {
memberAnnotations = JandexHelper.getMemberAnnotations( classInfo, "fubar" );
assertTrue( "there should be no annotations in fubar", memberAnnotations.isEmpty() );
}
+
+ @Test
+ public void shouldRetrieveDefaultOfUnspecifiedAnnotationElement() {
+
+ @NamedQuery(name="foo", query="bar")
+ @SequenceGenerator(name="fu")
+ class Foo {
+ }
+
+ Index index = JandexHelper.indexForClass(classLoaderService, Foo.class);
+ for (AnnotationInstance query : index.getAnnotations( JPADotNames.NAMED_QUERY)) {
+ assertThat(JandexHelper.getValueAsEnum(index, query, "lockMode", LockModeType.class), is(LockModeType.NONE));
+ }
+ for (AnnotationInstance generator : index.getAnnotations( JPADotNames.SEQUENCE_GENERATOR)) {
+ assertThat(JandexHelper.getValueAsInt(index, generator, "allocationSize"), is(50));
+ }
+ }
+
+ @Test
+ public void shouldRetrieveValueOfAnnotationElement() {
+
+ @NamedQuery(name="foo", query="bar")
+ class Foo {
+ }
+
+ Index index = JandexHelper.indexForClass(classLoaderService, Foo.class);
+ for (AnnotationInstance query : index.getAnnotations( JPADotNames.NAMED_QUERY)) {
+ assertThat(JandexHelper.getValueAsString(index, query, "name"), is("foo"));
+ }
+ }
+
+ @Test
+ public void shouldRetrieveValueOfEnumeratedAnnotationElement() {
+
+ @NamedQuery(name="foo", query="bar", lockMode=LockModeType.OPTIMISTIC)
+ class Foo {
+ }
+
+ Index index = JandexHelper.indexForClass(classLoaderService, Foo.class);
+ for (AnnotationInstance query : index.getAnnotations( JPADotNames.NAMED_QUERY)) {
+ assertThat(JandexHelper.getValueAsEnum(index, query, "lockMode", LockModeType.class), is(LockModeType.OPTIMISTIC));
+ }
+ }
}