@@ -835,8 +835,9 @@ private static void processIdClassElements(
835835
836836for ( int i = 0 ; i < classElements .size (); i ++ ) {
837837final PropertyData idClassPropertyData = classElements .get ( i );
838+ final String propertyName = idClassPropertyData .getPropertyName ();
838839final PropertyData entityPropertyData =
839- baseClassElementsByName .get ( idClassPropertyData . getPropertyName () );
840+ baseClassElementsByName .get ( propertyName );
840841if ( propertyHolder .isInIdClass () ) {
841842if ( entityPropertyData == null ) {
842843throw new AnnotationException (
@@ -852,11 +853,38 @@ private static void processIdClassElements(
852853//the annotation overriding will be dealt with by a mechanism similar to @MapsId
853854continue ;
854855}
856+ if ( !hasCompatibleType ( idClassPropertyData .getTypeName (), entityPropertyData .getTypeName () ) ) {
857+ throw new AnnotationException (
858+ "Property '" + propertyName + "' in @IdClass '" + idClassPropertyData .getDeclaringClass ().getName ()
859+ + "' doesn't match type in entity class '" + baseInferredData .getPropertyType ().getName ()
860+ + "' (expected '" + entityPropertyData .getTypeName () + "' but was '" + idClassPropertyData .getTypeName () + "')"
861+ );
862+ }
855863}
856864classElements .set ( i , entityPropertyData ); //this works since they are in the same order
857865}
858866}
859867
868+ private static boolean hasCompatibleType (String typeNameInIdClass , String typeNameInEntityClass ) {
869+ return typeNameInIdClass .equals ( typeNameInEntityClass )
870+ || canonicalize ( typeNameInIdClass ).equals ( typeNameInEntityClass )
871+ || typeNameInIdClass .equals ( canonicalize ( typeNameInEntityClass ) );
872+ }
873+
874+ private static String canonicalize (String typeName ) {
875+ return switch (typeName ) {
876+ case "boolean" -> Boolean .class .getName ();
877+ case "char" -> Character .class .getName ();
878+ case "int" -> Integer .class .getName ();
879+ case "long" -> Long .class .getName ();
880+ case "short" -> Short .class .getName ();
881+ case "byte" -> Byte .class .getName ();
882+ case "float" -> Float .class .getName ();
883+ case "double" -> Double .class .getName ();
884+ default -> typeName ;
885+ };
886+ }
887+
860888static Component createEmbeddable (
861889PropertyHolder propertyHolder ,
862890PropertyData inferredData ,
0 commit comments