Added @FetchProfile and @FetchProfiles annotations and wired them up. Added also some error handling in the AnnotationBinder.
Refactor the handling of precedence in the AnnotationConfiguration, because I thought I would be reusing it for the fetch profile as well, but in the end decided to jsut implement in a way that xml configured fetch profiles always win over annotation confgured ones.


git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18924 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Hardy Ferentschik 2010-03-04 21:55:10 +00:00
parent 5b595bcf26
commit 153ad753e1
20 changed files with 1596 additions and 386 deletions

View File

@ -0,0 +1,55 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.PACKAGE;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Define the fetching strategy profile.
*
* @author Hardy Ferentschik
*/
@Target({ TYPE, PACKAGE })
@Retention(RUNTIME)
public @interface FetchProfile {
String name();
FetchOverride[] fetchOverrides();
@Target({ TYPE, PACKAGE })
@Retention(RUNTIME)
@interface FetchOverride {
Class<?> entity();
String association();
FetchMode mode();
}
}

View File

@ -0,0 +1,41 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.PACKAGE;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* @author Hardy Ferentschik
*/
@Target({ TYPE, PACKAGE })
@Retention(RUNTIME)
public @interface FetchProfiles {
public abstract FetchProfile[] value();
}

View File

@ -33,7 +33,9 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@ -55,10 +57,10 @@ import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ErrorHandler;
import org.hibernate.AnnotationException;
import org.hibernate.DuplicateMappingException;
@ -68,12 +70,12 @@ import org.hibernate.MappingException;
import org.hibernate.SessionFactory;
import org.hibernate.annotations.AnyMetaDef;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.annotations.common.reflection.MetadataProvider;
import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.cfg.annotations.Version;
import org.hibernate.cfg.annotations.reflection.JPAMetadataProvider;
import org.hibernate.cfg.beanvalidation.BeanValidationActivator;
@ -84,15 +86,16 @@ import org.hibernate.event.EventListeners;
import org.hibernate.event.PreInsertEventListener;
import org.hibernate.event.PreUpdateEventListener;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.FetchProfile;
import org.hibernate.mapping.IdGenerator;
import org.hibernate.mapping.Join;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.UniqueKey;
import org.hibernate.util.CollectionHelper;
import org.hibernate.util.JoinedIterator;
import org.hibernate.util.ReflectHelper;
import org.hibernate.util.StringHelper;
import org.hibernate.util.CollectionHelper;
/**
* Similar to the {@link Configuration} object but handles EJB3 and Hibernate
@ -132,8 +135,9 @@ public class AnnotationConfiguration extends Configuration {
Version.touch(); //touch version
}
public static final String ARTEFACT = "hibernate.mapping.precedence";
public static final String DEFAULT_PRECEDENCE = "hbm, class";
public static final String ARTEFACT_PROCESSING_ORDER = "hibernate.mapping.precedence";
public static final ConfigurationArtefactType[] DEFAULT_ARTEFACT_PROCESSING_ORDER =
new ConfigurationArtefactType[] { ConfigurationArtefactType.HBM, ConfigurationArtefactType.CLASS };
private Map<String, IdGenerator> namedGenerators;
private Map<String, Map<String, Join>> joins;
@ -152,13 +156,13 @@ public class AnnotationConfiguration extends Configuration {
private Map<String, Document> hbmEntities;
private List<CacheHolder> caches;
private List<Document> hbmDocuments; //user ordering matters, hence the list
private String precedence = null;
private List<ConfigurationArtefactType> configurationArtefactPrecedence;
private boolean inSecondPass = false;
private transient ReflectionManager reflectionManager;
private boolean isDefaultProcessed = false;
private boolean isValidatorNotPresentLogged;
private Map<XClass,Map<String,PropertyData>> propertiesAnnotatedWithMapsId;
private Map<XClass,Map<String,PropertyData>> propertiesAnnotatedWithIdAndToOne;
private Map<XClass, Map<String, PropertyData>> propertiesAnnotatedWithMapsId;
private Map<XClass, Map<String, PropertyData>> propertiesAnnotatedWithIdAndToOne;
public AnnotationConfiguration() {
super();
@ -173,9 +177,10 @@ public class AnnotationConfiguration extends Configuration {
* ordered list.
*
* @param original The list of all entities annotated with {@code @Entity} or {@code @MappedSuperclass}
*
* @return Ordered list of entities including superclasses for entities which have any. Class hierachies are
* listed bottom up (starting from the top level base class). There is no indication in the list when a new class
* (hierarchy) starts.
* listed bottom up (starting from the top level base class). There is no indication in the list when a new class
* (hierarchy) starts.
*/
protected List<XClass> orderAndFillHierarchy(List<XClass> original) {
List<XClass> copy = new ArrayList<XClass>( original );
@ -226,6 +231,8 @@ public class AnnotationConfiguration extends Configuration {
* @param persistentClass the mapped class
*
* @return the configuration object
*
* @throws MappingException in case there is a configuration error for the specified class
*/
public AnnotationConfiguration addAnnotatedClass(Class persistentClass) throws MappingException {
XClass persistentXClass = reflectionManager.toXClass( persistentClass );
@ -240,11 +247,13 @@ public class AnnotationConfiguration extends Configuration {
}
/**
* Read package level metadata
* Read package level metadata.
*
* @param packageName java package name
*
* @return the configuration object
*
* @throws MappingException in case there is an error in the mapping data
*/
public AnnotationConfiguration addPackage(String packageName) throws MappingException {
log.info( "Mapping package {}", packageName );
@ -297,11 +306,11 @@ public class AnnotationConfiguration extends Configuration {
namingStrategy = EJB3NamingStrategy.INSTANCE;
setEntityResolver( new EJB3DTDEntityResolver() );
anyMetaDefs = new HashMap<String, AnyMetaDef>();
propertiesAnnotatedWithMapsId = new HashMap<XClass, Map<String,PropertyData>>();
propertiesAnnotatedWithIdAndToOne = new HashMap<XClass, Map<String,PropertyData>>();
propertiesAnnotatedWithMapsId = new HashMap<XClass, Map<String, PropertyData>>();
propertiesAnnotatedWithIdAndToOne = new HashMap<XClass, Map<String, PropertyData>>();
reflectionManager = new JavaReflectionManager();
( ( MetadataProviderInjector ) reflectionManager ).setMetadataProvider( new JPAMetadataProvider() );
configurationArtefactPrecedence = Collections.emptyList();
}
@Override
@ -327,7 +336,7 @@ public class AnnotationConfiguration extends Configuration {
if ( !isDefaultProcessed ) {
//use global delimiters if orm.xml declare it
final Object isDelimited = reflectionManager.getDefaults().get( "delimited-identifier" );
if (isDelimited != null && isDelimited == Boolean.TRUE) {
if ( isDelimited != null && isDelimited == Boolean.TRUE ) {
getProperties().put( Environment.GLOBALLY_QUOTED_IDENTIFIERS, "true" );
}
@ -336,20 +345,18 @@ public class AnnotationConfiguration extends Configuration {
}
//process entities
if ( precedence == null ) {
precedence = getProperties().getProperty( ARTEFACT );
if ( configurationArtefactPrecedence.isEmpty()
&& StringHelper.isNotEmpty( getProperties().getProperty( ARTEFACT_PROCESSING_ORDER ) ) ) {
configurationArtefactPrecedence = parsePrecedence( getProperties().getProperty( ARTEFACT_PROCESSING_ORDER ) );
}
if ( precedence == null ) {
precedence = DEFAULT_PRECEDENCE;
if ( configurationArtefactPrecedence.isEmpty() ) {
configurationArtefactPrecedence = Arrays.asList( DEFAULT_ARTEFACT_PROCESSING_ORDER );
}
StringTokenizer precedences = new StringTokenizer( precedence, ",; ", false );
if ( !precedences.hasMoreElements() ) {
throw new MappingException( ARTEFACT + " cannot be empty: " + precedence );
}
while ( precedences.hasMoreElements() ) {
String artifact = ( String ) precedences.nextElement();
removeConflictedArtifact( artifact );
processArtifactsOfType( artifact );
configurationArtefactPrecedence = Collections.unmodifiableList( configurationArtefactPrecedence );
for ( ConfigurationArtefactType p : configurationArtefactPrecedence ) {
removeConflictedArtifact( p );
processArtifactsOfType( p );
}
int cacheNbr = caches.size();
@ -381,11 +388,9 @@ public class AnnotationConfiguration extends Configuration {
throw ( RuntimeException ) e.getCause();
}
Iterator<Map.Entry<Table,List<UniqueConstraintHolder>>> tables = uniqueConstraintHoldersByTable.entrySet().iterator();
while ( tables.hasNext() ) {
final Map.Entry<Table,List<UniqueConstraintHolder>> entry = tables.next();
final Table table = entry.getKey();
final List<UniqueConstraintHolder> uniqueConstraints = entry.getValue();
for ( Map.Entry<Table, List<UniqueConstraintHolder>> tableListEntry : uniqueConstraintHoldersByTable.entrySet() ) {
final Table table = tableListEntry.getKey();
final List<UniqueConstraintHolder> uniqueConstraints = tableListEntry.getValue();
int uniqueIndexPerTable = 0;
for ( UniqueConstraintHolder holder : uniqueConstraints ) {
uniqueIndexPerTable++;
@ -607,8 +612,8 @@ public class AnnotationConfiguration extends Configuration {
}
}
private void processArtifactsOfType(String artifact) {
if ( "hbm".equalsIgnoreCase( artifact ) ) {
private void processArtifactsOfType(ConfigurationArtefactType p) {
if ( ConfigurationArtefactType.HBM.equals( p ) ) {
log.debug( "Process hbm files" );
for ( Document document : hbmDocuments ) {
super.add( document );
@ -616,7 +621,7 @@ public class AnnotationConfiguration extends Configuration {
hbmDocuments.clear();
hbmEntities.clear();
}
else if ( "class".equalsIgnoreCase( artifact ) ) {
else if ( ConfigurationArtefactType.CLASS.equals( p ) ) {
log.debug( "Process annotated classes" );
//bind classes in the correct order calculating some inheritance state
List<XClass> orderedClasses = orderAndFillHierarchy( annotatedClasses );
@ -633,13 +638,10 @@ public class AnnotationConfiguration extends Configuration {
annotatedClasses.clear();
annotatedClassEntities.clear();
}
else {
log.warn( "Unknown artifact: {}", artifact );
}
}
private void removeConflictedArtifact(String artifact) {
if ( "hbm".equalsIgnoreCase( artifact ) ) {
private void removeConflictedArtifact(ConfigurationArtefactType p) {
if ( ConfigurationArtefactType.HBM.equals( p ) ) {
for ( String entity : hbmEntities.keySet() ) {
if ( annotatedClassEntities.containsKey( entity ) ) {
annotatedClasses.remove( annotatedClassEntities.get( entity ) );
@ -647,7 +649,7 @@ public class AnnotationConfiguration extends Configuration {
}
}
}
else if ( "class".equalsIgnoreCase( artifact ) ) {
else if ( ConfigurationArtefactType.CLASS.equals( p ) ) {
for ( String entity : annotatedClassEntities.keySet() ) {
if ( hbmEntities.containsKey( entity ) ) {
hbmDocuments.remove( hbmEntities.get( entity ) );
@ -832,23 +834,19 @@ public class AnnotationConfiguration extends Configuration {
}
public void setPrecedence(String precedence) {
this.precedence = precedence;
this.configurationArtefactPrecedence = parsePrecedence( precedence );
}
private static class CacheHolder {
public CacheHolder(String role, String usage, String region, boolean isClass, boolean cacheLazy) {
this.role = role;
this.usage = usage;
this.region = region;
this.isClass = isClass;
this.cacheLazy = cacheLazy;
private List<ConfigurationArtefactType> parsePrecedence(String s) {
if ( StringHelper.isEmpty( s ) ) {
return Collections.emptyList();
}
public String role;
public String usage;
public String region;
public boolean isClass;
public boolean cacheLazy;
StringTokenizer precedences = new StringTokenizer( s, ",; ", false );
List<ConfigurationArtefactType> tmpPrecedences = new ArrayList<ConfigurationArtefactType>();
while ( precedences.hasMoreElements() ) {
tmpPrecedences.add( ConfigurationArtefactType.parsePrecedence( ( String ) precedences.nextElement() ) );
}
return tmpPrecedences;
}
@Override
@ -860,11 +858,11 @@ public class AnnotationConfiguration extends Configuration {
* - if it fails because of the version attribute mismatch, try and validate the document with orm_1_0.xsd
*/
List<SAXParseException> errors = new ArrayList<SAXParseException>();
SAXReader saxReader = new SAXReader( );
SAXReader saxReader = new SAXReader();
saxReader.setEntityResolver( getEntityResolver() );
saxReader.setErrorHandler( new ErrorLogger(errors) );
saxReader.setMergeAdjacentText(true);
saxReader.setValidation(true);
saxReader.setErrorHandler( new ErrorLogger( errors ) );
saxReader.setMergeAdjacentText( true );
saxReader.setValidation( true );
setValidationFor( saxReader, "orm_2_0.xsd" );
@ -880,7 +878,7 @@ public class AnnotationConfiguration extends Configuration {
if ( e.getCause() == null || !( throwable instanceof SAXParseException ) ) {
throw new MappingException( "Could not parse JPA mapping document", e );
}
errors.add( (SAXParseException) throwable );
errors.add( ( SAXParseException ) throwable );
}
boolean isV1Schema = false;
@ -889,11 +887,11 @@ public class AnnotationConfiguration extends Configuration {
final String errorMessage = exception.getMessage();
//does the error look like a schema mismatch?
isV1Schema = doc != null
&& errorMessage.contains("1.0")
&& errorMessage.contains("2.0")
&& errorMessage.contains("version");
&& errorMessage.contains( "1.0" )
&& errorMessage.contains( "2.0" )
&& errorMessage.contains( "version" );
}
if (isV1Schema) {
if ( isV1Schema ) {
//reparse with v1
errors.clear();
setValidationFor( saxReader, "orm_1_0.xsd" );
@ -903,21 +901,21 @@ public class AnnotationConfiguration extends Configuration {
}
catch ( DocumentException e ) {
//oops asXML fails even if the core doc parses initially
throw new AssertionFailure("Error in DOM4J leads to a bug in Hibernate", e);
throw new AssertionFailure( "Error in DOM4J leads to a bug in Hibernate", e );
}
}
if ( errors.size() != 0 ) {
//report errors in exception
StringBuilder errorMessage = new StringBuilder( );
for (SAXParseException error : errors) {
errorMessage.append("Error parsing XML (line")
.append(error.getLineNumber())
.append(" : column ")
.append(error.getColumnNumber())
.append("): ")
.append(error.getMessage())
.append("\n");
StringBuilder errorMessage = new StringBuilder();
for ( SAXParseException error : errors ) {
errorMessage.append( "Error parsing XML (line" )
.append( error.getLineNumber() )
.append( " : column " )
.append( error.getColumnNumber() )
.append( "): " )
.append( error.getMessage() )
.append( "\n" );
}
throw new MappingException( "Invalid ORM mapping file.\n" + errorMessage.toString() );
}
@ -934,25 +932,6 @@ public class AnnotationConfiguration extends Configuration {
}
}
private static class ErrorLogger implements ErrorHandler {
private List<SAXParseException> errors;
public ErrorLogger(List<SAXParseException> errors) {
this.errors = errors;
}
public void warning(SAXParseException exception) throws SAXException {
errors.add( exception );
}
public void error(SAXParseException exception) throws SAXException {
errors.add( exception );
}
public void fatalError(SAXParseException exception) throws SAXException {
}
}
private void setValidationFor(SAXReader saxReader, String xsd) {
try {
saxReader.setFeature( "http://apache.org/xml/features/validation/schema", true );
@ -1267,11 +1246,19 @@ public class AnnotationConfiguration extends Configuration {
}
//not a public API
public ReflectionManager getReflectionManager() {
return reflectionManager;
}
protected class ExtendedMappingsImpl extends MappingsImpl implements ExtendedMappings {
private Boolean useNewGeneratorMappings;
private Collection<FetchProfile> annotationConfiguredProfile;
public ExtendedMappingsImpl() {
annotationConfiguredProfile = new ArrayList<FetchProfile>();
}
public void addDefaultGenerator(IdGenerator generator) {
this.addGenerator( generator );
defaultNamedGenerators.add( generator.getName() );
@ -1288,7 +1275,7 @@ public class AnnotationConfiguration extends Configuration {
public void addPropertyAnnotatedWithMapsId(XClass entityType, PropertyData property) {
Map<String, PropertyData> map = propertiesAnnotatedWithMapsId.get( entityType );
if (map == null) {
if ( map == null ) {
map = new HashMap<String, PropertyData>();
propertiesAnnotatedWithMapsId.put( entityType, map );
}
@ -1302,15 +1289,13 @@ public class AnnotationConfiguration extends Configuration {
public void addToOneAndIdProperty(XClass entityType, PropertyData property) {
Map<String, PropertyData> map = propertiesAnnotatedWithIdAndToOne.get( entityType );
if (map == null) {
if ( map == null ) {
map = new HashMap<String, PropertyData>();
propertiesAnnotatedWithIdAndToOne.put( entityType, map );
}
map.put( property.getPropertyName(), property );
}
private Boolean useNewGeneratorMappings;
@SuppressWarnings({ "UnnecessaryUnboxing" })
public boolean useNewGeneratorMappings() {
if ( useNewGeneratorMappings == null ) {
@ -1382,6 +1367,7 @@ public class AnnotationConfiguration extends Configuration {
}
//FIXME should be private but is part of the ExtendedMapping contract
public AnnotatedClassType addClassType(XClass clazz) {
AnnotatedClassType type;
if ( clazz.isAnnotationPresent( Entity.class ) ) {
@ -1420,16 +1406,10 @@ public class AnnotationConfiguration extends Configuration {
return deprecatedStructure;
}
/**
* {@inheritDoc}
*/
public Map<Table, List<UniqueConstraintHolder>> getUniqueConstraintHoldersByTable() {
return uniqueConstraintHoldersByTable;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public void addUniqueConstraints(Table table, List uniqueConstraints) {
List<UniqueConstraintHolder> constraintHolders = new ArrayList<UniqueConstraintHolder>(
@ -1437,7 +1417,7 @@ public class AnnotationConfiguration extends Configuration {
);
int keyNameBase = determineCurrentNumberOfUniqueConstraintHolders( table );
for ( String[] columns : (List<String[]>)uniqueConstraints ) {
for ( String[] columns : ( List<String[]> ) uniqueConstraints ) {
final String keyName = "key" + keyNameBase++;
constraintHolders.add(
new UniqueConstraintHolder().setName( keyName ).setColumns( columns )
@ -1453,9 +1433,6 @@ public class AnnotationConfiguration extends Configuration {
: currentHolders.size();
}
/**
* {@inheritDoc}
*/
public void addUniqueConstraintHolders(Table table, List<UniqueConstraintHolder> uniqueConstraintHolders) {
List<UniqueConstraintHolder> holderList = getUniqueConstraintHoldersByTable().get( table );
if ( holderList == null ) {
@ -1550,5 +1527,54 @@ public class AnnotationConfiguration extends Configuration {
public AnyMetaDef getAnyMetaDef(String name) {
return anyMetaDefs.get( name );
}
public void addAnnotationConfiguredFetchProfile(FetchProfile fetchProfile) {
annotationConfiguredProfile.add( fetchProfile );
}
public boolean containsAnnotationConfiguredFetchProfile(FetchProfile fetchProfile) {
for ( FetchProfile profile : annotationConfiguredProfile ) {
// we need reference equality there!!
if ( profile == fetchProfile ) {
return true;
}
}
return false;
}
}
private static class CacheHolder {
public CacheHolder(String role, String usage, String region, boolean isClass, boolean cacheLazy) {
this.role = role;
this.usage = usage;
this.region = region;
this.isClass = isClass;
this.cacheLazy = cacheLazy;
}
public String role;
public String usage;
public String region;
public boolean isClass;
public boolean cacheLazy;
}
private static class ErrorLogger implements ErrorHandler {
private List<SAXParseException> errors;
public ErrorLogger(List<SAXParseException> errors) {
this.errors = errors;
}
public void warning(SAXParseException exception) throws SAXException {
errors.add( exception );
}
public void error(SAXParseException exception) throws SAXException {
errors.add( exception );
}
public void fatalError(SAXParseException exception) throws SAXException {
}
}
}

View File

@ -0,0 +1,49 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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.cfg;
import org.hibernate.HibernateException;
/**
* @author Hardy Ferentschik
*/
public enum ConfigurationArtefactType {
HBM,
CLASS;
static ConfigurationArtefactType parsePrecedence(String s) {
if ( s.equalsIgnoreCase( "hbm" ) ) {
return HBM;
}
else if ( s.equalsIgnoreCase( "class" ) ) {
return CLASS;
}
else {
throw new HibernateException( "'" + s + "' - invalid value for precedence configuration." );
}
}
}

View File

@ -1,3 +1,4 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
@ -30,12 +31,12 @@ import java.util.Properties;
import org.hibernate.AnnotationException;
import org.hibernate.MappingException;
import org.hibernate.annotations.AnyMetaDef;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.engine.NamedQueryDefinition;
import org.hibernate.engine.NamedSQLQueryDefinition;
import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.mapping.FetchProfile;
import org.hibernate.mapping.IdGenerator;
import org.hibernate.mapping.Join;
import org.hibernate.mapping.PersistentClass;
@ -47,6 +48,7 @@ import org.hibernate.mapping.Table;
* at least for named generators
*
* @author Emmanuel Bernard
* @author Hardy Ferentschik
*/
public interface ExtendedMappings extends Mappings {
@ -61,6 +63,7 @@ public interface ExtendedMappings extends Mappings {
* Retrieve the id-generator by name.
*
* @param name The generator name.
*
* @return The generator, or null.
*/
public IdGenerator getGenerator(String name);
@ -71,6 +74,7 @@ public interface ExtendedMappings extends Mappings {
*
* @param name generator name
* @param localGenerators local generators
*
* @return the appropriate idgenerator or null if not found
*/
public IdGenerator getGenerator(String name, Map<String, IdGenerator> localGenerators);
@ -95,6 +99,7 @@ public interface ExtendedMappings extends Mappings {
*
* @param name generator name
* @param localGeneratorTables local generator tables
*
* @return The properties, or null.
*/
public Properties getGeneratorTableProperties(String name, Map<String, Properties> localGeneratorTables);
@ -103,6 +108,7 @@ public interface ExtendedMappings extends Mappings {
* Retrieve join metadata for a particular persistent entity.
*
* @param entityName The entity name
*
* @return The join metadata
*/
public Map<String, Join> getJoins(String entityName);
@ -112,6 +118,7 @@ public interface ExtendedMappings extends Mappings {
*
* @param persistentClass The persistent entity metadata.
* @param joins The join metadata to add.
*
* @throws MappingException
*/
public void addJoins(PersistentClass persistentClass, Map<String, Join> joins);
@ -120,6 +127,7 @@ public interface ExtendedMappings extends Mappings {
* Get and maintain a cache of class type.
*
* @param clazz The XClass mapping
*
* @return The class type.
*/
public AnnotatedClassType getClassType(XClass clazz);
@ -129,6 +137,7 @@ public interface ExtendedMappings extends Mappings {
* Add a class type.
*
* @param clazz The XClass mapping.
*
* @return The class type.
*/
public AnnotatedClassType addClassType(XClass clazz);
@ -170,7 +179,7 @@ public interface ExtendedMappings extends Mappings {
public void addAnyMetaDef(AnyMetaDef defAnn) throws AnnotationException;
public AnyMetaDef getAnyMetaDef(String name);
public boolean isInSecondPass();
/**
@ -196,4 +205,16 @@ public interface ExtendedMappings extends Mappings {
public PropertyData getPropertyAnnotatedWithIdAndToOne(XClass entityType, String propertyName);
void addToOneAndIdProperty(XClass entity, PropertyData property);
/**
* Add the specified profile to the list of fetch profiles configured via annotations.
*
* @param fetchProfile the fetch profile
*/
void addAnnotationConfiguredFetchProfile(FetchProfile fetchProfile);
/**
* @return {@true} if the provided fetch profile has been configured via xml, {@false otherwise}.
*/
boolean containsAnnotationConfiguredFetchProfile(FetchProfile fetchProfile);
}

View File

@ -0,0 +1,73 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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.cfg;
import java.util.Map;
import org.hibernate.MappingException;
import org.hibernate.annotations.FetchProfile;
import org.hibernate.mapping.PersistentClass;
/**
* @author Hardy Ferentschik
*/
public class VerifyFetchProfileReferenceSecondPass implements SecondPass {
private String fetchProfileName;
private FetchProfile.FetchOverride fetch;
private ExtendedMappings mappings;
public VerifyFetchProfileReferenceSecondPass(String fetchProfileName, FetchProfile.FetchOverride fetch, ExtendedMappings mappings) {
this.fetchProfileName = fetchProfileName;
this.fetch = fetch;
this.mappings = mappings;
}
public void doSecondPass(Map persistentClasses) throws MappingException {
org.hibernate.mapping.FetchProfile profile = mappings.findOrCreateFetchProfile( fetchProfileName );
if ( skipProfile( profile ) ) {
return;
}
PersistentClass clazz = mappings.getClass( fetch.entity().getName() );
// throws MappingException in case the property does not exist
clazz.getProperty( fetch.association() );
profile.addFetch(
fetch.entity().getName(), fetch.association(), fetch.mode().toString().toLowerCase()
);
}
private boolean skipProfile(org.hibernate.mapping.FetchProfile profile) {
if ( mappings.containsAnnotationConfiguredFetchProfile( profile ) ) {
return false;
}
// if there are fetches they must come from xml. If there are xml profiles the annotations get ignored
return !profile.getFetches().isEmpty();
}
}

View File

@ -36,7 +36,7 @@ public class ConfigurationTest extends junit.framework.TestCase {
AnnotationConfiguration cfg = new AnnotationConfiguration();
cfg.configure( "org/hibernate/test/annotations/hibernate.cfg.xml" );
cfg.setProperty( Environment.HBM2DDL_AUTO, "create-drop" );
cfg.setProperty( AnnotationConfiguration.ARTEFACT, "class, whatever" );
cfg.setProperty( AnnotationConfiguration.ARTEFACT_PROCESSING_ORDER, "class" );
SessionFactory sf = cfg.buildSessionFactory();
assertNotNull( sf );
Session s = sf.openSession();
@ -85,7 +85,7 @@ public class ConfigurationTest extends junit.framework.TestCase {
AnnotationConfiguration cfg = new AnnotationConfiguration();
cfg.configure( "org/hibernate/test/annotations/hibernate.cfg.xml" );
cfg.setProperty( Environment.HBM2DDL_AUTO, "create-drop" );
cfg.setProperty( AnnotationConfiguration.ARTEFACT, "class, hbm" );
cfg.setProperty( AnnotationConfiguration.ARTEFACT_PROCESSING_ORDER, "class, hbm" );
cfg.addAnnotatedClass( Boat.class );
SessionFactory sf = cfg.buildSessionFactory();
assertNotNull( sf );

View File

@ -1,4 +1,4 @@
//$Id:
// $Id:$
@AnyMetaDefs(
@AnyMetaDef( name= "Property", metaType = "string", idType = "integer",
metaValues = {

View File

@ -0,0 +1,92 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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.test.annotations.fetchprofile;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.FetchProfile;
/**
* @author Hardy Ferentschik
*/
@Entity
@FetchProfile(name = "customer-with-orders", fetchOverrides = {
@FetchProfile.FetchOverride(entity = Customer.class, association = "orders", mode = FetchMode.JOIN)
})
public class Customer {
@Id
@GeneratedValue
private long id;
private String name;
private long customerNumber;
@OneToMany
private Set<Order> orders;
@OneToMany
private Set<SupportTickets> tickets;
public long getCustomerNumber() {
return customerNumber;
}
public void setCustomerNumber(long customerNumber) {
this.customerNumber = customerNumber;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}

View File

@ -0,0 +1,88 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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.test.annotations.fetchprofile;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.FetchProfile;
/**
* @author Hardy Ferentschik
*/
@Entity
@FetchProfile(name = "customer-with-orders", fetchOverrides = {
@FetchProfile.FetchOverride(entity = Customer2.class, association = "foo", mode = FetchMode.JOIN)
})
public class Customer2 {
@Id
@GeneratedValue
private long id;
private String name;
private long customerNumber;
@OneToMany
private Set<Order> orders;
public long getCustomerNumber() {
return customerNumber;
}
public void setCustomerNumber(long customerNumber) {
this.customerNumber = customerNumber;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}

View File

@ -0,0 +1,88 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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.test.annotations.fetchprofile;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.FetchProfile;
/**
* @author Hardy Ferentschik
*/
@Entity
@FetchProfile(name = "wrong-class-name", fetchOverrides = {
@FetchProfile.FetchOverride(entity = Order.class, association = "orders", mode = FetchMode.JOIN)
})
public class Customer3 {
@Id
@GeneratedValue
private long id;
private String name;
private long customerNumber;
@OneToMany
private Set<Order> orders;
public long getCustomerNumber() {
return customerNumber;
}
public void setCustomerNumber(long customerNumber) {
this.customerNumber = customerNumber;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}

View File

@ -0,0 +1,88 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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.test.annotations.fetchprofile;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.FetchProfile;
/**
* @author Hardy Ferentschik
*/
@Entity
@FetchProfile(name = "unsupported-fetch-mode", fetchOverrides = {
@FetchProfile.FetchOverride(entity = Customer4.class, association = "orders", mode = FetchMode.SELECT)
})
public class Customer4 {
@Id
@GeneratedValue
private long id;
private String name;
private long customerNumber;
@OneToMany
private Set<Order> orders;
public long getCustomerNumber() {
return customerNumber;
}
public void setCustomerNumber(long customerNumber) {
this.customerNumber = customerNumber;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}

View File

@ -0,0 +1,88 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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.test.annotations.fetchprofile;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.FetchProfile;
/**
* @author Hardy Ferentschik
*/
@Entity
@FetchProfile(name = "orders-profile", fetchOverrides = {
@FetchProfile.FetchOverride(entity = Customer5.class, association = "foo", mode = FetchMode.JOIN)
})
public class Customer5 {
@Id
@GeneratedValue
private long id;
private String name;
private long customerNumber;
@OneToMany
private Set<Order> orders;
public long getCustomerNumber() {
return customerNumber;
}
public void setCustomerNumber(long customerNumber) {
this.customerNumber = customerNumber;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}

View File

@ -0,0 +1,151 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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.test.annotations.fetchprofile;
import java.io.InputStream;
import junit.framework.TestCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.MappingException;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.engine.SessionFactoryImplementor;
/**
* Test case for HHH-4812
*
* @author Hardy Ferentschik
*/
public class FetchProfileTest extends TestCase {
private Logger log = LoggerFactory.getLogger( FetchProfileTest.class );
public void testFetchProfileConfigured() {
AnnotationConfiguration config = new AnnotationConfiguration();
config.addAnnotatedClass( Customer.class );
config.addAnnotatedClass( Order.class );
config.addAnnotatedClass( SupportTickets.class );
SessionFactoryImplementor sessionImpl = ( SessionFactoryImplementor ) config.buildSessionFactory();
assertTrue(
"fetch profile not parsed properly",
sessionImpl.containsFetchProfileDefinition( "customer-with-orders" )
);
assertFalse(
"package info should not be parsed",
sessionImpl.containsFetchProfileDefinition( "package-profile-1" )
);
}
public void testWrongAssociationName() {
AnnotationConfiguration config = new AnnotationConfiguration();
config.addAnnotatedClass( Customer2.class );
config.addAnnotatedClass( Order.class );
try {
config.buildSessionFactory();
fail();
}
catch ( MappingException e ) {
log.trace( "success" );
}
}
public void testWrongClass() {
AnnotationConfiguration config = new AnnotationConfiguration();
config.addAnnotatedClass( Customer3.class );
config.addAnnotatedClass( Order.class );
try {
config.buildSessionFactory();
fail();
}
catch ( MappingException e ) {
log.trace( "success" );
}
}
public void testUnsupportedFetchMode() {
AnnotationConfiguration config = new AnnotationConfiguration();
config.addAnnotatedClass( Customer4.class );
config.addAnnotatedClass( Order.class );
try {
config.buildSessionFactory();
fail();
}
catch ( MappingException e ) {
log.trace( "success" );
}
}
public void testXmlOverride() {
AnnotationConfiguration config = new AnnotationConfiguration();
config.addAnnotatedClass( Customer5.class );
config.addAnnotatedClass( Order.class );
InputStream is = Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream( "org/hibernate/test/annotations/fetchprofile/mappings.hbm.xml" );
config.addInputStream( is );
SessionFactoryImplementor sessionImpl = ( SessionFactoryImplementor ) config.buildSessionFactory();
assertTrue(
"fetch profile not parsed properly",
sessionImpl.containsFetchProfileDefinition( "orders-profile" )
);
// now the same with no xml
config = new AnnotationConfiguration();
config.addAnnotatedClass( Customer5.class );
config.addAnnotatedClass( Order.class );
try {
config.buildSessionFactory();
fail();
}
catch ( MappingException e ) {
log.trace( "success" );
}
}
public void testPackageConfiguredFetchProfile() {
AnnotationConfiguration config = new AnnotationConfiguration();
config.addAnnotatedClass( Customer.class );
config.addAnnotatedClass( Order.class );
config.addAnnotatedClass( SupportTickets.class );
config.addPackage( Customer.class.getPackage().getName() );
SessionFactoryImplementor sessionImpl = ( SessionFactoryImplementor ) config.buildSessionFactory();
assertTrue(
"fetch profile not parsed properly",
sessionImpl.containsFetchProfileDefinition( "package-profile-1" )
);
assertTrue(
"fetch profile not parsed properly",
sessionImpl.containsFetchProfileDefinition( "package-profile-2" )
);
}
}

View File

@ -0,0 +1,71 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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.test.annotations.fetchprofile;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
* @author Hardy Ferentschik
*/
@Entity
public class Order {
@Id
@GeneratedValue
private long id;
private long orderNumber;
private Date deliveryDate;
public Date getDeliveryDate() {
return deliveryDate;
}
public void setDeliveryDate(Date deliveryDate) {
this.deliveryDate = deliveryDate;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public long getOrderNumber() {
return orderNumber;
}
public void setOrderNumber(long orderNumber) {
this.orderNumber = orderNumber;
}
}

View File

@ -0,0 +1,70 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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.test.annotations.fetchprofile;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
* @author Hardy Ferentschik
*/
@Entity
public class SupportTickets {
@Id
@GeneratedValue
private long id;
private String description;
private String resolution;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getResolution() {
return resolution;
}
public void setResolution(String resolution) {
this.resolution = resolution;
}
}

View File

@ -0,0 +1,41 @@
// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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
*
*/
@FetchProfiles({
@FetchProfile(name = "package-profile-1", fetchOverrides = {
@FetchProfile.FetchOverride(entity = Customer.class, association = "orders", mode = FetchMode.JOIN)
}),
@FetchProfile(name = "package-profile-2", fetchOverrides = {
@FetchProfile.FetchOverride(entity = Customer.class, association = "tickets", mode = FetchMode.JOIN)
})
})
package org.hibernate.test.annotations.fetchprofile;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.FetchProfile;
import org.hibernate.annotations.FetchProfiles;

View File

@ -0,0 +1,35 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
SYSTEM
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
~
~ 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
~
-->
<hibernate-mapping package="org.hibernate.test.annotations.fetchprofile">
<fetch-profile name="orders-profile">
<fetch entity="Customer5" association="orders" style="join"/>
</fetch-profile>
</hibernate-mapping>

View File

@ -65,7 +65,7 @@
<dependency>
<groupId>org.jboss.shrinkwrap</groupId>
<artifactId>shrinkwrap-impl-base</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.0-alpha-6</version>
<scope>test</scope>
</dependency>
<dependency>