HHH-6132: Created binders for several global configurations and updated metadata appropriately.
This commit is contained in:
parent
3960b0d8ea
commit
7258cb98f4
|
@ -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() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,122 +22,93 @@
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.binding;
|
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
|
* A fetch profile allows a user to dynamically modify the fetching strategy used for particular associations at runtime, whereas
|
||||||
* runtime, whereas that information was historically only statically defined in the metadata.
|
* that information was historically only statically defined in the metadata.
|
||||||
* <p/>
|
* <p/>
|
||||||
* This class represent the data as it is defined in their metadata.
|
* This class represent the data as it is defined in their metadata.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*
|
|
||||||
* @see org.hibernate.engine.profile.FetchProfile
|
* @see org.hibernate.engine.profile.FetchProfile
|
||||||
*/
|
*/
|
||||||
public class FetchProfile {
|
public class FetchProfile {
|
||||||
private final String name;
|
|
||||||
private final MetadataSource source;
|
|
||||||
private LinkedHashSet<Fetch> fetches = new LinkedHashSet<Fetch>();
|
|
||||||
|
|
||||||
/**
|
private final String name;
|
||||||
* Create a fetch profile representation.
|
private final Set<Fetch> fetches;
|
||||||
*
|
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the name of the fetch profile.
|
* Create a fetch profile representation.
|
||||||
*
|
*
|
||||||
* @return The profile name
|
* @param name The name of the fetch profile.
|
||||||
*/
|
* @param fetches
|
||||||
public String getName() {
|
*/
|
||||||
return name;
|
public FetchProfile( String name,
|
||||||
}
|
Set<Fetch> fetches ) {
|
||||||
|
this.name = name;
|
||||||
|
this.fetches = fetches;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the fetch profile source.
|
* Retrieve the name of the fetch profile.
|
||||||
*
|
*
|
||||||
* @return The profile source.
|
* @return The profile name
|
||||||
*/
|
*/
|
||||||
public MetadataSource getSource() {
|
public String getName() {
|
||||||
return source;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the fetches associated with this profile
|
* Retrieve the fetches associated with this profile
|
||||||
*
|
*
|
||||||
* @return The fetches associated with this profile.
|
* @return The fetches associated with this profile.
|
||||||
*/
|
*/
|
||||||
public LinkedHashSet<Fetch> getFetches() {
|
public Set<Fetch> getFetches() {
|
||||||
return fetches;
|
return Collections.unmodifiableSet(fetches);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a fetch to this profile.
|
* Adds a fetch to this profile.
|
||||||
*
|
*
|
||||||
* @param entity The entity which contains the association to be fetched
|
* @param entity The entity which contains the association to be fetched
|
||||||
* @param association The association to fetch
|
* @param association The association to fetch
|
||||||
* @param style The style of fetch t apply
|
* @param style The style of fetch t apply
|
||||||
*/
|
*/
|
||||||
public void addFetch(String entity, String association, String style) {
|
public void addFetch( String entity,
|
||||||
fetches.add( new Fetch( entity, association, style ) );
|
String association,
|
||||||
}
|
String style ) {
|
||||||
|
fetches.add(new Fetch(entity, association, style));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* Defines an individual association fetch within the given profile.
|
||||||
*/
|
*/
|
||||||
public boolean equals(Object o) {
|
public static class Fetch {
|
||||||
if ( this == o ) {
|
private final String entity;
|
||||||
return true;
|
private final String association;
|
||||||
}
|
private final String style;
|
||||||
if ( o == null || getClass() != o.getClass() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
public String getAssociation() {
|
||||||
* {@inheritDoc}
|
return association;
|
||||||
*/
|
}
|
||||||
public int hashCode() {
|
|
||||||
return name.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public String getStyle() {
|
||||||
/**
|
return style;
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,52 +22,47 @@
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.binding;
|
package org.hibernate.metamodel.binding;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Properties;
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifier generator container,
|
* Identifier generator container, Useful to keep named generator in annotations
|
||||||
* Useful to keep named generator in annotations
|
|
||||||
*
|
*
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
public class IdGenerator implements Serializable {
|
public class IdGenerator implements Serializable {
|
||||||
private String name;
|
private final String name;
|
||||||
private String identifierGeneratorStrategy;
|
private final String strategy;
|
||||||
private Properties params = new Properties();
|
private final Map<String, String> parameters;
|
||||||
|
|
||||||
|
public IdGenerator( String name,
|
||||||
|
String strategy,
|
||||||
|
Map<String, String> parameters ) {
|
||||||
|
this.name = name;
|
||||||
|
this.strategy = strategy;
|
||||||
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return identifier generator strategy
|
* @return identifier generator strategy
|
||||||
*/
|
*/
|
||||||
public String getIdentifierGeneratorStrategy() {
|
public String getStrategy() {
|
||||||
return identifierGeneratorStrategy;
|
return strategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return generator name
|
* @return generator name
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
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 configuration parameters
|
||||||
|
*/
|
||||||
|
public Map<String, String> getParameters() {
|
||||||
|
return Collections.unmodifiableMap(parameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,27 +22,30 @@
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.binding;
|
package org.hibernate.metamodel.binding;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Properties;
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Placeholder for typedef information
|
* Placeholder for typedef information
|
||||||
*/
|
*/
|
||||||
public class TypeDef implements Serializable {
|
public class TypeDef implements Serializable {
|
||||||
|
|
||||||
private String typeClass;
|
private final String typeClass;
|
||||||
private Properties parameters;
|
private final Map<String, String> parameters;
|
||||||
|
|
||||||
public TypeDef(String typeClass, Properties parameters) {
|
public TypeDef( String typeClass,
|
||||||
this.typeClass = typeClass;
|
Map<String, String> parameters ) {
|
||||||
this.parameters = parameters;
|
this.typeClass = typeClass;
|
||||||
}
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
public Properties getParameters() {
|
public Map<String, String> getParameters() {
|
||||||
return parameters;
|
return Collections.unmodifiableMap(parameters);
|
||||||
}
|
}
|
||||||
public String getTypeClass() {
|
|
||||||
return typeClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public String getTypeClass() {
|
||||||
|
return typeClass;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,10 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClass;
|
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClass;
|
||||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
|
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
|
||||||
import org.hibernate.metamodel.source.annotations.entity.EntityBinder;
|
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.FetchProfileBinder;
|
||||||
import org.hibernate.metamodel.source.annotations.global.TableBinder;
|
import org.hibernate.metamodel.source.annotations.global.TableBinder;
|
||||||
import org.hibernate.metamodel.source.annotations.util.ConfiguredClassHierarchyBuilder;
|
import org.hibernate.metamodel.source.annotations.util.ConfiguredClassHierarchyBuilder;
|
||||||
|
@ -45,7 +49,9 @@ import org.hibernate.metamodel.source.internal.MetadataImpl;
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
*/
|
*/
|
||||||
public class AnnotationBinder {
|
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 MetadataImpl metadata;
|
||||||
private final Index index;
|
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.
|
* Binds global configuration data prior to entity binding. This includes generators and type definitions.
|
||||||
*/
|
*/
|
||||||
private void preEntityBindings() {
|
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
|
// now we process each hierarchy one at the time
|
||||||
for ( ConfiguredClassHierarchy hierarchy : hierarchies ) {
|
for ( ConfiguredClassHierarchy hierarchy : hierarchies ) {
|
||||||
for ( ConfiguredClass configuredClass : hierarchy ) {
|
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 entityBinder = new EntityBinder( metadata, configuredClass );
|
||||||
entityBinder.bind();
|
entityBinder.bind();
|
||||||
}
|
}
|
||||||
|
@ -92,6 +99,9 @@ public class AnnotationBinder {
|
||||||
*/
|
*/
|
||||||
private void postEntityBindings() {
|
private void postEntityBindings() {
|
||||||
TableBinder.bind( metadata, index );
|
TableBinder.bind( metadata, index );
|
||||||
|
FetchProfileBinder.bind( metadata, index );
|
||||||
|
QueryBinder.bind(metadata, index);
|
||||||
|
FilterDefBinder.bind(metadata, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,17 +23,17 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.source.annotations.global;
|
package org.hibernate.metamodel.source.annotations.global;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jboss.jandex.AnnotationInstance;
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
import org.jboss.jandex.Index;
|
import org.jboss.jandex.Index;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.annotations.FetchMode;
|
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;
|
||||||
|
import org.hibernate.metamodel.binding.FetchProfile.Fetch;
|
||||||
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
|
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.metamodel.source.internal.MetadataImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,51 +42,42 @@ import org.hibernate.metamodel.source.internal.MetadataImpl;
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
*/
|
*/
|
||||||
public class FetchProfileBinder {
|
public class FetchProfileBinder {
|
||||||
private FetchProfileBinder() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binds all {@link org.hibernate.annotations.FetchProfiles} and {@link org.hibernate.annotations.FetchProfile}
|
* Binds all {@link FetchProfiles} and {@link org.hibernate.annotations.FetchProfile} annotations to the supplied metadata.
|
||||||
* annotations to the specified meta data instance.
|
*
|
||||||
*
|
* @param metadata the global metadata
|
||||||
* @param meta the global metadata
|
* @param jandex the jandex index
|
||||||
* @param index the annotation index repository
|
*/
|
||||||
*/
|
// TODO verify that association exists. See former VerifyFetchProfileReferenceSecondPass
|
||||||
// TODO how to handle fetch profiles defined in hbm and annotations. Which overrides which?
|
public static void bind( MetadataImpl metadata,
|
||||||
// TODO verify that association exists. See former VerifyFetchProfileReferenceSecondPass
|
Index jandex ) {
|
||||||
public static void bind(MetadataImpl meta, Index index) {
|
for (AnnotationInstance fetchProfile : jandex.getAnnotations(HibernateDotNames.FETCH_PROFILE)) {
|
||||||
// check @FetchProfiles
|
bind(metadata, jandex, fetchProfile);
|
||||||
List<AnnotationInstance> fetchProfilesAnnotations = index.getAnnotations( HibernateDotNames.FETCH_PROFILES );
|
}
|
||||||
for ( AnnotationInstance fetchProfilesAnnotation : fetchProfilesAnnotations ) {
|
for (AnnotationInstance fetchProfiles : jandex.getAnnotations(HibernateDotNames.FETCH_PROFILES)) {
|
||||||
AnnotationInstance fetchProfiles[] = fetchProfilesAnnotation.value().asNestedArray();
|
for (AnnotationInstance fetchProfile : JandexHelper.getValueAsArray(fetchProfiles, "value")) {
|
||||||
bindFetchProfileAnnotations( meta, Arrays.asList( fetchProfiles ) );
|
bind(metadata, jandex, fetchProfile);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check @FetchProfile
|
private static void bind( MetadataImpl metadata,
|
||||||
List<AnnotationInstance> fetchProfileAnnotations = index.getAnnotations( HibernateDotNames.FETCH_PROFILE );
|
Index jandex,
|
||||||
bindFetchProfileAnnotations( meta, fetchProfileAnnotations );
|
AnnotationInstance fetchProfile ) {
|
||||||
}
|
String name = JandexHelper.getValueAsString(jandex, fetchProfile, "name");
|
||||||
|
Set<Fetch> fetches = new HashSet<Fetch>();
|
||||||
|
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<AnnotationInstance> fetchProfileAnnotations) {
|
private FetchProfileBinder() {
|
||||||
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()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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<String, Type> prms = new HashMap<String, Type>();
|
||||||
|
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() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<String, String> 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<String, String> prms = new HashMap<String, String>();
|
||||||
|
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<String, String> prms = new HashMap<String, String>();
|
||||||
|
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<String, String> prms = new HashMap<String, String>();
|
||||||
|
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() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,22 +23,221 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.source.annotations.global;
|
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.hibernate.metamodel.source.internal.MetadataImpl;
|
||||||
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
|
import org.jboss.jandex.Index;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
*/
|
*/
|
||||||
public class QueryBinder {
|
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() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,21 +23,19 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.source.annotations.global;
|
package org.hibernate.metamodel.source.annotations.global;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.jboss.jandex.AnnotationInstance;
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
import org.jboss.jandex.Index;
|
import org.jboss.jandex.Index;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.hibernate.AnnotationException;
|
import org.hibernate.AnnotationException;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.metamodel.relational.Column;
|
import org.hibernate.metamodel.relational.Column;
|
||||||
import org.hibernate.metamodel.relational.ObjectName;
|
import org.hibernate.metamodel.relational.ObjectName;
|
||||||
import org.hibernate.metamodel.relational.Schema;
|
import org.hibernate.metamodel.relational.Schema;
|
||||||
import org.hibernate.metamodel.relational.SimpleValue;
|
import org.hibernate.metamodel.relational.SimpleValue;
|
||||||
import org.hibernate.metamodel.relational.Table;
|
import org.hibernate.metamodel.relational.Table;
|
||||||
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
|
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.metamodel.source.internal.MetadataImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,93 +44,77 @@ import org.hibernate.metamodel.source.internal.MetadataImpl;
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
*/
|
*/
|
||||||
public class TableBinder {
|
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}
|
* Binds {@link org.hibernate.annotations.Tables} and {@link org.hibernate.annotations.Table} annotations to the supplied
|
||||||
* annotations to the specified meta data instance.
|
* metadata.
|
||||||
*
|
*
|
||||||
* @param meta the global metadata
|
* @param metadata the global metadata
|
||||||
* @param index the annotation index repository
|
* @param jandex the annotation index repository
|
||||||
*/
|
*/
|
||||||
public static void bind(MetadataImpl meta, Index index) {
|
public static void bind( MetadataImpl metadata,
|
||||||
// check @o.h.a.Tables
|
Index jandex ) {
|
||||||
List<AnnotationInstance> tablesAnnotations = index.getAnnotations( HibernateDotNames.TABLES );
|
for (AnnotationInstance tableAnnotation : jandex.getAnnotations(HibernateDotNames.TABLE)) {
|
||||||
for ( AnnotationInstance tableAnnotation : tablesAnnotations ) {
|
bind(metadata, jandex, tableAnnotation);
|
||||||
AnnotationInstance tables[] = tableAnnotation.value().asNestedArray();
|
}
|
||||||
bindTablesAnnotation( meta, Arrays.asList( tables ) );
|
for (AnnotationInstance tables : jandex.getAnnotations(HibernateDotNames.TABLES)) {
|
||||||
}
|
for (AnnotationInstance table : JandexHelper.getValueAsArray(tables, "value")) {
|
||||||
|
bind(metadata, jandex, table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check @o.h.a.Table
|
private static void bind( MetadataImpl metadata,
|
||||||
List<AnnotationInstance> tableAnnotations = index.getAnnotations( HibernateDotNames.TABLE );
|
Index jandex,
|
||||||
bindTablesAnnotation( meta, tableAnnotations );
|
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<AnnotationInstance> tableAnnotations) {
|
private static void bindHibernateTableAnnotation( Index jandex,
|
||||||
for ( AnnotationInstance tableAnnotation : tableAnnotations ) {
|
Table table,
|
||||||
String tableName = tableAnnotation.value( "appliesTo" ).asString();
|
AnnotationInstance tableAnnotation ) {
|
||||||
ObjectName objectName = new ObjectName( tableName );
|
for (AnnotationInstance indexAnnotation : JandexHelper.getValueAsArray(tableAnnotation, "indexes")) {
|
||||||
Schema schema = meta.getDatabase().getSchema( objectName.getSchema(), objectName.getCatalog() );
|
bindIndexAnnotation(jandex, table, indexAnnotation);
|
||||||
Table table = schema.getTable( objectName.getName() );
|
}
|
||||||
if ( table == null ) {
|
String comment = JandexHelper.getValueAsString(jandex, tableAnnotation, "comment");
|
||||||
continue;
|
if (StringHelper.isNotEmpty(comment)) table.addComment(comment.trim());
|
||||||
}
|
}
|
||||||
bindHibernateTableAnnotation( table, tableAnnotation );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void bindHibernateTableAnnotation(Table table, AnnotationInstance tableAnnotation) {
|
private static void bindIndexAnnotation( Index jandex,
|
||||||
if ( tableAnnotation.value( "indexes" ) != null ) {
|
Table table,
|
||||||
AnnotationInstance[] indexAnnotations = tableAnnotation.value( "indexes" ).asNestedArray();
|
AnnotationInstance indexAnnotation ) {
|
||||||
for ( AnnotationInstance indexAnnotation : indexAnnotations ) {
|
String indexName = JandexHelper.getValueAsString(jandex, indexAnnotation, "appliesTo");
|
||||||
bindIndexAnnotation( table, indexAnnotation );
|
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 ) {
|
private static Column findColumn( Table table,
|
||||||
table.addComment( tableAnnotation.value( "comment" ).asString().trim() );
|
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() {
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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<String, String> 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<String, String> prms = new HashMap<String, String>();
|
||||||
|
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() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.jboss.jandex.AnnotationInstance;
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
import org.jboss.jandex.AnnotationTarget;
|
import org.jboss.jandex.AnnotationTarget;
|
||||||
|
import org.jboss.jandex.AnnotationValue;
|
||||||
import org.jboss.jandex.ClassInfo;
|
import org.jboss.jandex.ClassInfo;
|
||||||
import org.jboss.jandex.DotName;
|
import org.jboss.jandex.DotName;
|
||||||
import org.jboss.jandex.FieldInfo;
|
import org.jboss.jandex.FieldInfo;
|
||||||
|
@ -40,6 +41,7 @@ import org.jboss.jandex.Index;
|
||||||
import org.jboss.jandex.Indexer;
|
import org.jboss.jandex.Indexer;
|
||||||
import org.jboss.jandex.MethodInfo;
|
import org.jboss.jandex.MethodInfo;
|
||||||
|
|
||||||
|
import org.hibernate.AnnotationException;
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||||
|
@ -50,172 +52,285 @@ import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
*/
|
*/
|
||||||
public class JandexHelper {
|
public class JandexHelper {
|
||||||
private JandexHelper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
private static final AnnotationInstance[] EMPTY_ANNOTATIONS_ARRAY = new AnnotationInstance[0];
|
||||||
* 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() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( target instanceof FieldInfo ) {
|
private static final Map<String, Object> DEFAULT_VALUES_BY_ELEMENT = new HashMap<String, Object>();
|
||||||
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 Object getDefaultValue( Index index,
|
||||||
* @param classInfo the class info from which to retrieve the annotation instance
|
AnnotationInstance annotation,
|
||||||
* @param annotationName the annotation to retrieve from the class info
|
String element ) {
|
||||||
*
|
String name = annotation.name().toString();
|
||||||
* @return the single annotation defined on the class or {@code null} in case the annotation is not specified at all
|
String fqElement = name + '.' + element;
|
||||||
*
|
Object val = DEFAULT_VALUES_BY_ELEMENT.get(fqElement);
|
||||||
* @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type.
|
if (val != null) return val;
|
||||||
*/
|
try {
|
||||||
public static AnnotationInstance getSingleAnnotation(ClassInfo classInfo, DotName annotationName)
|
val = Index.class.getClassLoader().loadClass(name).getMethod(element).getDefaultValue();
|
||||||
throws AssertionFailure {
|
DEFAULT_VALUES_BY_ELEMENT.put(fqElement, val);
|
||||||
return getSingleAnnotation( classInfo.annotations(), annotationName );
|
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.
|
* Expects a method or field annotation target and returns the property name for this target
|
||||||
* @param annotationName the annotation to retrieve from map
|
*
|
||||||
*
|
* @param target the annotation target
|
||||||
* @return the single annotation of the specified dot name or {@code null} in case the annotation is not specified at all
|
*
|
||||||
*
|
* @return the property name of the target. For a field it is the field name and for a method name it is
|
||||||
* @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type.
|
* the method name stripped of 'is', 'has' or 'get'
|
||||||
*/
|
*/
|
||||||
public static AnnotationInstance getSingleAnnotation(Map<DotName, List<AnnotationInstance>> annotations, DotName annotationName)
|
public static String getPropertyName(AnnotationTarget target) {
|
||||||
throws AssertionFailure {
|
if ( !( target instanceof MethodInfo || target instanceof FieldInfo ) ) {
|
||||||
List<AnnotationInstance> annotationList = annotations.get( annotationName );
|
throw new AssertionFailure( "Unexpected annotation target " + target.toString() );
|
||||||
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."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if ( target instanceof FieldInfo ) {
|
||||||
* Creates a jandex index for the specified classes
|
return ( (FieldInfo) target ).name();
|
||||||
*
|
}
|
||||||
* @param classLoaderService class loader service
|
else {
|
||||||
* @param classes the classes to index
|
String methodName = ( (MethodInfo) target ).name();
|
||||||
*
|
if ( methodName.startsWith( "is" ) ) {
|
||||||
* @return an annotation repository w/ all the annotation discovered in the specified classes
|
methodName = Introspector.decapitalize( methodName.substring( 2 ) );
|
||||||
*/
|
}
|
||||||
public static Index indexForClass(ClassLoaderService classLoaderService, Class<?>... classes) {
|
else if ( methodName.startsWith( "has" ) ) {
|
||||||
Indexer indexer = new Indexer();
|
methodName = Introspector.decapitalize( methodName.substring( 3 ) );
|
||||||
for ( Class<?> clazz : classes ) {
|
}
|
||||||
InputStream stream = classLoaderService.locateResourceStream(
|
else if ( methodName.startsWith( "get" ) ) {
|
||||||
clazz.getName().replace( '.', '/' ) + ".class"
|
methodName = Introspector.decapitalize( methodName.substring( 3 ) );
|
||||||
);
|
}
|
||||||
try {
|
else {
|
||||||
indexer.index( stream );
|
throw new AssertionFailure( "Expected a method following the Java Bean notation" );
|
||||||
}
|
}
|
||||||
catch ( IOException e ) {
|
return methodName;
|
||||||
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<DotName, List<AnnotationInstance>> getMemberAnnotations(ClassInfo classInfo, String name) {
|
/**
|
||||||
if ( classInfo == null ) {
|
* @param classInfo the class info from which to retrieve the annotation instance
|
||||||
throw new IllegalArgumentException( "classInfo cannot be null" );
|
* @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<DotName, List<AnnotationInstance>> annotations, DotName annotationName)
|
||||||
|
throws AssertionFailure {
|
||||||
|
List<AnnotationInstance> 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<DotName, List<AnnotationInstance>> annotations = new HashMap<DotName, List<AnnotationInstance>>();
|
/**
|
||||||
for ( List<AnnotationInstance> annotationList : classInfo.annotations().values() ) {
|
* Retrieves a jandex annotation element value. If the value is <code>null</code>, the default value specified in the
|
||||||
for ( AnnotationInstance instance : annotationList ) {
|
* annotation class is retrieved instead. Note, {@link #getValueAsEnum(Index, AnnotationInstance, String, Class)} must be
|
||||||
String targetName = null;
|
* called to retrieve an enumerated value, and {@link #getValueAsArray(AnnotationInstance, String)} must be called to retrieve
|
||||||
if ( instance.target() instanceof FieldInfo ) {
|
* an object array (other than a String array).
|
||||||
targetName = ( (FieldInfo) instance.target() ).name();
|
*
|
||||||
}
|
* @param index the jandex index containing the supplied annotation
|
||||||
else if ( instance.target() instanceof MethodInfo ) {
|
* @param annotation the annotation containing the element with the supplied name
|
||||||
targetName = ( (MethodInfo) instance.target() ).name();
|
* @param element the name of the element value to be retrieve
|
||||||
}
|
* @return the value if not <code>null</code>, else the default value if not
|
||||||
if ( targetName != null && name.equals( targetName ) ) {
|
* <code>null</code>, else <code>null</code>.
|
||||||
addAnnotationToMap( instance, annotations );
|
*/
|
||||||
}
|
public static Object getValue( Index index,
|
||||||
}
|
AnnotationInstance annotation,
|
||||||
}
|
String element ) {
|
||||||
return annotations;
|
AnnotationValue val = annotation.value(element);
|
||||||
}
|
if (val == null) return getDefaultValue(index, annotation, element);
|
||||||
|
return val.asNested();
|
||||||
|
}
|
||||||
|
|
||||||
public static Map<DotName, List<AnnotationInstance>> getTypeAnnotations(ClassInfo classInfo) {
|
/**
|
||||||
if ( classInfo == null ) {
|
* Retrieves a jandex annotation element array. Note, {@link #getValue(Index, AnnotationInstance, String)} may be
|
||||||
throw new IllegalArgumentException( "classInfo cannot be null" );
|
* 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 <code>null</code>, 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<DotName, List<AnnotationInstance>> annotations = new HashMap<DotName, List<AnnotationInstance>>();
|
/**
|
||||||
for ( List<AnnotationInstance> annotationList : classInfo.annotations().values() ) {
|
* Retrieves a jandex annotation element value, converting it to the supplied enumerated type. If the value is
|
||||||
for ( AnnotationInstance instance : annotationList ) {
|
* <code>null</code>, the default value specified in the annotation class is retrieved instead.
|
||||||
if ( instance.target() instanceof ClassInfo ) {
|
*
|
||||||
addAnnotationToMap( instance, annotations );
|
* @param <T> 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
|
||||||
return annotations;
|
* @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 <code>null</code>, else the default value if
|
||||||
|
* not <code>null</code>, else <code>null</code>.
|
||||||
|
* @see #getValue(Index, AnnotationInstance, String)
|
||||||
|
*/
|
||||||
|
public static <T extends Enum<T>> T getValueAsEnum( Index index,
|
||||||
|
AnnotationInstance annotation,
|
||||||
|
String element,
|
||||||
|
Class<T> 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<DotName, List<AnnotationInstance>> annotations) {
|
/**
|
||||||
DotName dotName = instance.name();
|
* Retrieves a jandex annotation element value as an Integer. If the value is <code>null</code>, the default value specified in
|
||||||
List<AnnotationInstance> list;
|
* the annotation class is retrieved instead.
|
||||||
if ( annotations.containsKey( dotName ) ) {
|
*
|
||||||
list = annotations.get( dotName );
|
* @param index the jandex index containing the supplied annotation
|
||||||
}
|
* @param annotation the annotation containing the element with the supplied name
|
||||||
else {
|
* @param element the name of the element value to be retrieve
|
||||||
list = new ArrayList<AnnotationInstance>();
|
* @return the value converted to an int if the value is not <code>null</code>, else the default value if not
|
||||||
annotations.put( dotName, list );
|
* <code>null</code>, else <code>0</code>.
|
||||||
}
|
*/
|
||||||
list.add( instance );
|
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 <code>null</code>, 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 <code>null</code>, else the default value if not
|
||||||
|
* <code>null</code>, else <code>null</code>.
|
||||||
|
*/
|
||||||
|
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<DotName, List<AnnotationInstance>> 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<DotName, List<AnnotationInstance>> annotations = new HashMap<DotName, List<AnnotationInstance>>();
|
||||||
|
for ( List<AnnotationInstance> 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<DotName, List<AnnotationInstance>> getTypeAnnotations(ClassInfo classInfo) {
|
||||||
|
if ( classInfo == null ) {
|
||||||
|
throw new IllegalArgumentException( "classInfo cannot be null" );
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<DotName, List<AnnotationInstance>> annotations = new HashMap<DotName, List<AnnotationInstance>>();
|
||||||
|
for ( List<AnnotationInstance> 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<DotName, List<AnnotationInstance>> annotations) {
|
||||||
|
DotName dotName = instance.name();
|
||||||
|
List<AnnotationInstance> list;
|
||||||
|
if ( annotations.containsKey( dotName ) ) {
|
||||||
|
list = annotations.get( dotName );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
list = new ArrayList<AnnotationInstance>();
|
||||||
|
annotations.put( dotName, list );
|
||||||
|
}
|
||||||
|
list.add( instance );
|
||||||
|
}
|
||||||
|
|
||||||
|
private JandexHelper() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,18 +23,19 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.source.hbm;
|
package org.hibernate.metamodel.source.hbm;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import org.dom4j.Attribute;
|
import org.dom4j.Attribute;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.cfg.NamingStrategy;
|
import org.hibernate.cfg.NamingStrategy;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
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.domain.MetaAttribute;
|
||||||
import org.hibernate.metamodel.source.Origin;
|
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;
|
||||||
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLFetchProfileElement.XMLFetch;
|
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLFetchProfileElement.XMLFetch;
|
||||||
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping;
|
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.XMLSqlQueryElement;
|
||||||
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSubclassElement;
|
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSubclassElement;
|
||||||
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLUnionSubclassElement;
|
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;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -225,14 +226,15 @@ public class HibernateMappingBinder implements MappingDefaults {
|
||||||
protected void parseFetchProfiles(List<XMLFetchProfileElement> fetchProfiles, String containingEntityName) {
|
protected void parseFetchProfiles(List<XMLFetchProfileElement> fetchProfiles, String containingEntityName) {
|
||||||
for ( XMLFetchProfileElement fetchProfile : fetchProfiles ) {
|
for ( XMLFetchProfileElement fetchProfile : fetchProfiles ) {
|
||||||
String profileName = fetchProfile.getName();
|
String profileName = fetchProfile.getName();
|
||||||
org.hibernate.metamodel.binding.FetchProfile profile = hibernateXmlBinder.getMetadata().findOrCreateFetchProfile( profileName, MetadataSource.HBM );
|
Set<Fetch> fetches = new HashSet<Fetch>();
|
||||||
for ( XMLFetch fetch : fetchProfile.getFetch() ) {
|
for ( XMLFetch fetch : fetchProfile.getFetch() ) {
|
||||||
String entityName = fetch.getEntity() == null ? containingEntityName : fetch.getEntity();
|
String entityName = fetch.getEntity() == null ? containingEntityName : fetch.getEntity();
|
||||||
if ( entityName == null ) {
|
if ( entityName == null ) {
|
||||||
throw new MappingException( "could not determine entity for fetch-profile fetch [" + profileName + "]:[" + fetch.getAssociation() + "]" );
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,21 +30,21 @@ import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jboss.jandex.Index;
|
import org.jboss.jandex.Index;
|
||||||
import org.jboss.jandex.Indexer;
|
import org.jboss.jandex.Indexer;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.hibernate.DuplicateMappingException;
|
import org.hibernate.DuplicateMappingException;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.SessionFactory;
|
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.internal.CoreMessageLogger;
|
||||||
import org.hibernate.mapping.MetadataSource;
|
|
||||||
import org.hibernate.metamodel.Metadata;
|
|
||||||
import org.hibernate.metamodel.MetadataSources;
|
import org.hibernate.metamodel.MetadataSources;
|
||||||
import org.hibernate.metamodel.SourceProcessingOrder;
|
import org.hibernate.metamodel.SourceProcessingOrder;
|
||||||
import org.hibernate.metamodel.binding.EntityBinding;
|
import org.hibernate.metamodel.binding.EntityBinding;
|
||||||
import org.hibernate.metamodel.binding.FetchProfile;
|
import org.hibernate.metamodel.binding.FetchProfile;
|
||||||
|
import org.hibernate.metamodel.binding.IdGenerator;
|
||||||
import org.hibernate.metamodel.binding.PluralAttributeBinding;
|
import org.hibernate.metamodel.binding.PluralAttributeBinding;
|
||||||
import org.hibernate.metamodel.binding.TypeDef;
|
import org.hibernate.metamodel.binding.TypeDef;
|
||||||
import org.hibernate.metamodel.relational.Database;
|
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.metamodel.source.spi.MetadataImplementor;
|
||||||
import org.hibernate.service.BasicServiceRegistry;
|
import org.hibernate.service.BasicServiceRegistry;
|
||||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||||
|
import org.hibernate.type.TypeResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container for configuration data collected during binding the metamodel.
|
* Container for configuration data collected during binding the metamodel.
|
||||||
|
@ -63,15 +64,15 @@ import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
*/
|
*/
|
||||||
public class MetadataImpl implements Metadata, MetadataImplementor, Serializable {
|
public class MetadataImpl implements MetadataImplementor, Serializable {
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
|
||||||
CoreMessageLogger.class, MetadataImpl.class.getName()
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, MetadataImpl.class.getName());
|
||||||
);
|
|
||||||
|
|
||||||
private final BasicServiceRegistry serviceRegistry;
|
private final BasicServiceRegistry serviceRegistry;
|
||||||
private final Options options;
|
private final Options options;
|
||||||
|
|
||||||
private final Database database = new Database();
|
private final Database database = new Database();
|
||||||
|
private TypeResolver typeResolver = new TypeResolver();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps the fully qualified class name of an entity to its entity binding
|
* 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<String, EntityBinding> entityBindingMap = new HashMap<String, EntityBinding>();
|
private Map<String, EntityBinding> entityBindingMap = new HashMap<String, EntityBinding>();
|
||||||
private Map<String, PluralAttributeBinding> collectionBindingMap = new HashMap<String, PluralAttributeBinding>();
|
private Map<String, PluralAttributeBinding> collectionBindingMap = new HashMap<String, PluralAttributeBinding>();
|
||||||
private Map<String, FetchProfile> fetchProfiles = new HashMap<String, FetchProfile>();
|
private Map<String, FetchProfile> fetchProfiles = new HashMap<String, FetchProfile>();
|
||||||
private Map<String, TypeDef> typeDefs = new HashMap<String, TypeDef>();
|
|
||||||
private Map<String, String> imports;
|
private Map<String, String> imports;
|
||||||
|
private Map<String, TypeDef> typeDefs = new HashMap<String, TypeDef>();
|
||||||
|
private Map<String, IdGenerator> idGenerators = new HashMap<String, IdGenerator>();
|
||||||
|
private Map<String, NamedQueryDefinition> namedQueryDefs = new HashMap<String, NamedQueryDefinition>();
|
||||||
|
private Map<String, NamedSQLQueryDefinition> namedNativeQueryDefs = new HashMap<String, NamedSQLQueryDefinition>();
|
||||||
|
private Map<String, FilterDefinition> filterDefs = new HashMap<String, FilterDefinition>();
|
||||||
|
|
||||||
public MetadataImpl(MetadataSources metadataSources, Options options) {
|
public MetadataImpl(MetadataSources metadataSources, Options options) {
|
||||||
this.serviceRegistry = metadataSources.getServiceRegistry();
|
this.serviceRegistry = metadataSources.getServiceRegistry();
|
||||||
|
@ -99,6 +104,33 @@ public class MetadataImpl implements Metadata, MetadataImplementor, Serializable
|
||||||
new EntityReferenceResolver( this ).resolve();
|
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<String> processedEntityNames) {
|
private void applyHibernateMappings(MetadataSources metadataSources, List<String> processedEntityNames) {
|
||||||
final HibernateXmlBinder hibernateXmlBinder = new HibernateXmlBinder( this );
|
final HibernateXmlBinder hibernateXmlBinder = new HibernateXmlBinder( this );
|
||||||
for ( JaxbRoot jaxbRoot : metadataSources.getJaxbRootList() ) {
|
for ( JaxbRoot jaxbRoot : metadataSources.getJaxbRootList() ) {
|
||||||
|
@ -223,25 +255,15 @@ public class MetadataImpl implements Metadata, MetadataImplementor, Serializable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<FetchProfile> 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) {
|
public TypeDef getTypeDef(String name) {
|
||||||
return typeDefs.get( name );
|
return typeDefs.get( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
public FetchProfile findOrCreateFetchProfile(String profileName, MetadataSource source) {
|
public Iterable<FetchProfile> getFetchProfiles() {
|
||||||
FetchProfile profile = fetchProfiles.get( profileName );
|
return fetchProfiles.values();
|
||||||
if ( profile == null ) {
|
}
|
||||||
profile = new FetchProfile( profileName, source );
|
|
||||||
fetchProfiles.put( profileName, profile );
|
public TypeResolver typeResolver() {
|
||||||
}
|
return typeResolver;
|
||||||
return profile;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.source.spi;
|
package org.hibernate.metamodel.source.spi;
|
||||||
|
|
||||||
import org.hibernate.mapping.MetadataSource;
|
|
||||||
import org.hibernate.metamodel.Metadata;
|
import org.hibernate.metamodel.Metadata;
|
||||||
import org.hibernate.metamodel.binding.EntityBinding;
|
import org.hibernate.metamodel.binding.EntityBinding;
|
||||||
import org.hibernate.metamodel.binding.FetchProfile;
|
import org.hibernate.metamodel.binding.FetchProfile;
|
||||||
|
@ -47,5 +46,5 @@ public interface MetadataImplementor extends Metadata {
|
||||||
|
|
||||||
public void addCollection(PluralAttributeBinding collectionBinding);
|
public void addCollection(PluralAttributeBinding collectionBinding);
|
||||||
|
|
||||||
public FetchProfile findOrCreateFetchProfile(String profileName, MetadataSource hbm);
|
public void addFetchProfile( FetchProfile profile );
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,17 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.source.annotations.util;
|
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.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.persistence.Basic;
|
import javax.persistence.Basic;
|
||||||
import javax.persistence.Column;
|
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.AnnotationInstance;
|
||||||
import org.jboss.jandex.ClassInfo;
|
import org.jboss.jandex.ClassInfo;
|
||||||
|
@ -36,6 +43,7 @@ import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||||
import org.hibernate.service.ServiceRegistryBuilder;
|
import org.hibernate.service.ServiceRegistryBuilder;
|
||||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.service.internal.BasicServiceRegistryImpl;
|
import org.hibernate.service.internal.BasicServiceRegistryImpl;
|
||||||
|
@ -88,6 +96,49 @@ public class JandexHelperTest extends BaseUnitTestCase {
|
||||||
memberAnnotations = JandexHelper.getMemberAnnotations( classInfo, "fubar" );
|
memberAnnotations = JandexHelper.getMemberAnnotations( classInfo, "fubar" );
|
||||||
assertTrue( "there should be no annotations in fubar", memberAnnotations.isEmpty() );
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue