HHH-6581: Changed default access type determination to look for an explicit access annotation at the top of the hierarchy before falling back to the current strategy of examining identifiers

This commit is contained in:
John Verhaeg 2011-09-09 09:41:02 -05:00
parent 47d76b365c
commit 88b6b4c67b
2 changed files with 20 additions and 9 deletions

View File

@ -25,6 +25,7 @@ package org.hibernate.cfg;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.persistence.Access;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Id;
@ -206,7 +207,8 @@ public class InheritanceState {
}
/*
* Get the annotated elements, guessing the access type from @Id or @EmbeddedId presence.
* Get the annotated elements and determine access type from hierarchy, guessing from @Id or @EmbeddedId presence if not
* specified.
* Change EntityBinder by side effect
*/
@ -245,8 +247,16 @@ public class InheritanceState {
}
private AccessType determineDefaultAccessType() {
XClass xclass = clazz;
while ( xclass != null && !Object.class.getName().equals( xclass.getName() ) ) {
for (XClass xclass = clazz; xclass != null; xclass = xclass.getSuperclass()) {
if ((xclass.getSuperclass() == null || Object.class.getName().equals(xclass.getSuperclass().getName()))
&& (xclass.isAnnotationPresent(Entity.class) || xclass.isAnnotationPresent(MappedSuperclass.class))
&& xclass.isAnnotationPresent(Access.class))
return AccessType.getAccessStrategy(xclass.getAnnotation(Access.class).value());
}
// Guess from identifier.
// FIX: Shouldn't this be determined by the first attribute (i.e., field or property) with annotations, but without an
// explicit Access annotation, according to JPA 2.0 spec 2.3.1: Default Access Type?
for (XClass xclass = clazz; xclass != null && !Object.class.getName().equals(xclass.getName()); xclass = xclass.getSuperclass()) {
if ( xclass.isAnnotationPresent( Entity.class ) || xclass.isAnnotationPresent( MappedSuperclass.class ) ) {
for ( XProperty prop : xclass.getDeclaredProperties( AccessType.PROPERTY.getType() ) ) {
final boolean isEmbeddedId = prop.isAnnotationPresent( EmbeddedId.class );
@ -261,9 +271,8 @@ public class InheritanceState {
}
}
}
xclass = xclass.getSuperclass();
}
throw new AnnotationException( "No identifier specified for entity: " + clazz );
throw new AnnotationException( "No identifier specified for entity: " + clazz );
}
private void getMappedSuperclassesTillNextEntityOrdered() {

View File

@ -47,11 +47,13 @@ import org.hibernate.testing.TestForIssue;
public class AccessMappingTest extends TestCase {
private ServiceRegistry serviceRegistry;
protected void setUp() {
@Override
protected void setUp() {
serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( Environment.getProperties() );
}
protected void tearDown() {
@Override
protected void tearDown() {
if ( serviceRegistry != null ) {
ServiceRegistryBuilder.destroy( serviceRegistry );
}
@ -202,8 +204,8 @@ public class AccessMappingTest extends TestCase {
.getEntityMetamodel()
.getTuplizer();
assertTrue(
"Property access should be used since the default access mode gets inherited",
tuplizer.getGetter( 0 ) instanceof BasicPropertyAccessor.BasicGetter
"Field access should be used since the default access mode gets inherited",
tuplizer.getGetter( 0 ) instanceof DirectPropertyAccessor.DirectGetter
);
}