diff --git a/annotations/src/main/java/org/hibernate/cfg/AccessType.java b/annotations/src/main/java/org/hibernate/cfg/AccessType.java
new file mode 100644
index 0000000000..6b71db3932
--- /dev/null
+++ b/annotations/src/main/java/org/hibernate/cfg/AccessType.java
@@ -0,0 +1,85 @@
+// $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.cfg;
+
+/**
+ * Enum defining deifferent access strategies for accessing entity values.
+ *
+ * @author Hardy Ferentschik
+ */
+public enum AccessType {
+ /**
+ * Default access strategy is property
+ */
+ DEFAULT( "property" ),
+
+ /**
+ * Access to value via property
+ */
+ PROPERTY( "property" ),
+
+ /**
+ * Access to value via field
+ */
+ FIELD( "field" );
+
+ private final String accessType;
+
+ AccessType(String type) {
+ this.accessType = type;
+ }
+
+ public String getType() {
+ return accessType;
+ }
+
+ public static AccessType getAccessStrategy(String type) {
+ if ( type == null ) {
+ return DEFAULT;
+ }
+ else if ( FIELD.getType().equals( type ) ) {
+ return FIELD;
+ }
+ else if ( PROPERTY.getType().equals( type ) ) {
+ return PROPERTY;
+ }
+ else {
+ // TODO historically if the type string could not be matched default access was used. Maybe this should be an exception though!?
+ return DEFAULT;
+ }
+ }
+
+ public static AccessType getAccessStrategy(javax.persistence.AccessType type) {
+ if ( javax.persistence.AccessType.PROPERTY.equals( type ) ) {
+ return PROPERTY;
+ }
+ else if ( javax.persistence.AccessType.FIELD.equals( type ) ) {
+ return FIELD;
+ }
+ else {
+ return DEFAULT;
+ }
+ }
+}
diff --git a/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
index 59294c7024..286c79e126 100644
--- a/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
+++ b/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
@@ -1,3 +1,4 @@
+// $Id:$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
@@ -24,8 +25,8 @@
package org.hibernate.cfg;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
@@ -34,6 +35,7 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
+import javax.persistence.Access;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.DiscriminatorType;
@@ -68,7 +70,6 @@ import javax.persistence.SqlResultSetMapping;
import javax.persistence.SqlResultSetMappings;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
-import javax.persistence.Transient;
import javax.persistence.Version;
import javax.persistence.ElementCollection;
import javax.persistence.CollectionTable;
@@ -83,7 +84,6 @@ import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode;
import org.hibernate.FetchMode;
import org.hibernate.MappingException;
-import org.hibernate.annotations.AccessType;
import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.Cascade;
@@ -116,10 +116,8 @@ import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Parent;
import org.hibernate.annotations.Proxy;
import org.hibernate.annotations.Sort;
-import org.hibernate.annotations.Target;
import org.hibernate.annotations.Tuplizer;
import org.hibernate.annotations.Tuplizers;
-import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;
import org.hibernate.annotations.Where;
@@ -424,6 +422,11 @@ public final class AnnotationBinder {
/**
* Bind a class having JSR175 annotations
* The subclasses have to be binded after its mother class
+ *
+ * @param clazzToProcess entity to bind as {@code XClass} instance
+ * @param inheritanceStatePerClass Meta data about the inheritance relationships for all mapped classes
+ * @param mappings Mapping meta data
+ * @throws MappingException in case there is an configuration error
*/
public static void bindClass(
XClass clazzToProcess, Map inheritanceStatePerClass, ExtendedMappings mappings
@@ -516,12 +519,12 @@ public final class AnnotationBinder {
entityBinder.setWhere( whereAnn );
entityBinder.setCache( cacheAnn );
entityBinder.setInheritanceState( inheritanceState );
-
+
//Filters are not allowed on subclasses
if ( !inheritanceState.hasParents() ) {
bindFilters(clazzToProcess, entityBinder, mappings);
}
-
+
entityBinder.bindEntity();
if ( inheritanceState.hasTable() ) {
@@ -621,7 +624,7 @@ public final class AnnotationBinder {
// check properties
List elements =
getElementsToProcess(
- persistentClass, clazzToProcess, inheritanceStatePerClass, propertyHolder, entityBinder, mappings
+ persistentClass, clazzToProcess, inheritanceStatePerClass, entityBinder, mappings
);
if ( elements == null ) {
throw new AnnotationException( "No identifier specified for entity: " + propertyHolder.getEntityName() );
@@ -650,8 +653,7 @@ public final class AnnotationBinder {
if ( idClass != null ) {
XClass compositeClass = mappings.getReflectionManager().toXClass( idClass.value() );
boolean isComponent = true;
- boolean propertyAnnotated = entityBinder.isPropertyAnnotated( compositeClass );
- String propertyAccessor = entityBinder.getPropertyAccessor( compositeClass );
+ AccessType propertyAccessor = entityBinder.getPropertyAccessor( compositeClass );
String generatorType = "assigned";
String generator = BinderHelper.ANNOTATION_STRING_DEFAULT;
PropertyData inferredData = new PropertyPreloadedData(
@@ -672,7 +674,6 @@ public final class AnnotationBinder {
propertyHolder,
localGenerators,
isComponent,
- propertyAnnotated,
propertyAccessor, entityBinder,
true,
false, mappings, inheritanceStatePerClass
@@ -684,7 +685,6 @@ public final class AnnotationBinder {
propertyHolder,
inferredData,
baseInferredData,
- propertyAnnotated,
propertyAccessor, false,
entityBinder,
true, true,
@@ -875,11 +875,11 @@ public final class AnnotationBinder {
.getName()
);
}
-
+
return true;
}
- /**
+ /*
* Get the annotated elements
* Guess the annotated element from @Id or @EmbeddedId presence
* Change EntityBinder by side effect
@@ -887,9 +887,15 @@ public final class AnnotationBinder {
private static List getElementsToProcess(
PersistentClass persistentClass, XClass clazzToProcess,
Map inheritanceStatePerClass,
- PropertyHolder propertyHolder, EntityBinder entityBinder, ExtendedMappings mappings
+ EntityBinder entityBinder, ExtendedMappings mappings
) {
InheritanceState inheritanceState = inheritanceStatePerClass.get( clazzToProcess );
+ assert !inheritanceState.isEmbeddableSuperclass();
+
+ AccessType accessType = determineExplicitAccessType(
+ clazzToProcess, inheritanceStatePerClass, mappings, inheritanceState
+ );
+
List classesToProcess = getMappedSuperclassesTillNextEntityOrdered(
persistentClass, clazzToProcess, inheritanceStatePerClass, mappings
);
@@ -897,53 +903,14 @@ public final class AnnotationBinder {
int deep = classesToProcess.size();
boolean hasIdentifier = false;
- assert !inheritanceState.isEmbeddableSuperclass();
- Boolean isExplicitPropertyAnnotated = null;
- String explicitAccessType;
- if ( inheritanceState.hasParents() ) {
- InheritanceState superEntityState =
- InheritanceState.getInheritanceStateOfSuperEntity(
- clazzToProcess, inheritanceStatePerClass, mappings.getReflectionManager()
- );
- isExplicitPropertyAnnotated = superEntityState != null ?
- superEntityState.isPropertyAnnotated() :
- null;
- explicitAccessType = superEntityState != null ?
- superEntityState.getAccessType() :
- null;
- }
- else {
- //the are the root entity but we might have mapped superclasses that contain the id class
- AccessType access = clazzToProcess.getAnnotation( AccessType.class );
- explicitAccessType = access != null ?
- access.value() :
- null;
- if ( "property".equals( explicitAccessType ) ) {
- isExplicitPropertyAnnotated = Boolean.TRUE;
- }
- else if ( "field".equals( explicitAccessType ) ) {
- isExplicitPropertyAnnotated = Boolean.FALSE;
- }
- }
- Boolean isPropertyAnnotated = isExplicitPropertyAnnotated == null ?
- Boolean.TRUE :
- //default to property and fallback if needed
- isExplicitPropertyAnnotated;
- String accessType = explicitAccessType != null ?
- explicitAccessType :
- "property";
/*
* delay the exception in case field access is used
*/
AnnotationException exceptionWhileWalkingElements = null;
try {
for (int index = 0; index < deep; index++) {
- XClass clazz = classesToProcess.get( index );
-
- boolean currentHasIdentifier = addElementsOfAClass(
- elements, propertyHolder, isPropertyAnnotated,
- accessType, clazz, mappings
- );
+ PropertyContainer properyContainer = new PropertyContainer( classesToProcess.get( index ) );
+ boolean currentHasIdentifier = addElementsOfClass( elements, accessType , properyContainer, mappings );
hasIdentifier = hasIdentifier || currentHasIdentifier;
}
}
@@ -952,43 +919,85 @@ public final class AnnotationBinder {
}
if ( !hasIdentifier && !inheritanceState.hasParents() ) {
- if ( isExplicitPropertyAnnotated != null ) {
+ if ( AccessType.PROPERTY.equals( accessType ) ) {
//the original exception is legitimate
if ( exceptionWhileWalkingElements != null) throw exceptionWhileWalkingElements;
return null; //explicit but no @Id: the upper layer will raise an exception
}
- isPropertyAnnotated = !isPropertyAnnotated;
- accessType = "field";
+ accessType = AccessType.FIELD;
elements.clear();
for (int index = 0; index < deep; index++) {
- XClass clazz = classesToProcess.get( index );
- boolean currentHasIdentifier = addElementsOfAClass(
- elements, propertyHolder, isPropertyAnnotated,
- accessType, clazz, mappings
- );
+ PropertyContainer properyContainer = new PropertyContainer( classesToProcess.get( index ) );
+ boolean currentHasIdentifier = addElementsOfClass(elements, accessType, properyContainer, mappings );
hasIdentifier = hasIdentifier || currentHasIdentifier;
}
}
- //the field show no id, fallback tot he original exception
+ //the field show no id, fallback to he original exception
if (!hasIdentifier && exceptionWhileWalkingElements != null) throw exceptionWhileWalkingElements;
- //TODO set the access type here?
- entityBinder.setPropertyAnnotated( isPropertyAnnotated );
entityBinder.setPropertyAccessor( accessType );
- inheritanceState.setPropertyAnnotated( isPropertyAnnotated );
inheritanceState.setAccessType( accessType );
return hasIdentifier || inheritanceState.hasParents() ?
elements :
null;
}
+ /*
+ * Check whether either the class itself or any of its super classes explicitly defines a value access strategy.
+ *
+ * @return {@code AccessType.FIELD} or {@code AccessType.PROPERTY} in case there is an explicit value,
+ * {@code AccessType.DEFAULT} otherwise.
+ */
+ private static AccessType determineExplicitAccessType(XClass clazzToProcess, Map inheritanceStatePerClass, ExtendedMappings mappings, InheritanceState inheritanceState) {
+ AccessType explicitAccessType = AccessType.DEFAULT;
+
+ // check whether any of the super classes or the class itself
+ if ( inheritanceState.hasParents() ) {
+ InheritanceState superEntityState =
+ InheritanceState.getInheritanceStateOfSuperEntity(
+ clazzToProcess, inheritanceStatePerClass, mappings.getReflectionManager()
+ );
+ if ( superEntityState != null ) {
+ explicitAccessType = superEntityState.getAccessType();
+ }
+ }
+ else {
+ AccessType hibernateExplicitAccessType = AccessType.DEFAULT;
+ AccessType jpaExplicitAccessType = AccessType.DEFAULT;
+
+ //the are the root entity but we might have mapped superclasses that contain the id class
+ org.hibernate.annotations.AccessType accessType = clazzToProcess.getAnnotation( org.hibernate.annotations.AccessType.class );
+ if ( accessType != null ) {
+ hibernateExplicitAccessType = AccessType.getAccessStrategy( accessType.value() );
+ }
+
+ Access access = clazzToProcess.getAnnotation( Access.class );
+ if( access != null ) {
+ jpaExplicitAccessType = AccessType.getAccessStrategy( access.value() );
+ }
+
+ if ( hibernateExplicitAccessType != AccessType.DEFAULT
+ && jpaExplicitAccessType != AccessType.DEFAULT
+ && hibernateExplicitAccessType != jpaExplicitAccessType ) {
+ throw new MappingException( "@AccessType and @Access specified with contradicting values. Use of @Access only is recommended. " );
+ }
+
+ if(hibernateExplicitAccessType != AccessType.DEFAULT) {
+ explicitAccessType = hibernateExplicitAccessType;
+ } else {
+ explicitAccessType = jpaExplicitAccessType;
+ }
+ }
+ return explicitAccessType;
+ }
+
private static List getMappedSuperclassesTillNextEntityOrdered(
PersistentClass persistentClass, XClass annotatedClass,
Map inheritanceStatePerClass,
ExtendedMappings mappings
) {
-
+
//ordered to allow proper messages on properties subclassing
List classesToProcess = new ArrayList();
XClass currentClassInHierarchy = annotatedClass;
@@ -1034,17 +1043,17 @@ public final class AnnotationBinder {
}
return classesToProcess;
}
-
- /**
- * Process the filters defined on the given class, as well as all filters defined
- * on the MappedSuperclass(s) in the inheritance hierarchy
+
+ /*
+ * Process the filters defined on the given class, as well as all filters defined
+ * on the MappedSuperclass(s) in the inheritance hierarchy
*/
- private static void bindFilters(XClass annotatedClass, EntityBinder entityBinder,
+ private static void bindFilters(XClass annotatedClass, EntityBinder entityBinder,
ExtendedMappings mappings) {
-
+
bindFilters(annotatedClass, entityBinder);
-
- XClass classToProcess = annotatedClass.getSuperclass();
+
+ XClass classToProcess = annotatedClass.getSuperclass();
while (classToProcess != null) {
AnnotatedClassType classType = mappings.getClassType( classToProcess );
if ( AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals( classType ) ) {
@@ -1052,24 +1061,24 @@ public final class AnnotationBinder {
}
classToProcess = classToProcess.getSuperclass();
}
-
+
}
-
+
private static void bindFilters(XAnnotatedElement annotatedElement, EntityBinder entityBinder) {
-
+
Filters filtersAnn = annotatedElement.getAnnotation( Filters.class );
if ( filtersAnn != null ) {
for (Filter filter : filtersAnn.value()) {
entityBinder.addFilter( filter.name(), filter.condition() );
}
}
-
+
Filter filterAnn = annotatedElement.getAnnotation( Filter.class );
if ( filterAnn != null ) {
entityBinder.addFilter( filterAnn.name(), filterAnn.condition() );
}
}
-
+
private static void bindFilterDefs(XAnnotatedElement annotatedElement, ExtendedMappings mappings) {
FilterDef defAnn = annotatedElement.getAnnotation( FilterDef.class );
FilterDefs defsAnn = annotatedElement.getAnnotation( FilterDefs.class );
@@ -1111,13 +1120,13 @@ public final class AnnotationBinder {
for (Parameter param : defAnn.parameters()) {
params.setProperty( param.name(), param.value() );
}
-
+
if (BinderHelper.isDefault(defAnn.name()) && defAnn.defaultForType().equals(void.class)) {
throw new AnnotationException(
- "Either name or defaultForType (or both) attribute should be set in TypeDef having typeClass " +
+ "Either name or defaultForType (or both) attribute should be set in TypeDef having typeClass " +
defAnn.typeClass().getName());
}
-
+
if (!BinderHelper.isDefault(defAnn.name())) {
log.info( "Binding type definition: {}", defAnn.name() );
mappings.addTypeDef( defAnn.name(), defAnn.typeClass().getName(), params );
@@ -1126,10 +1135,10 @@ public final class AnnotationBinder {
log.info( "Binding type definition: {}", defAnn.defaultForType().getName() );
mappings.addTypeDef( defAnn.defaultForType().getName(), defAnn.typeClass().getName(), params );
}
-
+
}
-
-
+
+
private static void bindDiscriminatorToPersistentClass(
RootClass rootClass,
Ejb3DiscriminatorColumn discriminatorColumn, Map secondaryTables,
@@ -1151,95 +1160,35 @@ public final class AnnotationBinder {
}
/**
- * Add elements of a class
+ *
+ * @param elements List of {@code ProperyData} instances
+ * @param propertyAccessor The default value access strategy which has to be used in case no explicit local access
+ * strategy is used
+ * @param propertyContainer Metadata about a class and its properties
+ * @param mappings Mapping meta data
+ * @return {@code true} in case an id property was found while iterating the elements of {@code annoatedClass} using
+ * the determined access strategy, {@code false} otherwise.
*/
- private static boolean addElementsOfAClass(
- List elements, PropertyHolder propertyHolder, boolean isPropertyAnnotated,
- String propertyAccessor, final XClass annotatedClass, ExtendedMappings mappings
+ private static boolean addElementsOfClass(
+ List elements, AccessType propertyAccessor, PropertyContainer propertyContainer, ExtendedMappings mappings
) {
boolean hasIdentifier = false;
- AccessType access = annotatedClass.getAnnotation( AccessType.class );
- String localPropertyAccessor = access != null ?
- access.value() :
- null;
- String accessType;
- if ( "property".equals( localPropertyAccessor ) || "field".equals( localPropertyAccessor ) ) {
- accessType = localPropertyAccessor;
- }
- else {
- if ( localPropertyAccessor == null ) {
- localPropertyAccessor = propertyAccessor;
- }
+ AccessType classDefinedAccessType = propertyContainer.getDefaultAccessStrategy();
- if ( isPropertyAnnotated ) {
- accessType = "property";
- }
- else {
- accessType = "field";
- }
+ if ( classDefinedAccessType.equals( AccessType.DEFAULT ) ) {
+ classDefinedAccessType = propertyAccessor;
}
- log.debug( "Processing {} {} annotation", propertyHolder.getEntityName(), accessType );
- List properties = annotatedClass.getDeclaredProperties( accessType );
- //order so that property are used in the same order when binding native query
- Collections.sort( properties, new Comparator() {
- public int compare(XProperty property1, XProperty property2) {
- return property1.getName().compareTo( property2.getName() );
- }
- } );
- for (XProperty p : properties) {
- if ( !p.isTypeResolved() && !discoverTypeWithoutReflection( p ) && !mustBeSkipped( p, mappings ) ) {
- throw new AnnotationException(
- "Property " + StringHelper.qualify( propertyHolder.getEntityName(), p.getName() ) +
- " has an unbound type and no explicit target entity. Resolve this Generic usage issue" +
- " or set an explicit target attribute (eg @OneToMany(target=) or use an explicit @Type"
- );
- }
- final boolean currentHasIdentifier = addProperty( annotatedClass, p, elements, localPropertyAccessor, mappings );
+ Collection properties = propertyContainer.getProperties( classDefinedAccessType );
+ for ( XProperty p : properties ) {
+ final boolean currentHasIdentifier = addProperty(
+ propertyContainer.getXClass(), p, elements, classDefinedAccessType.getType(), mappings
+ );
hasIdentifier = hasIdentifier || currentHasIdentifier;
}
return hasIdentifier;
}
- private static boolean discoverTypeWithoutReflection(XProperty p) {
- if ( p.isAnnotationPresent( OneToOne.class ) && !p.getAnnotation( OneToOne.class )
- .targetEntity()
- .equals( void.class ) ) {
- return true;
- }
- else if ( p.isAnnotationPresent( OneToMany.class ) && !p.getAnnotation( OneToMany.class )
- .targetEntity()
- .equals( void.class ) ) {
- return true;
- }
- else if ( p.isAnnotationPresent( ManyToOne.class ) && !p.getAnnotation( ManyToOne.class )
- .targetEntity()
- .equals( void.class ) ) {
- return true;
- }
- else if ( p.isAnnotationPresent( ManyToMany.class ) && !p.getAnnotation( ManyToMany.class )
- .targetEntity()
- .equals( void.class ) ) {
- return true;
- }
- else if ( p.isAnnotationPresent( org.hibernate.annotations.Any.class ) ) {
- return true;
- }
- else if ( p.isAnnotationPresent( ManyToAny.class ) ) {
- if ( !p.isCollection() && !p.isArray() ) {
- throw new AnnotationException( "@ManyToAny used on a non collection non array property: " + p.getName() );
- }
- return true;
- }
- else if ( p.isAnnotationPresent( Type.class ) ) {
- return true;
- }
- else if ( p.isAnnotationPresent( Target.class ) ) {
- return true;
- }
- return false;
- }
-
private static boolean addProperty(
XClass declaringClass, XProperty property, List annElts,
String propertyAccessor, ExtendedMappings mappings
@@ -1248,32 +1197,25 @@ public final class AnnotationBinder {
PropertyData propertyAnnotatedElement = new PropertyInferredData(
declaringClass, property, propertyAccessor,
mappings.getReflectionManager() );
- if ( !mustBeSkipped( propertyAnnotatedElement.getProperty(), mappings ) ) {
- /*
- * put element annotated by @Id in front
- * since it has to be parsed before any association by Hibernate
- */
- final XAnnotatedElement element = propertyAnnotatedElement.getProperty();
- if ( element.isAnnotationPresent( Id.class ) || element.isAnnotationPresent( EmbeddedId.class ) ) {
- annElts.add( 0, propertyAnnotatedElement );
- hasIdentifier = true;
- }
- else {
- annElts.add( propertyAnnotatedElement );
- hasIdentifier = false;
- }
+
+ /*
+ * put element annotated by @Id in front
+ * since it has to be parsed before any association by Hibernate
+ */
+ final XAnnotatedElement element = propertyAnnotatedElement.getProperty();
+ if ( element.isAnnotationPresent( Id.class ) || element.isAnnotationPresent( EmbeddedId.class ) ) {
+ annElts.add( 0, propertyAnnotatedElement );
+ hasIdentifier = true;
}
+ else {
+ annElts.add( propertyAnnotatedElement );
+ hasIdentifier = false;
+ }
+
return hasIdentifier;
}
- private static boolean mustBeSkipped(XProperty property, ExtendedMappings mappings) {
- //TODO make those hardcoded tests more portable (through the bytecode provider?)
- return property.isAnnotationPresent( Transient.class )
- || "net.sf.cglib.transform.impl.InterceptFieldCallback".equals( property.getType().getName() )
- || "org.hibernate.bytecode.javassist.FieldHandler".equals( property.getType().getName() );
- }
-
- /**
+ /*
* Process annotation of a particular property
*/
private static void processElementAnnotations(
@@ -1434,9 +1376,7 @@ public final class AnnotationBinder {
//guess if its a component and find id data access (property, field etc)
final boolean isComponent = returnedClass.isAnnotationPresent( Embeddable.class )
|| property.isAnnotationPresent( EmbeddedId.class );
- boolean propertyAnnotated = entityBinder.isPropertyAnnotated( returnedClass );
- String propertyAccessor = entityBinder.getPropertyAccessor( returnedClass );
- //if ( isComponent && embeddableAnn != null && embeddableAnn.access() == AccessType.FIELD ) propertyAccess = false;
+ AccessType propertyAccessor = entityBinder.getPropertyAccessor( returnedClass );
GeneratedValue generatedValue = property.getAnnotation( GeneratedValue.class );
String generatorType = generatedValue != null ?
@@ -1446,7 +1386,7 @@ public final class AnnotationBinder {
generatedValue.generator() :
BinderHelper.ANNOTATION_STRING_DEFAULT;
if ( isComponent ) generatorType = "assigned"; //a component must not have any generator
-
+
bindId(
generatorType,
generator,
@@ -1455,14 +1395,13 @@ public final class AnnotationBinder {
propertyHolder,
localGenerators,
isComponent,
- propertyAnnotated,
propertyAccessor, entityBinder,
false,
isIdentifierMapper,
mappings,
inheritanceStatePerClass
);
-
+
log.debug(
"Bind {} on {}", ( isComponent ? "@EmbeddedId" : "@Id" ), inferredData.getPropertyName()
);
@@ -1491,7 +1430,7 @@ public final class AnnotationBinder {
propBinder.setName( inferredData.getPropertyName() );
propBinder.setReturnedClassName( inferredData.getTypeName() );
propBinder.setLazy( false );
- propBinder.setPropertyAccessorName( inferredData.getDefaultAccess() );
+ propBinder.setAccessType( inferredData.getDefaultAccess() );
propBinder.setColumns( columns );
propBinder.setHolder( propertyHolder ); //PropertyHolderBuilder.buildPropertyHolder(rootClass)
propBinder.setProperty( property );
@@ -1515,7 +1454,7 @@ public final class AnnotationBinder {
//we know the property is on the actual entity
rootClass.setDeclaredVersion( prop );
}
-
+
SimpleValue simpleValue = (SimpleValue) prop.getValue();
simpleValue.setNullValue( "undefined" );
rootClass.setOptimisticLockMode( Versioning.OPTIMISTIC_LOCK_VERSION );
@@ -1630,7 +1569,7 @@ public final class AnnotationBinder {
if ( property.isAnnotationPresent( OrderColumn.class ) ) {
indexColumn = IndexColumn.buildColumnFromAnnotation(
- property.getAnnotation(OrderColumn.class),
+ property.getAnnotation(OrderColumn.class),
propertyHolder,
inferredData,
entityBinder.getSecondaryTables(),
@@ -1673,7 +1612,7 @@ public final class AnnotationBinder {
collectionBinder.setIgnoreNotFound( ignoreNotFound );
collectionBinder.setCollectionType( inferredData.getProperty().getElementClass() );
collectionBinder.setMappings( mappings );
- collectionBinder.setPropertyAccessorName( inferredData.getDefaultAccess() );
+ collectionBinder.setAccessType( inferredData.getDefaultAccess() );
Ejb3Column[] elementColumns;
PropertyData virtualProperty = new WrappedInferredData( inferredData, "element" );
@@ -1732,7 +1671,7 @@ public final class AnnotationBinder {
//nullify empty array
keyColumns = keyColumns != null && keyColumns.length > 0 ? keyColumns : null;
-
+
PropertyData mapKeyVirtualProperty = new WrappedInferredData( inferredData, "mapkey" );
Ejb3Column[] mapColumns = Ejb3Column.buildColumnFromAnnotation(
keyColumns,
@@ -1887,13 +1826,9 @@ public final class AnnotationBinder {
isComponent = embeddedAnn != null || embeddableAnn != null;
if ( isComponent ) {
- //process component object
- //boolean propertyAccess = true;
- //if ( embeddableAnn != null && embeddableAnn.access() == AccessType.FIELD ) propertyAccess = false;
- boolean propertyAnnotated = entityBinder.isPropertyAnnotated( property );
- String propertyAccessor = entityBinder.getPropertyAccessor( property );
+ AccessType propertyAccessor = entityBinder.getPropertyAccessor( property );
bindComponent(
- inferredData, propertyHolder, propertyAnnotated, propertyAccessor, entityBinder,
+ inferredData, propertyHolder, propertyAccessor, entityBinder,
isIdentifierMapper,
mappings, isComponentEmbedded, inheritanceStatePerClass
);
@@ -1919,7 +1854,7 @@ public final class AnnotationBinder {
propBinder.setName( inferredData.getPropertyName() );
propBinder.setReturnedClassName( inferredData.getTypeName() );
propBinder.setLazy( lazy );
- propBinder.setPropertyAccessorName( inferredData.getDefaultAccess() );
+ propBinder.setAccessType( inferredData.getDefaultAccess() );
propBinder.setColumns( columns );
propBinder.setHolder( propertyHolder );
propBinder.setProperty( property );
@@ -1938,7 +1873,7 @@ public final class AnnotationBinder {
Index index = property.getAnnotation( Index.class );
if ( index != null ) {
if ( joinColumns != null ) {
-
+
for (Ejb3Column column : joinColumns) {
column.addIndex( index, inSecondPass );
}
@@ -2038,14 +1973,13 @@ public final class AnnotationBinder {
private static void bindComponent(
PropertyData inferredData,
PropertyHolder propertyHolder,
- boolean propertyAnnotated,
- String propertyAccessor, EntityBinder entityBinder,
+ AccessType propertyAccessor, EntityBinder entityBinder,
boolean isIdentifierMapper,
ExtendedMappings mappings, boolean isComponentEmbedded,
Map inheritanceStatePerClass
) {
Component comp = fillComponent(
- propertyHolder, inferredData, propertyAnnotated, propertyAccessor, true, entityBinder,
+ propertyHolder, inferredData, propertyAccessor, true, entityBinder,
isComponentEmbedded, isIdentifierMapper,
false, mappings, inheritanceStatePerClass
);
@@ -2056,32 +1990,31 @@ public final class AnnotationBinder {
binder.setName( inferredData.getPropertyName() );
binder.setValue( comp );
binder.setProperty( inferredData.getProperty() );
- binder.setPropertyAccessorName( inferredData.getDefaultAccess() );
+ binder.setAccessType( inferredData.getDefaultAccess() );
Property prop = binder.make();
propertyHolder.addProperty( prop, inferredData.getDeclaringClass() );
}
public static Component fillComponent(
PropertyHolder propertyHolder, PropertyData inferredData,
- boolean propertyAnnotated, String propertyAccessor, boolean isNullable,
+ AccessType propertyAccessor, boolean isNullable,
EntityBinder entityBinder,
boolean isComponentEmbedded, boolean isIdentifierMapper, boolean inSecondPass,
ExtendedMappings mappings, Map inheritanceStatePerClass
) {
-
- return fillComponent(propertyHolder, inferredData, null, propertyAnnotated, propertyAccessor,
+
+ return fillComponent(propertyHolder, inferredData, null, propertyAccessor,
isNullable, entityBinder, isComponentEmbedded, isIdentifierMapper, inSecondPass, mappings,
inheritanceStatePerClass);
}
-
+
public static Component fillComponent(
PropertyHolder propertyHolder, PropertyData inferredData, PropertyData baseInferredData,
- boolean propertyAnnotated, String propertyAccessor, boolean isNullable,
- EntityBinder entityBinder,
+ AccessType propertyAccessor, boolean isNullable, EntityBinder entityBinder,
boolean isComponentEmbedded, boolean isIdentifierMapper, boolean inSecondPass, ExtendedMappings mappings,
Map inheritanceStatePerClass
) {
-
+
/**
* inSecondPass can only be used to apply right away the second pass of a composite-element
* Because it's a value type, there is no bidirectional association, hence second pass
@@ -2104,48 +2037,33 @@ public final class AnnotationBinder {
comp, subpath,
inferredData, propertyHolder, mappings
);
-
+
List classElements = new ArrayList();
XClass returnedClassOrElement = inferredData.getClassOrElement();
-
+
List baseClassElements = null;
XClass baseReturnedClassOrElement;
PropertyHolder baseSubHolder;
if(baseInferredData != null)
{
- baseSubHolder = PropertyHolderBuilder.buildPropertyHolder(
- comp, subpath,
- inferredData, propertyHolder, mappings
- );
baseClassElements = new ArrayList();
baseReturnedClassOrElement = baseInferredData.getClassOrElement();
bindTypeDefs(baseReturnedClassOrElement, mappings);
- addElementsOfAClass(
- baseClassElements,
- baseSubHolder,
- propertyAnnotated,
- propertyAccessor, baseReturnedClassOrElement, mappings
- );
+ PropertyContainer propContainer = new PropertyContainer( baseReturnedClassOrElement );
+ addElementsOfClass( baseClassElements, propertyAccessor, propContainer, mappings );
}
//embeddable elements can have type defs
bindTypeDefs(returnedClassOrElement, mappings);
- addElementsOfAClass(
- classElements,
- subHolder,
- propertyAnnotated,
- propertyAccessor, returnedClassOrElement, mappings
- );
+ PropertyContainer propContainer = new PropertyContainer( returnedClassOrElement );
+ addElementsOfClass( classElements, propertyAccessor, propContainer, mappings);
+
//add elements of the embeddable superclass
XClass superClass = inferredData.getPropertyClass().getSuperclass();
while ( superClass != null && superClass.isAnnotationPresent( MappedSuperclass.class ) ) {
//FIXME: proper support of typevariables incl var resolved at upper levels
- addElementsOfAClass(
- classElements,
- subHolder,
- entityBinder.isPropertyAnnotated( superClass ),
- propertyAccessor, superClass, mappings
- );
+ propContainer = new PropertyContainer( superClass );
+ addElementsOfClass( classElements, propertyAccessor, propContainer, mappings );
superClass = superClass.getSuperclass();
}
if ( baseClassElements != null ) {
@@ -2173,28 +2091,26 @@ public final class AnnotationBinder {
PropertyData inferredData, Ejb3Column[] columns, PropertyHolder propertyHolder,
Map localGenerators,
boolean isComposite,
- boolean isPropertyAnnotated,
- String propertyAccessor, EntityBinder entityBinder, boolean isEmbedded,
+ AccessType propertyAccessor, EntityBinder entityBinder, boolean isEmbedded,
boolean isIdentifierMapper, ExtendedMappings mappings,
Map inheritanceStatePerClass
) {
-
+
bindId(generatorType, generatorName, inferredData, null, columns, propertyHolder,
- localGenerators, isComposite, isPropertyAnnotated, propertyAccessor, entityBinder,
+ localGenerators, isComposite, propertyAccessor, entityBinder,
isEmbedded, isIdentifierMapper, mappings, inheritanceStatePerClass);
}
-
+
private static void bindId(
String generatorType, String generatorName, PropertyData inferredData,
PropertyData baseInferredData, Ejb3Column[] columns, PropertyHolder propertyHolder,
Map localGenerators,
boolean isComposite,
- boolean isPropertyAnnotated,
- String propertyAccessor, EntityBinder entityBinder, boolean isEmbedded,
+ AccessType propertyAccessor, EntityBinder entityBinder, boolean isEmbedded,
boolean isIdentifierMapper, ExtendedMappings mappings,
Map inheritanceStatePerClass
) {
-
+
/*
* Fill simple value and property since and Id is a property
*/
@@ -2210,7 +2126,7 @@ public final class AnnotationBinder {
SimpleValue id;
if ( isComposite ) {
id = fillComponent(
- propertyHolder, inferredData, baseInferredData, isPropertyAnnotated, propertyAccessor,
+ propertyHolder, inferredData, baseInferredData, propertyAccessor,
false, entityBinder, isEmbedded, isIdentifierMapper, false, mappings, inheritanceStatePerClass
);
Component componentId = (Component) id;
@@ -2247,7 +2163,7 @@ public final class AnnotationBinder {
PropertyBinder binder = new PropertyBinder();
binder.setName( inferredData.getPropertyName() );
binder.setValue( id );
- binder.setPropertyAccessorName( inferredData.getDefaultAccess() );
+ binder.setAccessType( inferredData.getDefaultAccess() );
binder.setProperty( inferredData.getProperty() );
Property prop = binder.make();
rootClass.setIdentifierProperty( prop );
@@ -2345,7 +2261,7 @@ public final class AnnotationBinder {
binder.setInsertable( columns[0].isInsertable() );
binder.setUpdatable( columns[0].isUpdatable() );
}
- binder.setPropertyAccessorName( inferredData.getDefaultAccess() );
+ binder.setAccessType( inferredData.getDefaultAccess() );
binder.setCascade( cascadeStrategy );
binder.setProperty(inferredData.getProperty());
Property prop = binder.make();
@@ -2496,7 +2412,7 @@ public final class AnnotationBinder {
binder.setInsertable( columns[0].isInsertable() );
binder.setUpdatable( columns[0].isUpdatable() );
}
- binder.setPropertyAccessorName( inferredData.getDefaultAccess() );
+ binder.setAccessType( inferredData.getDefaultAccess() );
binder.setCascade( cascadeStrategy );
Property prop = binder.make();
//composite FK columns are in the same table so its OK
@@ -2556,15 +2472,12 @@ public final class AnnotationBinder {
hibernateCascadeAnnotation.value();
if ( hibernateCascades != null && hibernateCascades.length > 0 ) {
- for (CascadeType cascadeType : hibernateCascades) {
- hibernateCascadeSet.add( cascadeType );
- }
+ hibernateCascadeSet.addAll( Arrays.asList( hibernateCascades ) );
}
StringBuilder cascade = new StringBuilder();
- Iterator cascadeType = hibernateCascadeSet.iterator();
- while ( cascadeType.hasNext() ) {
- switch ( cascadeType.next() ) {
+ for ( CascadeType aHibernateCascadeSet : hibernateCascadeSet ) {
+ switch ( aHibernateCascadeSet ) {
case ALL:
cascade.append( "," ).append( "all" );
break;
diff --git a/annotations/src/main/java/org/hibernate/cfg/InheritanceState.java b/annotations/src/main/java/org/hibernate/cfg/InheritanceState.java
index 65cbfd03f4..658c236ed7 100644
--- a/annotations/src/main/java/org/hibernate/cfg/InheritanceState.java
+++ b/annotations/src/main/java/org/hibernate/cfg/InheritanceState.java
@@ -60,8 +60,7 @@ public class InheritanceState {
/**
* only defined on embedded superclasses
*/
- private String accessType = null;
- private Boolean isPropertyAnnotated;
+ private AccessType accessType = AccessType.DEFAULT;
private void extractInheritanceType() {
XAnnotatedElement element = getClazz();
@@ -108,7 +107,9 @@ public class InheritanceState {
do {
superclass = superclass.getSuperclass();
InheritanceState currentState = states.get( superclass );
- if ( currentState != null ) return currentState;
+ if ( currentState != null ) {
+ return currentState;
+ }
}
while ( superclass != null && !reflectionManager.equals( superclass, Object.class ) );
return null;
@@ -154,19 +155,11 @@ public class InheritanceState {
isEmbeddableSuperclass = embeddableSuperclass;
}
- public String getAccessType() {
+ public AccessType getAccessType() {
return accessType;
}
- public void setAccessType(String accessType) {
- this.accessType = accessType;
- }
-
- public Boolean isPropertyAnnotated() {
- return isPropertyAnnotated;
- }
-
- public void setPropertyAnnotated(Boolean propertyAnnotated) {
- isPropertyAnnotated = propertyAnnotated;
+ public void setAccessType(AccessType type) {
+ this.accessType = type;
}
}
diff --git a/annotations/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java b/annotations/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
index fab43d0245..032e282e2f 100644
--- a/annotations/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
+++ b/annotations/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
@@ -111,7 +111,7 @@ public class OneToOneSecondPass implements SecondPass {
binder.setName( propertyName );
binder.setValue( value );
binder.setCascade( cascadeStrategy );
- binder.setPropertyAccessorName( inferredData.getDefaultAccess() );
+ binder.setAccessType( inferredData.getDefaultAccess() );
Property prop = binder.make();
if ( BinderHelper.isDefault( mappedBy ) ) {
/*
diff --git a/annotations/src/main/java/org/hibernate/cfg/PropertyContainer.java b/annotations/src/main/java/org/hibernate/cfg/PropertyContainer.java
new file mode 100644
index 0000000000..32a7d0aefb
--- /dev/null
+++ b/annotations/src/main/java/org/hibernate/cfg/PropertyContainer.java
@@ -0,0 +1,233 @@
+// $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.cfg;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.TreeMap;
+import javax.persistence.Access;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Transient;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.MappingException;
+import org.hibernate.annotations.ManyToAny;
+import org.hibernate.annotations.Target;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+
+/**
+ * @author Hardy Ferentschik
+ */
+
+/**
+ * A temporary class where we keep the {@code XProperty}s of a class ordered by access type.
+ */
+class PropertyContainer {
+
+ private static final Logger log = LoggerFactory.getLogger( AnnotationBinder.class );
+ private final TreeMap fieldAccessMap;
+ private final TreeMap propertyAccessMap;
+ private final XClass xClass;
+ private final AccessType defaultAccessType;
+
+ PropertyContainer(XClass clazz) {
+ this.xClass = clazz;
+ fieldAccessMap = initProperties( AccessType.FIELD );
+ propertyAccessMap = initProperties( AccessType.PROPERTY );
+ defaultAccessType = determineClassDefinedAccessStrategy();
+ checkForJpaAccess();
+
+
+ }
+
+ public XClass getXClass() {
+ return xClass;
+ }
+
+ public AccessType getDefaultAccessStrategy() {
+ return defaultAccessType;
+ }
+
+ public Collection getProperties(AccessType accessType) {
+ if ( AccessType.DEFAULT == accessType || AccessType.PROPERTY == accessType ) {
+ return propertyAccessMap.values();
+ }
+ else {
+ return fieldAccessMap.values();
+ }
+ }
+
+ private void checkForJpaAccess() {
+ List tmpList = new ArrayList();
+ for ( XProperty property : fieldAccessMap.values() ) {
+ Access access = property.getAnnotation( Access.class );
+ if ( access == null ) {
+ continue;
+ }
+
+ AccessType accessType = AccessType.getAccessStrategy( access.value() );
+ if ( accessType == AccessType.PROPERTY ) {
+ log.warn( "Placing @Access(AccessType.PROPERTY) on a field does not have any effect." );
+ continue;
+ }
+
+ tmpList.add( property );
+ }
+ for ( XProperty property : tmpList ) {
+ fieldAccessMap.remove( property.getName() );
+ propertyAccessMap.put( property.getName(), property );
+ }
+
+
+ tmpList.clear();
+ for ( XProperty property : propertyAccessMap.values() ) {
+ Access access = property.getAnnotation( Access.class );
+ if ( access == null ) {
+ continue;
+ }
+
+ AccessType accessType = AccessType.getAccessStrategy( access.value() );
+ if ( accessType == AccessType.FIELD ) {
+ log.warn( "Placing @Access(AccessType.FIELD) on a field does not have any effect." );
+ continue;
+ }
+
+ tmpList.add( property );
+ }
+ for ( XProperty property : tmpList ) {
+ propertyAccessMap.remove( property.getName() );
+ fieldAccessMap.put( property.getName(), property );
+ }
+ }
+
+ private TreeMap initProperties(AccessType access) {
+ //order so that property are used in the same order when binding native query
+ TreeMap propertiesMap = new TreeMap();
+ List properties = xClass.getDeclaredProperties( access.getType() );
+ for ( XProperty property : properties ) {
+// if ( !property.isTypeResolved() && !discoverTypeWithoutReflection( property )
+// && !mustBeSkipped( property ) ) {
+// String msg = "Property " + StringHelper.qualify( xClass.getName(), property.getName() ) +
+// " has an unbound type and no explicit target entity. Resolve this Generic usage issue" +
+// " or set an explicit target attribute (eg @OneToMany(target=) or use an explicit @Type";
+// throw new AnnotationException( msg );
+// }
+ if ( !mustBeSkipped( property ) ) {
+ propertiesMap.put( property.getName(), property );
+ }
+ }
+ return propertiesMap;
+ }
+
+ private AccessType determineClassDefinedAccessStrategy() {
+ AccessType classDefinedAccessType;
+
+ AccessType hibernateDefinedAccessType = AccessType.DEFAULT;
+ AccessType jpaDefinedAccessType = AccessType.DEFAULT;
+
+ org.hibernate.annotations.AccessType accessType = xClass.getAnnotation( org.hibernate.annotations.AccessType.class );
+ if ( accessType != null ) {
+ hibernateDefinedAccessType = AccessType.getAccessStrategy( accessType.value() );
+ }
+
+ Access access = xClass.getAnnotation( Access.class );
+ if ( access != null ) {
+ jpaDefinedAccessType = AccessType.getAccessStrategy( access.value() );
+ }
+
+ if ( hibernateDefinedAccessType != AccessType.DEFAULT
+ && jpaDefinedAccessType != AccessType.DEFAULT
+ && hibernateDefinedAccessType != jpaDefinedAccessType ) {
+ throw new MappingException(
+ "@AccessType and @Access specified with contradicting values. Use of @Access only is recommended. "
+ );
+ }
+
+ if ( hibernateDefinedAccessType != AccessType.DEFAULT ) {
+ classDefinedAccessType = hibernateDefinedAccessType;
+ }
+ else {
+ classDefinedAccessType = jpaDefinedAccessType;
+ }
+ return classDefinedAccessType;
+ }
+
+ private static boolean discoverTypeWithoutReflection(XProperty p) {
+ if ( p.isAnnotationPresent( OneToOne.class ) && !p.getAnnotation( OneToOne.class )
+ .targetEntity()
+ .equals( void.class ) ) {
+ return true;
+ }
+ else if ( p.isAnnotationPresent( OneToMany.class ) && !p.getAnnotation( OneToMany.class )
+ .targetEntity()
+ .equals( void.class ) ) {
+ return true;
+ }
+ else if ( p.isAnnotationPresent( ManyToOne.class ) && !p.getAnnotation( ManyToOne.class )
+ .targetEntity()
+ .equals( void.class ) ) {
+ return true;
+ }
+ else if ( p.isAnnotationPresent( ManyToMany.class ) && !p.getAnnotation( ManyToMany.class )
+ .targetEntity()
+ .equals( void.class ) ) {
+ return true;
+ }
+ else if ( p.isAnnotationPresent( org.hibernate.annotations.Any.class ) ) {
+ return true;
+ }
+ else if ( p.isAnnotationPresent( ManyToAny.class ) ) {
+ if ( !p.isCollection() && !p.isArray() ) {
+ throw new AnnotationException( "@ManyToAny used on a non collection non array property: " + p.getName() );
+ }
+ return true;
+ }
+ else if ( p.isAnnotationPresent( Type.class ) ) {
+ return true;
+ }
+ else if ( p.isAnnotationPresent( Target.class ) ) {
+ return true;
+ }
+ return false;
+ }
+
+ private static boolean mustBeSkipped(XProperty property) {
+ //TODO make those hardcoded tests more portable (through the bytecode provider?)
+ return property.isAnnotationPresent( Transient.class )
+ || "net.sf.cglib.transform.impl.InterceptFieldCallback".equals( property.getType().getName() )
+ || "org.hibernate.bytecode.javassist.FieldHandler".equals( property.getType().getName() );
+ }
+}
+
+
diff --git a/annotations/src/main/java/org/hibernate/cfg/PropertyData.java b/annotations/src/main/java/org/hibernate/cfg/PropertyData.java
index b4a628c6d2..2dde2ca5e0 100644
--- a/annotations/src/main/java/org/hibernate/cfg/PropertyData.java
+++ b/annotations/src/main/java/org/hibernate/cfg/PropertyData.java
@@ -33,7 +33,7 @@ public interface PropertyData {
* @return default member access (whether field or property)
* @throws MappingException No getter or field found or wrong JavaBean spec usage
*/
- String getDefaultAccess();
+ AccessType getDefaultAccess();
/**
* @return property name
diff --git a/annotations/src/main/java/org/hibernate/cfg/PropertyInferredData.java b/annotations/src/main/java/org/hibernate/cfg/PropertyInferredData.java
index b9e2132f42..d1bb6a59fa 100644
--- a/annotations/src/main/java/org/hibernate/cfg/PropertyInferredData.java
+++ b/annotations/src/main/java/org/hibernate/cfg/PropertyInferredData.java
@@ -23,8 +23,9 @@
*/
package org.hibernate.cfg;
+import javax.persistence.Access;
+
import org.hibernate.MappingException;
-import org.hibernate.annotations.AccessType;
import org.hibernate.annotations.Target;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass;
@@ -37,7 +38,7 @@ import org.hibernate.annotations.common.reflection.XProperty;
* @author Paolo Perrotta
*/
public class PropertyInferredData implements PropertyData {
- private final String defaultAccess;
+ private final AccessType defaultAccess;
private final XProperty property;
private final ReflectionManager reflectionManager;
@@ -50,15 +51,45 @@ public class PropertyInferredData implements PropertyData {
public PropertyInferredData(XClass declaringClass, XProperty property, String propertyAccessor, ReflectionManager reflectionManager) {
this.declaringClass = declaringClass;
this.property = property;
- this.defaultAccess = propertyAccessor;
+ this.defaultAccess = AccessType.getAccessStrategy( propertyAccessor );
this.reflectionManager = reflectionManager;
}
- public String getDefaultAccess() throws MappingException {
- // if(skip())
- // return defaultAccess;
- AccessType access = property.getAnnotation( AccessType.class );
- return access != null ? access.value() : defaultAccess;
+ public AccessType getDefaultAccess() throws MappingException {
+ AccessType accessType = defaultAccess;
+
+ AccessType hibernateAccessType = AccessType.DEFAULT;
+ AccessType jpaAccessType = AccessType.DEFAULT;
+
+ org.hibernate.annotations.AccessType accessTypeAnnotation = property.getAnnotation( org.hibernate.annotations.AccessType.class );
+ if ( accessTypeAnnotation != null ) {
+ hibernateAccessType = AccessType.getAccessStrategy( accessTypeAnnotation.value() );
+ }
+
+ Access access = property.getAnnotation( Access.class );
+ if ( access != null ) {
+ jpaAccessType = AccessType.getAccessStrategy( access.value() );
+ }
+
+ if ( hibernateAccessType != AccessType.DEFAULT
+ && jpaAccessType != AccessType.DEFAULT
+ && hibernateAccessType != jpaAccessType ) {
+
+ StringBuilder builder = new StringBuilder();
+ builder.append( property.toString() );
+ builder.append(
+ " defines @AccessType and @Access with contradicting values. Use of @Access only is recommended."
+ );
+ throw new MappingException( builder.toString() );
+ }
+
+ if ( hibernateAccessType != AccessType.DEFAULT ) {
+ accessType = hibernateAccessType;
+ }
+ else if ( jpaAccessType != AccessType.DEFAULT ) {
+ accessType = jpaAccessType;
+ }
+ return accessType;
}
public String getPropertyName() throws MappingException {
diff --git a/annotations/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java b/annotations/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java
index cafa7aa650..1121a34be0 100644
--- a/annotations/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java
+++ b/annotations/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java
@@ -28,19 +28,19 @@ import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
public class PropertyPreloadedData implements PropertyData {
- private final String defaultAccess;
+ private final AccessType defaultAccess;
private final String propertyName;
private final XClass returnedClass;
- public PropertyPreloadedData(String defaultAccess, String propertyName, XClass returnedClass) {
+ public PropertyPreloadedData(AccessType defaultAccess, String propertyName, XClass returnedClass) {
this.defaultAccess = defaultAccess;
this.propertyName = propertyName;
this.returnedClass = returnedClass;
}
- public String getDefaultAccess() throws MappingException {
+ public AccessType getDefaultAccess() throws MappingException {
return defaultAccess;
}
diff --git a/annotations/src/main/java/org/hibernate/cfg/WrappedInferredData.java b/annotations/src/main/java/org/hibernate/cfg/WrappedInferredData.java
index 4ff3e6d90f..82ae148637 100644
--- a/annotations/src/main/java/org/hibernate/cfg/WrappedInferredData.java
+++ b/annotations/src/main/java/org/hibernate/cfg/WrappedInferredData.java
@@ -43,7 +43,7 @@ public class WrappedInferredData implements PropertyData {
return wrappedInferredData.getClassOrElementName();
}
- public String getDefaultAccess() {
+ public AccessType getDefaultAccess() {
return wrappedInferredData.getDefaultAccess();
}
diff --git a/annotations/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java b/annotations/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
index 094f39fdb9..aa871c4bde 100644
--- a/annotations/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
+++ b/annotations/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
@@ -76,6 +76,7 @@ import org.hibernate.annotations.WhereJoinTable;
import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.cfg.AccessType;
import org.hibernate.cfg.AnnotatedClassType;
import org.hibernate.cfg.AnnotationBinder;
import org.hibernate.cfg.BinderHelper;
@@ -157,6 +158,7 @@ public abstract class CollectionBinder {
protected Map inheritanceStatePerClass;
private XClass declaringClass;
private boolean declaringClassSet;
+ private AccessType accessType;
public void setUpdatable(boolean updatable) {
this.updatable = updatable;
@@ -170,17 +172,14 @@ public abstract class CollectionBinder {
this.insertable = insertable;
}
-
public void setCascadeStrategy(String cascadeStrategy) {
this.cascadeStrategy = cascadeStrategy;
}
- public void setPropertyAccessorName(String propertyAccessorName) {
- this.propertyAccessorName = propertyAccessorName;
+ public void setAccessType(AccessType accessType) {
+ this.accessType = accessType;
}
- private String propertyAccessorName;
-
public void setInverseJoinColumns(Ejb3JoinColumn[] inverseJoinColumns) {
this.inverseJoinColumns = inverseJoinColumns;
}
@@ -491,7 +490,7 @@ public abstract class CollectionBinder {
if ( cascadeStrategy != null && cascadeStrategy.indexOf( "delete-orphan" ) >= 0 ) {
collection.setOrphanDelete( true );
}
- binder.setPropertyAccessorName( propertyAccessorName );
+ binder.setAccessType( accessType );
binder.setProperty( property );
binder.setInsertable( insertable );
binder.setUpdatable( updatable );
@@ -1296,11 +1295,10 @@ public abstract class CollectionBinder {
throw new AssertionFailure( "Unable to guess collection property accessor name" );
}
- //boolean propertyAccess = embeddable == null || AccessType.PROPERTY.equals( embeddable.access() );
- PropertyData inferredData = new PropertyPreloadedData( "property", "element", elementClass );
+ PropertyData inferredData = new PropertyPreloadedData( AccessType.PROPERTY, "element", elementClass );
//TODO be smart with isNullable
Component component = AnnotationBinder.fillComponent(
- holder, inferredData, isPropertyAnnotated, isPropertyAnnotated ? "property" : "field", true,
+ holder, inferredData, isPropertyAnnotated ? AccessType.PROPERTY : AccessType.FIELD, true,
entityBinder, false, false,
true, mappings, inheritanceStatePerClass
);
diff --git a/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java b/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
index 248b10a718..5b198ae63e 100644
--- a/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
+++ b/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
@@ -27,6 +27,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import javax.persistence.Access;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
@@ -38,7 +39,6 @@ import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode;
import org.hibernate.MappingException;
-import org.hibernate.annotations.AccessType;
import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@@ -60,6 +60,7 @@ import org.hibernate.annotations.Tuplizers;
import org.hibernate.annotations.Where;
import org.hibernate.annotations.common.reflection.XAnnotatedElement;
import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.cfg.AccessType;
import org.hibernate.cfg.AnnotationBinder;
import org.hibernate.cfg.BinderHelper;
import org.hibernate.cfg.Ejb3JoinColumn;
@@ -99,7 +100,6 @@ public class EntityBinder {
private ExtendedMappings mappings;
private Logger log = LoggerFactory.getLogger( EntityBinder.class );
private String discriminatorValue = "";
- private boolean isPropertyAnnotated = false;
private boolean dynamicInsert;
private boolean dynamicUpdate;
private boolean explicitHibernateEntityAnnotation;
@@ -118,11 +118,7 @@ public class EntityBinder {
private InheritanceState inheritanceState;
private boolean ignoreIdAnnotations;
private boolean cacheLazyProperty;
- private String propertyAccessor;
-
- public boolean isPropertyAnnotated() {
- return isPropertyAnnotated;
- }
+ private AccessType propertyAccessor = AccessType.DEFAULT;
/**
* Use as a fake one for Collection of elements
@@ -847,36 +843,41 @@ public class EntityBinder {
}
}
- public void setPropertyAnnotated(boolean propertyAnnotated) {
- this.isPropertyAnnotated = propertyAnnotated;
- }
-
- public String getPropertyAccessor() {
+ public AccessType getPropertyAccessor() {
return propertyAccessor;
}
- public void setPropertyAccessor(String propertyAccessor) {
+ public void setPropertyAccessor(AccessType propertyAccessor) {
this.propertyAccessor = propertyAccessor;
}
- public boolean isPropertyAnnotated(XAnnotatedElement element) {
- AccessType access = element.getAnnotation( AccessType.class );
- if ( access == null ) return isPropertyAnnotated;
- String propertyAccessor = access.value();
- if ( "property".equals( propertyAccessor ) ) {
- return Boolean.TRUE;
- }
- else if ( "field".equals( propertyAccessor ) ) {
- return Boolean.FALSE;
- }
- else {
- return isPropertyAnnotated;
- }
- }
+ public AccessType getPropertyAccessor(XAnnotatedElement element) {
+ AccessType accessType = propertyAccessor;
- public String getPropertyAccessor(XAnnotatedElement element) {
- AccessType access = element.getAnnotation( AccessType.class );
- if ( access == null ) return propertyAccessor;
- return access.value();
+ AccessType hibernateAccessType = null;
+ AccessType jpaAccessType = null;
+
+ org.hibernate.annotations.AccessType accessTypeAnnotation = element.getAnnotation( org.hibernate.annotations.AccessType.class );
+ if ( accessTypeAnnotation != null ) {
+ hibernateAccessType = AccessType.getAccessStrategy( accessTypeAnnotation.value() );
+ }
+
+ Access access = element.getAnnotation( Access.class );
+ if ( access != null ) {
+ jpaAccessType = AccessType.getAccessStrategy( access.value() );
+ }
+
+ if ( hibernateAccessType != null && jpaAccessType != null && hibernateAccessType != jpaAccessType ) {
+ throw new MappingException( " " );
+ }
+
+ if ( hibernateAccessType != null ) {
+ accessType = hibernateAccessType;
+ }
+ else if ( jpaAccessType != null ) {
+ accessType = jpaAccessType;
+ }
+
+ return accessType;
}
}
diff --git a/annotations/src/main/java/org/hibernate/cfg/annotations/MapBinder.java b/annotations/src/main/java/org/hibernate/cfg/annotations/MapBinder.java
index 786e06713c..0e674cdaa1 100644
--- a/annotations/src/main/java/org/hibernate/cfg/annotations/MapBinder.java
+++ b/annotations/src/main/java/org/hibernate/cfg/annotations/MapBinder.java
@@ -39,6 +39,7 @@ import org.hibernate.annotations.MapKey;
import org.hibernate.annotations.MapKeyManyToMany;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.cfg.AccessType;
import org.hibernate.cfg.AnnotatedClassType;
import org.hibernate.cfg.AnnotationBinder;
import org.hibernate.cfg.BinderHelper;
@@ -227,10 +228,10 @@ public class MapBinder extends CollectionBinder {
//boolean propertyAccess = embeddable == null || AccessType.PROPERTY.equals( embeddable.access() );
//FIXME "index" is it right?
- PropertyData inferredData = new PropertyPreloadedData( "property", "index", elementClass );
+ PropertyData inferredData = new PropertyPreloadedData( AccessType.PROPERTY, "index", elementClass );
//TODO be smart with isNullable
Component component = AnnotationBinder.fillComponent(
- holder, inferredData, isPropertyAnnotated, isPropertyAnnotated ? "property" : "field", true,
+ holder, inferredData, isPropertyAnnotated ? AccessType.PROPERTY : AccessType.FIELD, true,
entityBinder, false, false,
true, mappings, inheritanceStatePerClass
);
diff --git a/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java b/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java
index 2439600cb5..343ee96283 100644
--- a/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java
+++ b/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java
@@ -35,6 +35,7 @@ import org.hibernate.annotations.OptimisticLock;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.cfg.AccessType;
import org.hibernate.cfg.Ejb3Column;
import org.hibernate.cfg.ExtendedMappings;
import org.hibernate.cfg.PropertyHolder;
@@ -54,7 +55,7 @@ public class PropertyBinder {
private String name;
private String returnedClassName;
private boolean lazy;
- private String propertyAccessorName;
+ private AccessType accessType;
private Ejb3Column[] columns;
private PropertyHolder holder;
private ExtendedMappings mappings;
@@ -94,8 +95,8 @@ public class PropertyBinder {
this.lazy = lazy;
}
- public void setPropertyAccessorName(String propertyAccessorName) {
- this.propertyAccessorName = propertyAccessorName;
+ public void setAccessType(AccessType accessType) {
+ this.accessType = accessType;
}
public void setColumns(Ejb3Column[] columns) {
@@ -170,7 +171,7 @@ public class PropertyBinder {
prop.setValue( value );
prop.setLazy( lazy );
prop.setCascade( cascade );
- prop.setPropertyAccessorName( propertyAccessorName );
+ prop.setPropertyAccessorName( accessType.getType() );
Generated ann = property != null ?
property.getAnnotation( Generated.class ) :
null;
@@ -231,5 +232,5 @@ public class PropertyBinder {
public SimpleValueBinder getSimpleValueBinder() {
return simpleValueBinder;
}
-
+
}
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/Closet.java b/annotations/src/test/java/org/hibernate/test/annotations/access/Closet.java
new file mode 100644
index 0000000000..5f4ad09b69
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/Closet.java
@@ -0,0 +1,30 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.test.annotations.access;
+
+import javax.persistence.Embeddable;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Embeddable
+public class Closet extends Furniture {
+ int numberOfDoors;
+}
+
+
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/Foobar.java b/annotations/src/test/java/org/hibernate/test/annotations/access/Foobar.java
new file mode 100644
index 0000000000..1a7e29dd0f
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/Foobar.java
@@ -0,0 +1,31 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.test.annotations.access;
+
+import javax.persistence.Entity;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+public class Foobar {
+ String foo;
+}
+
+
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/AccessMappingTest.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/AccessMappingTest.java
new file mode 100644
index 0000000000..580e4b2384
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/AccessMappingTest.java
@@ -0,0 +1,154 @@
+//$Id: AccessTest.java 15025 2008-08-11 09:14:39Z hardy.ferentschik $
+/*
+ * 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.test.annotations.access.jpa;
+
+import junit.framework.TestCase;
+
+import org.hibernate.EntityMode;
+import org.hibernate.MappingException;
+import org.hibernate.cfg.AnnotationConfiguration;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.property.BasicPropertyAccessor;
+import org.hibernate.property.DirectPropertyAccessor;
+import org.hibernate.tuple.entity.EntityMetamodel;
+import org.hibernate.tuple.entity.PojoEntityTuplizer;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class AccessMappingTest extends TestCase {
+
+ public void testInconsistentAnnotationPlacement() throws Exception {
+ AnnotationConfiguration cfg = new AnnotationConfiguration();
+ cfg.addAnnotatedClass( Course.class );
+ cfg.addAnnotatedClass( Student.class );
+ try {
+ cfg.buildSessionFactory();
+ fail( "@Id and @OneToMany are not placed consistently in test entities. SessionFactory creation should fail." );
+ }
+ catch ( MappingException e ) {
+ // success
+ }
+ }
+
+ public void testFieldAnnotationPlacement() throws Exception {
+ AnnotationConfiguration cfg = new AnnotationConfiguration();
+ Class> classUnderTest = CourseFieldAccess.class;
+ cfg.addAnnotatedClass( classUnderTest );
+ cfg.addAnnotatedClass( Student.class );
+ SessionFactoryImplementor factory = ( SessionFactoryImplementor ) cfg.buildSessionFactory();
+ EntityMetamodel metaModel = factory.getEntityPersister( classUnderTest.getName() )
+ .getEntityMetamodel();
+ PojoEntityTuplizer tuplizer = ( PojoEntityTuplizer ) metaModel.getTuplizer( EntityMode.POJO );
+ assertTrue(
+ "Field access should be used.",
+ tuplizer.getIdentifierGetter() instanceof DirectPropertyAccessor.DirectGetter
+ );
+ }
+
+ public void testPropertyAnnotationPlacement() throws Exception {
+ AnnotationConfiguration cfg = new AnnotationConfiguration();
+ Class> classUnderTest = CoursePropertyAccess.class;
+ cfg.addAnnotatedClass( classUnderTest );
+ cfg.addAnnotatedClass( Student.class );
+ SessionFactoryImplementor factory = ( SessionFactoryImplementor ) cfg.buildSessionFactory();
+ EntityMetamodel metaModel = factory.getEntityPersister( classUnderTest.getName() )
+ .getEntityMetamodel();
+ PojoEntityTuplizer tuplizer = ( PojoEntityTuplizer ) metaModel.getTuplizer( EntityMode.POJO );
+ assertTrue(
+ "Property access should be used.",
+ tuplizer.getIdentifierGetter() instanceof BasicPropertyAccessor.BasicGetter
+ );
+ }
+
+ public void testExplicitPropertyAccessAnnotationsOnProperty() throws Exception {
+ AnnotationConfiguration cfg = new AnnotationConfiguration();
+ Class> classUnderTest = CourseExplicitPropertyAccess.class;
+ cfg.addAnnotatedClass( classUnderTest );
+ cfg.addAnnotatedClass( Student.class );
+ SessionFactoryImplementor factory = ( SessionFactoryImplementor ) cfg.buildSessionFactory();
+ EntityMetamodel metaModel = factory.getEntityPersister( classUnderTest.getName() )
+ .getEntityMetamodel();
+ PojoEntityTuplizer tuplizer = ( PojoEntityTuplizer ) metaModel.getTuplizer( EntityMode.POJO );
+ assertTrue(
+ "Property access should be used.",
+ tuplizer.getIdentifierGetter() instanceof BasicPropertyAccessor.BasicGetter
+ );
+ }
+
+ public void testExplicitPropertyAccessAnnotationsOnField() throws Exception {
+ AnnotationConfiguration cfg = new AnnotationConfiguration();
+ cfg.addAnnotatedClass( CourseExplicitPropertyAccess3.class );
+ cfg.addAnnotatedClass( Student.class );
+ try {
+ cfg.buildSessionFactory();
+ fail( "@Id and @OneToMany are not placed consistently in test entities. SessionFactory creation should fail." );
+ }
+ catch ( MappingException e ) {
+ // success
+ }
+ }
+
+ public void testExplicitPropertyAccessAnnotationsWithHibernateStyleOverride() throws Exception {
+ AnnotationConfiguration cfg = new AnnotationConfiguration();
+ Class> classUnderTest = CourseExplicitPropertyAccess2.class;
+ cfg.addAnnotatedClass( classUnderTest );
+ cfg.addAnnotatedClass( Student.class );
+ SessionFactoryImplementor factory = ( SessionFactoryImplementor ) cfg.buildSessionFactory();
+ EntityMetamodel metaModel = factory.getEntityPersister( classUnderTest.getName() )
+ .getEntityMetamodel();
+ PojoEntityTuplizer tuplizer = ( PojoEntityTuplizer ) metaModel.getTuplizer( EntityMode.POJO );
+ assertTrue(
+ "Field access should be used.",
+ tuplizer.getIdentifierGetter() instanceof DirectPropertyAccessor.DirectGetter
+ );
+
+ assertTrue(
+ "Property access should be used.",
+ tuplizer.getGetter( 0 ) instanceof BasicPropertyAccessor.BasicGetter
+ );
+ }
+
+ public void testExplicitPropertyAccessAnnotationsWithJpaStyleOverride() throws Exception {
+ AnnotationConfiguration cfg = new AnnotationConfiguration();
+ Class> classUnderTest = CourseExplicitPropertyAccess4.class;
+ cfg.addAnnotatedClass( classUnderTest );
+ cfg.addAnnotatedClass( Student.class );
+ SessionFactoryImplementor factory = ( SessionFactoryImplementor ) cfg.buildSessionFactory();
+ EntityMetamodel metaModel = factory.getEntityPersister( classUnderTest.getName() )
+ .getEntityMetamodel();
+ PojoEntityTuplizer tuplizer = ( PojoEntityTuplizer ) metaModel.getTuplizer( EntityMode.POJO );
+ assertTrue(
+ "Field access should be used.",
+ tuplizer.getIdentifierGetter() instanceof DirectPropertyAccessor.DirectGetter
+ );
+
+ assertTrue(
+ "Property access should be used.",
+ tuplizer.getGetter( 0 ) instanceof BasicPropertyAccessor.BasicGetter
+ );
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/AccessTest.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/AccessTest.java
new file mode 100644
index 0000000000..77a40796c6
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/AccessTest.java
@@ -0,0 +1,184 @@
+//$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.test.annotations.access.jpa;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.test.annotations.TestCase;
+import org.hibernate.test.annotations.access.Closet;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class AccessTest extends TestCase {
+
+ public void testDefaultConfigurationModeIsInherited() throws Exception {
+ User john = new User();
+ john.setFirstname( "John" );
+ john.setLastname( "Doe" );
+ List friends = new ArrayList();
+ User friend = new User();
+ friend.setFirstname( "Jane" );
+ friend.setLastname( "Doe" );
+ friends.add( friend );
+ john.setFriends( friends );
+
+ Session s = openSession();
+ s.persist( john );
+ Transaction tx = s.beginTransaction();
+ tx.commit();
+ s.clear();
+ tx = s.beginTransaction();
+ john = (User) s.get( User.class, john.getId() );
+ assertEquals("Wrong number of friends", 1, john.getFriends().size() );
+ assertNull( john.firstname );
+
+ s.delete( john );
+ tx.commit();
+ s.close();
+ }
+
+ public void testSuperclassOverriding() throws Exception {
+ Furniture fur = new Furniture();
+ fur.setColor( "Black" );
+ fur.setName( "Beech" );
+ fur.isAlive = true;
+ Session s = openSession();
+ s.persist( fur );
+ Transaction tx = s.beginTransaction();
+ tx.commit();
+ s.clear();
+ tx = s.beginTransaction();
+ fur = (Furniture) s.get( Furniture.class, fur.getId() );
+ assertFalse( fur.isAlive );
+ assertNotNull( fur.getColor() );
+ s.delete( fur );
+ tx.commit();
+ s.close();
+ }
+
+ public void testSuperclassNonOverriding() throws Exception {
+ Furniture fur = new Furniture();
+ fur.setGod( "Buddha" );
+ Session s = openSession();
+ s.persist( fur );
+ Transaction tx = s.beginTransaction();
+ tx.commit();
+ s.clear();
+ tx = s.beginTransaction();
+ fur = (Furniture) s.get( Furniture.class, fur.getId() );
+ assertNotNull( fur.getGod() );
+ s.delete( fur );
+ tx.commit();
+ s.close();
+ }
+
+ public void testPropertyOverriding() throws Exception {
+ Furniture fur = new Furniture();
+ fur.weight = 3;
+ Session s = openSession();
+ s.persist( fur );
+ Transaction tx = s.beginTransaction();
+ tx.commit();
+ s.clear();
+ tx = s.beginTransaction();
+ fur = (Furniture) s.get( Furniture.class, fur.getId() );
+ assertEquals( 5, fur.weight );
+ s.delete( fur );
+ tx.commit();
+ s.close();
+
+ }
+
+ public void testNonOverridenSubclass() throws Exception {
+ Chair chair = new Chair();
+ chair.setPillow( "Blue" );
+ Session s = openSession();
+ s.persist( chair );
+ Transaction tx = s.beginTransaction();
+ tx.commit();
+ s.clear();
+ tx = s.beginTransaction();
+ chair = (Chair) s.get( Chair.class, chair.getId() );
+ assertNull( chair.getPillow() );
+ s.delete( chair );
+ tx.commit();
+ s.close();
+
+ }
+
+ public void testOverridenSubclass() throws Exception {
+ BigBed bed = new BigBed();
+ bed.size = 5;
+ bed.setQuality( "good" );
+ Session s = openSession();
+ s.persist( bed );
+ Transaction tx = s.beginTransaction();
+ tx.commit();
+ s.clear();
+ tx = s.beginTransaction();
+ bed = (BigBed) s.get( BigBed.class, bed.getId() );
+ assertEquals( 5, bed.size );
+ assertNull( bed.getQuality() );
+ s.delete( bed );
+ tx.commit();
+ s.close();
+
+ }
+
+ public void testFieldsOverriding() throws Exception {
+ Gardenshed gs = new Gardenshed();
+ gs.floors = 4;
+ Session s = openSession();
+ s.persist( gs );
+ Transaction tx = s.beginTransaction();
+ tx.commit();
+ s.clear();
+ tx = s.beginTransaction();
+ gs = (Gardenshed) s.get( Gardenshed.class, gs.getId() );
+ assertEquals( 4, gs.floors );
+ assertEquals( 6, gs.getFloors() );
+ s.delete( gs );
+ tx.commit();
+ s.close();
+
+ }
+
+ protected Class[] getMappings() {
+ return new Class[] {
+ Bed.class,
+ Chair.class,
+ Furniture.class,
+ BigBed.class,
+ Gardenshed.class,
+ Closet.class,
+ Person.class,
+ User.class
+ };
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Bed.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Bed.java
new file mode 100644
index 0000000000..a85d219de3
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Bed.java
@@ -0,0 +1,49 @@
+//$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.test.annotations.access.jpa;
+
+import javax.persistence.Access;
+import javax.persistence.AccessType;
+import javax.persistence.Entity;
+import javax.persistence.Transient;
+
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+@Access(AccessType.PROPERTY)
+public class Bed extends Furniture {
+ String quality;
+
+ @Transient
+ public String getQuality() {
+ return quality;
+ }
+
+ public void setQuality(String quality) {
+ this.quality = quality;
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Being.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Being.java
new file mode 100644
index 0000000000..f8d3d4964a
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Being.java
@@ -0,0 +1,49 @@
+//$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.test.annotations.access.jpa;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+public class Being {
+ @Id
+ @GeneratedValue
+ private long id;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+}
+
+
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/BigBed.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/BigBed.java
new file mode 100644
index 0000000000..a142f9811a
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/BigBed.java
@@ -0,0 +1,37 @@
+//$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.test.annotations.access.jpa;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class BigBed extends Bed {
+ @Column(name = "bed_size")
+ public int size;
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Chair.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Chair.java
new file mode 100644
index 0000000000..c420d7048c
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Chair.java
@@ -0,0 +1,46 @@
+//$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.test.annotations.access.jpa;
+
+import javax.persistence.Entity;
+import javax.persistence.Transient;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Chair extends Furniture {
+
+ @Transient
+ private String pillow;
+
+ public String getPillow() {
+ return pillow;
+ }
+
+ public void setPillow(String pillow) {
+ this.pillow = pillow;
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Course.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Course.java
new file mode 100644
index 0000000000..a3d96cf8f4
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Course.java
@@ -0,0 +1,74 @@
+//$Id: AccessTest.java 15025 2008-08-11 09:14:39Z hardy.ferentschik $
+/*
+ * 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.test.annotations.access.jpa;
+
+import java.util.List;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+public class Course {
+ @Id
+ @GeneratedValue
+ private long id;
+
+ private String title;
+
+ private List students;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @OneToMany(cascade = CascadeType.ALL)
+ public List getStudents() {
+ return students;
+ }
+
+ public void setStudents(List students) {
+ this.students = students;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
+
+
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseExplicitPropertyAccess.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseExplicitPropertyAccess.java
new file mode 100644
index 0000000000..2c48c80c66
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseExplicitPropertyAccess.java
@@ -0,0 +1,75 @@
+//$Id: AccessTest.java 15025 2008-08-11 09:14:39Z hardy.ferentschik $
+/*
+ * 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.test.annotations.access.jpa;
+
+import java.util.List;
+import javax.persistence.Access;
+import javax.persistence.AccessType;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+@Access(AccessType.PROPERTY)
+public class CourseExplicitPropertyAccess {
+ private long id;
+
+ private String title;
+
+ private List students;
+
+ @Id
+ @GeneratedValue
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @OneToMany(cascade = CascadeType.ALL)
+ public List getStudents() {
+ return students;
+ }
+
+ public void setStudents(List students) {
+ this.students = students;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseExplicitPropertyAccess2.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseExplicitPropertyAccess2.java
new file mode 100644
index 0000000000..d3e22ed982
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseExplicitPropertyAccess2.java
@@ -0,0 +1,77 @@
+//$Id: AccessTest.java 15025 2008-08-11 09:14:39Z hardy.ferentschik $
+/*
+ * 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.test.annotations.access.jpa;
+
+import java.util.List;
+import javax.persistence.Access;
+import javax.persistence.AccessType;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+@Access(AccessType.PROPERTY)
+public class CourseExplicitPropertyAccess2 {
+ private long id;
+
+ private String title;
+
+
+ private List students;
+
+ @Id
+ @GeneratedValue
+ @org.hibernate.annotations.AccessType("field")
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @OneToMany(cascade = CascadeType.ALL)
+ public List getStudents() {
+ return students;
+ }
+
+ public void setStudents(List students) {
+ this.students = students;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseExplicitPropertyAccess3.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseExplicitPropertyAccess3.java
new file mode 100644
index 0000000000..b288e38cbb
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseExplicitPropertyAccess3.java
@@ -0,0 +1,75 @@
+//$Id: AccessTest.java 15025 2008-08-11 09:14:39Z hardy.ferentschik $
+/*
+ * 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.test.annotations.access.jpa;
+
+import java.util.List;
+import javax.persistence.Access;
+import javax.persistence.AccessType;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+@Access(AccessType.PROPERTY)
+public class CourseExplicitPropertyAccess3 {
+ @Id
+ @GeneratedValue
+ private long id;
+
+ private String title;
+
+ @OneToMany(cascade = CascadeType.ALL)
+ private List students;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public List getStudents() {
+ return students;
+ }
+
+ public void setStudents(List students) {
+ this.students = students;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseExplicitPropertyAccess4.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseExplicitPropertyAccess4.java
new file mode 100644
index 0000000000..7a33476aa0
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseExplicitPropertyAccess4.java
@@ -0,0 +1,77 @@
+//$Id: AccessTest.java 15025 2008-08-11 09:14:39Z hardy.ferentschik $
+/*
+ * 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.test.annotations.access.jpa;
+
+import java.util.List;
+import javax.persistence.Access;
+import javax.persistence.AccessType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+@Access(AccessType.PROPERTY)
+public class CourseExplicitPropertyAccess4 {
+
+ @Access(AccessType.FIELD)
+ @Id
+ @GeneratedValue
+ private long id;
+
+ private String title;
+
+ private List students;
+
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @ManyToMany
+ public List getStudents() {
+ return students;
+ }
+
+ public void setStudents(List students) {
+ this.students = students;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseFieldAccess.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseFieldAccess.java
new file mode 100644
index 0000000000..ab99a815e0
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CourseFieldAccess.java
@@ -0,0 +1,72 @@
+//$Id: AccessTest.java 15025 2008-08-11 09:14:39Z hardy.ferentschik $
+/*
+ * 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.test.annotations.access.jpa;
+
+import java.util.List;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+public class CourseFieldAccess {
+ @Id
+ @GeneratedValue
+ private long id;
+
+ private String title;
+
+ @OneToMany(cascade = CascadeType.ALL)
+ private List students;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public List getStudents() {
+ return students;
+ }
+
+ public void setStudents(List students) {
+ this.students = students;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CoursePropertyAccess.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CoursePropertyAccess.java
new file mode 100644
index 0000000000..943aeaa8f4
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/CoursePropertyAccess.java
@@ -0,0 +1,72 @@
+//$Id: AccessTest.java 15025 2008-08-11 09:14:39Z hardy.ferentschik $
+/*
+ * 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.test.annotations.access.jpa;
+
+import java.util.List;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+public class CoursePropertyAccess {
+ private long id;
+
+ private String title;
+
+ private List students;
+
+ @Id
+ @GeneratedValue
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @OneToMany(cascade = CascadeType.ALL)
+ public List getStudents() {
+ return students;
+ }
+
+ public void setStudents(List students) {
+ this.students = students;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Furniture.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Furniture.java
new file mode 100644
index 0000000000..3e3c63d0cf
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Furniture.java
@@ -0,0 +1,72 @@
+//$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.test.annotations.access.jpa;
+
+import javax.persistence.Access;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Transient;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+@Access(javax.persistence.AccessType.FIELD)
+public class Furniture extends Woody {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ private String brand;
+
+ @Transient
+ public String getBrand() {
+ return brand;
+ }
+
+ public void setBrand(String brand) {
+ this.brand = brand;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ @Access(javax.persistence.AccessType.PROPERTY)
+ public long weight;
+
+ public long getWeight() {
+ return weight + 1;
+ }
+
+ public void setWeight(long weight) {
+ this.weight = weight + 1;
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Gardenshed.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Gardenshed.java
new file mode 100644
index 0000000000..b3a1fd1911
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Gardenshed.java
@@ -0,0 +1,78 @@
+//$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.test.annotations.access.jpa;
+
+import javax.persistence.Access;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Transient;
+
+/**
+ * This is the opposite of the Furniture test, as this tries to override the class AccessType("property") with
+ * the property AccessType("field").
+ *
+ * @author Dennis Fleurbaaij
+ * @since 2007-05-31
+ */
+@Entity
+@Access(javax.persistence.AccessType.PROPERTY)
+public class Gardenshed
+ extends
+ Woody {
+ private Integer id;
+ private String brand;
+ public long floors;
+
+ @Transient
+ public String getBrand() {
+ return brand;
+ }
+
+ public void setBrand(String brand) {
+ this.brand = brand;
+ }
+
+ @Id
+ @GeneratedValue
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ // These 2 functions should not return in Hibernate, but the value should come from the field "floors"
+
+ @Access(javax.persistence.AccessType.FIELD)
+ public long getFloors() {
+ return this.floors + 2;
+ }
+
+ public void setFloors(long floors) {
+ this.floors = floors + 2;
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Person.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Person.java
new file mode 100644
index 0000000000..bb6e1d3c5d
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Person.java
@@ -0,0 +1,60 @@
+//$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.test.annotations.access.jpa;
+
+import javax.persistence.Access;
+import javax.persistence.Entity;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+// explicitly override the access type to be property (default is field, see Being)
+@Access(javax.persistence.AccessType.PROPERTY)
+public class Person extends Being {
+
+ String firstname;
+
+ private String lastname;
+
+ public String getFirstname() {
+ return null;
+ }
+
+ public void setFirstname(String firstname) {
+ this.firstname = firstname;
+ }
+
+ public String getLastname() {
+ return lastname;
+ }
+
+ public void setLastname(String lastname) {
+ this.lastname = lastname;
+ }
+}
+
+
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Student.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Student.java
new file mode 100644
index 0000000000..ad4216a841
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Student.java
@@ -0,0 +1,59 @@
+//$Id: AccessTest.java 15025 2008-08-11 09:14:39Z hardy.ferentschik $
+/*
+ * 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.test.annotations.access.jpa;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+public class Student {
+ @Id
+ @GeneratedValue
+ private long id;
+
+ private String name;
+
+ 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;
+ }
+}
+
+
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Thingy.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Thingy.java
new file mode 100644
index 0000000000..33a296b267
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Thingy.java
@@ -0,0 +1,45 @@
+//$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.test.annotations.access.jpa;
+
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Transient;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@MappedSuperclass
+public class Thingy {
+ private String god;
+
+ @Transient
+ public String getGod() {
+ return god;
+ }
+
+ public void setGod(String god) {
+ this.god = god;
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/User.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/User.java
new file mode 100644
index 0000000000..4af84a7c21
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/User.java
@@ -0,0 +1,48 @@
+//$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.test.annotations.access.jpa;
+
+import java.util.List;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.OneToMany;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+public class User extends Person {
+
+ @OneToMany(cascade = CascadeType.ALL)
+ private List friends;
+
+ public List getFriends() {
+ return friends;
+ }
+
+ public void setFriends(List friends) {
+ this.friends = friends;
+ }
+}
\ No newline at end of file
diff --git a/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Woody.java b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Woody.java
new file mode 100644
index 0000000000..5e8f1a4b5c
--- /dev/null
+++ b/annotations/src/test/java/org/hibernate/test/annotations/access/jpa/Woody.java
@@ -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.test.annotations.access.jpa;
+
+import javax.persistence.Access;
+import javax.persistence.MappedSuperclass;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@MappedSuperclass
+@Access(javax.persistence.AccessType.PROPERTY)
+public class Woody extends Thingy {
+ private String color;
+ private String name;
+ public boolean isAlive; //shouldn't be persistent
+
+ public String getColor() {
+ return color;
+ }
+
+ public void setColor(String color) {
+ this.color = color;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
\ No newline at end of file