44 */
55package org .hibernate .boot .model .internal ;
66
7- import java .io .Serializable ;
87import java .lang .annotation .Annotation ;
9- import java .lang .reflect .ParameterizedType ;
108import java .util .Collection ;
119import java .util .HashMap ;
1210import java .util .List ;
1311import java .util .Map ;
1412import java .util .function .Function ;
1513
14+ import jakarta .persistence .Embedded ;
15+ import jakarta .persistence .ManyToMany ;
16+ import jakarta .persistence .ManyToOne ;
17+ import jakarta .persistence .OneToMany ;
18+ import jakarta .persistence .OneToOne ;
1619import org .hibernate .AnnotationException ;
1720import org .hibernate .AssertionFailure ;
1821import org .hibernate .MappingException ;
5760import org .hibernate .internal .util .ReflectHelper ;
5861import org .hibernate .mapping .BasicValue ;
5962import org .hibernate .mapping .Component ;
63+ import org .hibernate .mapping .PersistentClass ;
64+ import org .hibernate .mapping .SimpleValue ;
6065import org .hibernate .mapping .Table ;
6166import org .hibernate .models .spi .ClassDetails ;
6267import org .hibernate .models .spi .MemberDetails ;
9297
9398import static java .util .Collections .emptyMap ;
9499import static org .hibernate .boot .model .internal .AnnotationHelper .extractParameterMap ;
100+ import static org .hibernate .boot .model .internal .TableBinder .linkJoinColumnWithValueOverridingNameIfImplicit ;
95101import static org .hibernate .internal .log .DeprecationLogger .DEPRECATION_LOGGER ;
96102
97103/**
@@ -157,9 +163,8 @@ public enum Kind {
157163 private BasicValue basicValue ;
158164
159165 private String persistentClassName ;
160- private String propertyName ;
161166 private String returnedClassName ;
162- private String referencedEntityName ;
167+ private String referencedEntityName ; // only used for @MapsId or @IdClass
163168
164169 public BasicValueBinder (Kind kind , MetadataBuildingContext buildingContext ) {
165170 this ( kind , null , buildingContext );
@@ -293,14 +298,10 @@ public void setVersion(boolean isVersion) {
293298 }
294299 }
295300
296- public void setReferencedEntityName (String referencedEntityName ) {
301+ void setReferencedEntityName (String referencedEntityName ) {
297302 this .referencedEntityName = referencedEntityName ;
298303 }
299304
300- public void setPropertyName (String propertyName ) {
301- this .propertyName = propertyName ;
302- }
303-
304305 public void setReturnedClassName (String returnedClassName ) {
305306 this .returnedClassName = returnedClassName ;
306307 }
@@ -553,6 +554,7 @@ private void prepareMapKey(
553554 enumType = mapKeyEnumeratedAnn .value ();
554555 }
555556
557+ //noinspection deprecation
556558 final MapKeyTemporal mapKeyTemporalAnn =
557559 attribute .getDirectAnnotationUsage ( MapKeyTemporal .class );
558560 if ( mapKeyTemporalAnn != null ) {
@@ -731,12 +733,14 @@ private void prepareCollectionElement(
731733 : explicitElementTypeDetails ;
732734 final ClassDetails rawElementType = elementTypeDetails .determineRawClass ();
733735 final java .lang .reflect .Type javaType = rawElementType .toJavaClass ();
734- final Class <Object > javaTypeClass = ReflectHelper .getClass ( javaType );
736+ final Class <? > javaTypeClass = ReflectHelper .getClass ( javaType );
735737
736738 implicitJavaTypeAccess = typeConfiguration -> javaType ;
737739
740+ //noinspection deprecation
738741 final Temporal temporalAnn = attribute .getDirectAnnotationUsage ( Temporal .class );
739742 if ( temporalAnn != null ) {
743+ //noinspection deprecation
740744 DEPRECATION_LOGGER .deprecatedAnnotation ( Temporal .class , attribute .getName () );
741745 temporalPrecision = temporalAnn .value ();
742746 if ( temporalPrecision == null ) {
@@ -795,7 +799,7 @@ private void prepareBasicAttribute(
795799 String declaringClassName ,
796800 MemberDetails attribute ,
797801 TypeDetails attributeType ) {
798- final Class <Object > javaTypeClass = attributeType .determineRawClass ().toJavaClass ();
802+ final Class <? > javaTypeClass = attributeType .determineRawClass ().toJavaClass ();
799803 implicitJavaTypeAccess = typeConfiguration -> {
800804 if ( attributeType .getTypeKind () == TypeDetails .Kind .PARAMETERIZED_TYPE ) {
801805 return ParameterizedTypeImpl .from ( attributeType .asParameterizedType () );
@@ -806,7 +810,7 @@ private void prepareBasicAttribute(
806810 };
807811
808812 //noinspection deprecation
809- final var temporalAnn = attribute .getDirectAnnotationUsage ( Temporal .class );
813+ final Temporal temporalAnn = attribute .getDirectAnnotationUsage ( Temporal .class );
810814 if ( temporalAnn != null ) {
811815 //noinspection deprecation
812816 DEPRECATION_LOGGER .deprecatedAnnotation ( Temporal .class ,
@@ -852,7 +856,7 @@ private void prepareBasicAttribute(
852856 normalSupplementalDetails ( attribute );
853857 }
854858
855- private boolean canUseEnumerated (TypeDetails javaType , Class <Object > javaTypeClass ) {
859+ private boolean canUseEnumerated (TypeDetails javaType , Class <? > javaTypeClass ) {
856860 if ( javaTypeClass .isEnum ()
857861 || javaTypeClass .isArray () && javaTypeClass .getComponentType ().isEnum () ) {
858862 return true ;
@@ -1152,6 +1156,7 @@ private void normalSupplementalDetails(MemberDetails attribute) {
11521156 enumType = enumerated .value ();
11531157 }
11541158
1159+ //noinspection deprecation
11551160 final Temporal temporal = attribute .getDirectAnnotationUsage ( Temporal .class );
11561161 if ( temporal != null ) {
11571162 temporalPrecision = temporal .value ();
@@ -1187,15 +1192,19 @@ private void applyJpaConverter(MemberDetails attribute, ConverterDescriptor attr
11871192 disallowConverter ( attribute , Id .class );
11881193 disallowConverter ( attribute , Version .class );
11891194 if ( kind == Kind .MAP_KEY ) {
1195+ //noinspection deprecation
11901196 disallowConverter ( attribute , MapKeyTemporal .class );
11911197 disallowConverter ( attribute , MapKeyEnumerated .class );
11921198 }
11931199 else {
1200+ //noinspection deprecation
11941201 disallowConverter ( attribute , Temporal .class );
11951202 disallowConverter ( attribute , Enumerated .class );
1196- }
1197- if ( isAssociation () ) {
1198- throw new AnnotationException ( "'AttributeConverter' not allowed for association '" + attribute .getName () + "'" );
1203+ disallowConverter ( attribute , Embedded .class );
1204+ disallowConverter ( attribute , ManyToOne .class );
1205+ disallowConverter ( attribute , OneToOne .class );
1206+ disallowConverter ( attribute , OneToMany .class );
1207+ disallowConverter ( attribute , ManyToMany .class );
11991208 }
12001209 this .converterDescriptor = attributeConverterDescriptor ;
12011210 }
@@ -1207,12 +1216,6 @@ void disallowConverter(MemberDetails attribute, Class<? extends Annotation> anno
12071216 }
12081217 }
12091218
1210- private boolean isAssociation () {
1211- // todo : this information is only known to caller(s), need to pass that information in somehow.
1212- // or, is this enough?
1213- return referencedEntityName != null ;
1214- }
1215-
12161219 public BasicValue make () {
12171220 if ( basicValue != null ) {
12181221 return basicValue ;
@@ -1227,7 +1230,8 @@ public BasicValue make() {
12271230 basicValue = new BasicValue ( buildingContext , table );
12281231
12291232 if ( columns .getPropertyHolder ().isComponent () ) {
1230- final ComponentPropertyHolder propertyHolder = (ComponentPropertyHolder ) columns .getPropertyHolder ();
1233+ final ComponentPropertyHolder propertyHolder =
1234+ (ComponentPropertyHolder ) columns .getPropertyHolder ();
12311235 basicValue .setAggregateColumn ( propertyHolder .getAggregateColumn () );
12321236 }
12331237
@@ -1285,7 +1289,38 @@ private void linkWithValue() {
12851289 column .setParent ( joinColumns );
12861290 }
12871291 collector .addSecondPass (
1288- new PkDrivenByDefaultMapsIdSecondPass ( referencedEntityName , joinColumns , basicValue )
1292+ new FkSecondPass () {
1293+ @ Override
1294+ public SimpleValue getValue () {
1295+ return basicValue ;
1296+ }
1297+
1298+ @ Override
1299+ public String getReferencedEntityName () {
1300+ return referencedEntityName ;
1301+ }
1302+
1303+ @ Override
1304+ public boolean isInPrimaryKey () {
1305+ // @MapsId is not itself in the primary key,
1306+ // so it's safe to simply process it after all the primary keys have been processed.
1307+ return true ;
1308+ }
1309+
1310+ @ Override
1311+ public void doSecondPass (Map <String , PersistentClass > persistentClasses ) {
1312+ final PersistentClass referencedEntity = persistentClasses .get ( referencedEntityName );
1313+ if ( referencedEntity == null ) {
1314+ // TODO: much better error message if this is something that can really happen!
1315+ throw new AnnotationException ( "Unknown entity name '" + referencedEntityName + "'" );
1316+ }
1317+ linkJoinColumnWithValueOverridingNameIfImplicit (
1318+ referencedEntity ,
1319+ referencedEntity .getKey (),
1320+ joinColumns , basicValue
1321+ );
1322+ }
1323+ }
12891324 );
12901325 }
12911326 else if ( aggregateComponent != null ) {
@@ -1311,7 +1346,8 @@ public void fillSimpleValue() {
13111346
13121347 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
13131348
1314- if ( explicitCustomType != null && DynamicParameterizedType .class .isAssignableFrom ( explicitCustomType ) ) {
1349+ if ( explicitCustomType != null
1350+ && DynamicParameterizedType .class .isAssignableFrom ( explicitCustomType ) ) {
13151351 basicValue .setTypeParameters ( createDynamicParameterizedTypeParameters () );
13161352 }
13171353
@@ -1393,29 +1429,6 @@ private Map<String, Object> createDynamicParameterizedTypeParameters() {
13931429 return parameters ;
13941430 }
13951431
1396- private boolean isEnum () {
1397- final Class <?> clazz = getValueClass ();
1398- return clazz != null && clazz .isEnum ();
1399- }
1400-
1401- private boolean isSerializable () {
1402- final Class <?> clazz = getValueClass ();
1403- return clazz != null && Serializable .class .isAssignableFrom ( clazz );
1404- }
1405-
1406- private Class <?> getValueClass () {
1407- if ( implicitJavaTypeAccess != null ) {
1408- java .lang .reflect .Type type = implicitJavaTypeAccess .apply ( getTypeConfiguration () );
1409- if ( type instanceof ParameterizedType parameterizedType ) {
1410- type = parameterizedType .getRawType ();
1411- }
1412- if ( type instanceof Class <?> cl ) {
1413- return cl ;
1414- }
1415- }
1416- return null ;
1417- }
1418-
14191432 /**
14201433 * Access to detail of basic value mappings based on {@link Kind}
14211434 */
0 commit comments