3636import org .hibernate .type .descriptor .java .SerializableJavaType ;
3737import org .hibernate .type .descriptor .java .TemporalJavaType ;
3838import org .hibernate .type .descriptor .java .spi .JavaTypeRegistry ;
39+ import org .hibernate .type .descriptor .java .spi .JdbcTypeRecommendationException ;
3940import org .hibernate .type .descriptor .jdbc .JdbcType ;
4041import org .hibernate .type .descriptor .jdbc .JdbcTypeIndicators ;
4142import org .hibernate .type .descriptor .jdbc .ObjectJdbcType ;
@@ -74,9 +75,10 @@ public static <T> BasicValue.Resolution<T> from(
7475
7576 final JavaType <T > reflectedJtd = reflectedJtdResolver .get ();
7677
77- // NOTE : the distinction that is made below wrt `explicitJavaType` and `reflectedJtd` is
78- // needed temporarily to trigger "legacy resolution" versus "ORM6 resolution. Yes, it
79- // makes the code a little more complicated but the benefit is well worth it - saving memory
78+ // NOTE: the distinction that is made below wrt `explicitJavaType` and `reflectedJtd`
79+ // is needed temporarily to trigger "legacy resolution" versus "ORM6 resolution.
80+ // Yes, it makes the code a little more complicated but the benefit is well worth
81+ // it - saving memory
8082
8183 final BasicType <T > jdbcMapping ;
8284
@@ -141,8 +143,8 @@ else if ( explicitJdbcType != null ) {
141143 );
142144 }
143145 else {
144- // see if there is a registered BasicType for this JavaType and, if so, use it.
145- // this mimics the legacy handling
146+ // see if there is a registered BasicType for this JavaType and,
147+ // if so, use it. This mimics the legacy handling.
146148 final BasicType registeredType ;
147149 if ( reflectedJtd instanceof BasicPluralJavaType <?> ) {
148150 final BasicPluralJavaType <?> containerJtd = (BasicPluralJavaType <?>) reflectedJtd ;
@@ -198,9 +200,26 @@ else if ( isTemporal( elementJtd ) ) {
198200 jdbcMapping = resolveSqlTypeIndicators ( stdIndicators , registeredType , reflectedJtd );
199201 }
200202 else {
201- // there was not a "legacy" BasicType registration, so use `JavaType#getRecommendedJdbcType`, if
202- // one, to create a mapping
203- final JdbcType recommendedJdbcType = reflectedJtd .getRecommendedJdbcType ( stdIndicators );
203+ // there was not a "legacy" BasicType registration,
204+ // so use `JavaType#getRecommendedJdbcType`, if one,
205+ // to create a mapping
206+ final JdbcType recommendedJdbcType ;
207+ try {
208+ recommendedJdbcType = reflectedJtd .getRecommendedJdbcType ( stdIndicators );
209+ }
210+ catch (JdbcTypeRecommendationException jtre ) {
211+ if ( buildingContext .getMetadataCollector ()
212+ .getEntityBindingMap ().values ().stream ()
213+ .anyMatch ( pc -> pc .getMappedClass ().equals (resolvedJavaType ) ) ) {
214+ throw new MappingException ( "Incorrect use of entity type '"
215+ + resolvedJavaType .getTypeName ()
216+ + "' (possibly due to missing association mapping annotation)" ,
217+ jtre );
218+ }
219+ else {
220+ throw jtre ;
221+ }
222+ }
204223 if ( recommendedJdbcType != null ) {
205224 jdbcMapping = resolveSqlTypeIndicators (
206225 stdIndicators ,
@@ -222,7 +241,7 @@ else if ( reflectedJtd instanceof SerializableJavaType
222241 else {
223242 if ( explicitJdbcType != null ) {
224243 // we have an explicit STD, but no JTD - infer JTD
225- // - NOTE : yes its an odd case, but its easy to implement here, so...
244+ // NOTE : yes it's an odd case, but easy to implement here, so...
226245 Integer length = null ;
227246 Integer scale = null ;
228247 if ( selectable instanceof Column ) {
@@ -251,7 +270,6 @@ else if ( column.getLength() != null ) {
251270 }
252271 else {
253272 // we have neither a JTD nor STD
254-
255273 throw new MappingException (
256274 "Could not determine JavaType nor JdbcType to use" +
257275 " for BasicValue: owner = " + ownerName +
0 commit comments