HHH-10242 - Deal with HCANN poor handling of multiple properties by matching stem name
This commit is contained in:
parent
5cc5ed1c84
commit
ae9ff5587e
|
@ -28,6 +28,10 @@ import org.hibernate.annotations.Target;
|
||||||
import org.hibernate.annotations.Type;
|
import org.hibernate.annotations.Type;
|
||||||
import org.hibernate.annotations.common.reflection.XClass;
|
import org.hibernate.annotations.common.reflection.XClass;
|
||||||
import org.hibernate.annotations.common.reflection.XProperty;
|
import org.hibernate.annotations.common.reflection.XProperty;
|
||||||
|
import org.hibernate.annotations.common.reflection.java.JavaXMember;
|
||||||
|
import org.hibernate.boot.jaxb.Origin;
|
||||||
|
import org.hibernate.boot.jaxb.SourceType;
|
||||||
|
import org.hibernate.cfg.annotations.HCANNHelper;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
|
||||||
|
@ -188,7 +192,14 @@ class PropertyContainer {
|
||||||
// HHH-10242 detect registration of the same property twice eg boolean isId() + UUID getId()
|
// HHH-10242 detect registration of the same property twice eg boolean isId() + UUID getId()
|
||||||
XProperty oldProperty = propertiesMap.get( property.getName() );
|
XProperty oldProperty = propertiesMap.get( property.getName() );
|
||||||
if ( oldProperty != null ) {
|
if ( oldProperty != null ) {
|
||||||
throw LOG.throwAmbiguousPropertyException( this.xClass, oldProperty.getName(), oldProperty.getType(), property.getType() );
|
throw new org.hibernate.boot.MappingException(
|
||||||
|
LOG.ambiguousPropertyMethods(
|
||||||
|
xClass.getName(),
|
||||||
|
HCANNHelper.annotatedElementSignature( oldProperty ),
|
||||||
|
HCANNHelper.annotatedElementSignature( property )
|
||||||
|
),
|
||||||
|
new Origin( SourceType.ANNOTATION, xClass.getName() )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
propertiesMap.put( property.getName(), property );
|
propertiesMap.put( property.getName(), property );
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.cfg.annotations;
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedElement;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Member;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import org.hibernate.AssertionFailure;
|
||||||
|
import org.hibernate.annotations.common.reflection.XProperty;
|
||||||
|
import org.hibernate.annotations.common.reflection.java.JavaXMember;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage the various fun-ness of dealing with HCANN...
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class HCANNHelper {
|
||||||
|
private static Class javaXMemberClass = JavaXMember.class;
|
||||||
|
private static Method getMemberMethod;
|
||||||
|
|
||||||
|
public static String annotatedElementSignature(XProperty xProperty) {
|
||||||
|
if ( getMemberMethod == null ) {
|
||||||
|
resolveGetMemberMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
return getUnderlyingMember( xProperty ).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Member getUnderlyingMember(XProperty xProperty) {
|
||||||
|
if ( getMemberMethod == null ) {
|
||||||
|
resolveGetMemberMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return (Member) getMemberMethod.invoke( xProperty );
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException e) {
|
||||||
|
throw new AssertionFailure(
|
||||||
|
"Could not resolve member signature from XProperty reference",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (InvocationTargetException e) {
|
||||||
|
throw new AssertionFailure(
|
||||||
|
"Could not resolve member signature from XProperty reference",
|
||||||
|
e.getCause()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static void resolveGetMemberMethod() {
|
||||||
|
try {
|
||||||
|
getMemberMethod = javaXMemberClass.getDeclaredMethod( "getMember" );
|
||||||
|
getMemberMethod.setAccessible( true );
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodException e) {
|
||||||
|
throw new AssertionFailure(
|
||||||
|
"Could not resolve JavaXAnnotatedElement#toAnnotatedElement method in order to access XProperty member signature",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1753,6 +1753,9 @@ public interface CoreMessageLogger extends BasicLogger {
|
||||||
@Message(value = "Omitting cached file [%s] as the mapping file is newer", id = 473)
|
@Message(value = "Omitting cached file [%s] as the mapping file is newer", id = 473)
|
||||||
void cachedFileObsolete(File cachedFile);
|
void cachedFileObsolete(File cachedFile);
|
||||||
|
|
||||||
@Message(value = "Ambiguous property detected %s.%s (of types %s and %s). Mark one as @Transient.", id = 474)
|
@Message(
|
||||||
HibernateException throwAmbiguousPropertyException(XClass entity, String propertyName, XClass firstPropertyType, XClass secondPropertyType);
|
value = "Ambiguous persistent property methods detected on %s; mark one as @Transient : [%s] and [%s]",
|
||||||
|
id = 474
|
||||||
|
)
|
||||||
|
String ambiguousPropertyMethods(String entityName, String oneMethodSig, String secondMethodSig);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.startsWith;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,17 +52,23 @@ public class GetAndIsVariantGetterTest {
|
||||||
.buildMetadata();
|
.buildMetadata();
|
||||||
fail( "Expecting a failure" );
|
fail( "Expecting a failure" );
|
||||||
}
|
}
|
||||||
catch (MappingException ignore) {
|
catch (MappingException e) {
|
||||||
// expected
|
assertThat( e.getMessage(), startsWith( "In trying to locate getter for property [id]" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestForIssue( jiraKey = "HHH-10172" )
|
@TestForIssue( jiraKey = "HHH-10172" )
|
||||||
public void testAnnotations() {
|
public void testAnnotations() {
|
||||||
new MetadataSources( ssr )
|
try {
|
||||||
.addAnnotatedClass( TheEntity.class )
|
new MetadataSources( ssr )
|
||||||
.buildMetadata();
|
.addAnnotatedClass( TheEntity.class )
|
||||||
|
.buildMetadata();
|
||||||
|
fail( "Expecting a failure" );
|
||||||
|
}
|
||||||
|
catch (MappingException e) {
|
||||||
|
assertThat( e.getMessage(), startsWith( "HHH000474: Ambiguous persistent property methods detected on" ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
|
|
Loading…
Reference in New Issue