@@ -357,7 +357,7 @@ private static NotFoundAction notFoundAction(
357357 if ( notFound != null ) {
358358 if ( manyToManyAnn == null ) {
359359 throw new AnnotationException ( "Collection '" + getPath ( propertyHolder , inferredData )
360- + "' annotated '@NotFound' is not a '@ManyToMany' association" );
360+ + "' annotated '@NotFound' is not a '@ManyToMany' association" );
361361 }
362362 return notFound .action ();
363363 }
@@ -405,8 +405,8 @@ private static void checkAnnotations(
405405 if ( ( oneToMany != null || manyToMany != null || elementCollection != null )
406406 && isToManyAssociationWithinEmbeddableCollection ( propertyHolder ) ) {
407407 throw new AnnotationException ( "Property '" + getPath ( propertyHolder , inferredData ) +
408- "' belongs to an '@Embeddable' class that is contained in an '@ElementCollection' and may not be a "
409- + annotationName ( oneToMany , manyToMany , elementCollection ) );
408+ "' belongs to an '@Embeddable' class that is contained in an '@ElementCollection' and may not be a "
409+ + annotationName ( oneToMany , manyToMany , elementCollection ) );
410410 }
411411
412412 if ( oneToMany != null && property .hasDirectAnnotationUsage ( SoftDelete .class ) ) {
@@ -420,20 +420,20 @@ && isToManyAssociationWithinEmbeddableCollection( propertyHolder ) ) {
420420 && manyToMany != null
421421 && isNotBlank ( manyToMany .mappedBy () ) ) {
422422 throw new AnnotationException ( "Collection '" + getPath ( propertyHolder , inferredData ) +
423- "' is the unowned side of a bidirectional '@ManyToMany' and may not have an '@OrderColumn'" );
423+ "' is the unowned side of a bidirectional '@ManyToMany' and may not have an '@OrderColumn'" );
424424 }
425425
426426 if ( manyToMany != null || elementCollection != null ) {
427427 if ( property .hasDirectAnnotationUsage ( JoinColumn .class )
428428 || property .hasDirectAnnotationUsage ( JoinColumns .class ) ) {
429429 throw new AnnotationException ( "Property '" + getPath ( propertyHolder , inferredData )
430- + "' is a " + annotationName (
430+ + "' is a " + annotationName (
431431 oneToMany ,
432432 manyToMany ,
433433 elementCollection
434434 )
435- + " and is directly annotated '@JoinColumn'"
436- + " (specify '@JoinColumn' inside '@JoinTable' or '@CollectionTable')" );
435+ + " and is directly annotated '@JoinColumn'"
436+ + " (specify '@JoinColumn' inside '@JoinTable' or '@CollectionTable')" );
437437 }
438438 }
439439 }
@@ -476,13 +476,13 @@ private static String handleTargetEntity(
476476 //TODO enhance exception with @ManyToAny and @CollectionOfElements
477477 if ( oneToManyAnn != null && manyToManyAnn != null ) {
478478 throw new AnnotationException ( "Property '" + getPath ( propertyHolder , inferredData )
479- + "' is annotated both '@OneToMany' and '@ManyToMany'" );
479+ + "' is annotated both '@OneToMany' and '@ManyToMany'" );
480480 }
481481 final String mappedBy ;
482482 if ( oneToManyAnn != null ) {
483483 if ( joinColumns .isSecondary () ) {
484484 throw new AnnotationException ( "Collection '" + getPath ( propertyHolder , inferredData )
485- + "' has foreign key in secondary table" );
485+ + "' has foreign key in secondary table" );
486486 }
487487 collectionBinder .setFkJoinColumns ( joinColumns );
488488 mappedBy = nullIfEmpty ( oneToManyAnn .mappedBy () );
@@ -497,7 +497,7 @@ private static String handleTargetEntity(
497497 else if ( elementCollectionAnn != null ) {
498498 if ( joinColumns .isSecondary () ) {
499499 throw new AnnotationException ( "Collection '" + getPath ( propertyHolder , inferredData )
500- + "' has foreign key in secondary table" );
500+ + "' has foreign key in secondary table" );
501501 }
502502 collectionBinder .setFkJoinColumns ( joinColumns );
503503 mappedBy = null ;
@@ -657,9 +657,14 @@ private static void bindJoinedTableAssociation(
657657 buildingContext
658658 );
659659
660+ // If @CollectionTableOverride is present, use its collectionTable annotation
661+ final CollectionTable effectiveCollectionTable = collectionTableOverride != null
662+ ? collectionTableOverride .collectionTable ()
663+ : collectionTable ;
664+
660665 final JoinColumn [] annJoins ;
661666 final JoinColumn [] annInverseJoins ;
662- if ( assocTable != null || collectionTable != null ) {
667+ if ( assocTable != null || effectiveCollectionTable != null ) {
663668 final String catalog ;
664669 final String schema ;
665670 final String tableName ;
@@ -670,18 +675,15 @@ private static void bindJoinedTableAssociation(
670675 final String options ;
671676
672677 //JPA 2 has priority
673- if ( collectionTable != null ) {
674- catalog = collectionTable .catalog ();
675- schema = collectionTable .schema ();
676- // Use overridden table name if @CollectionTableOverride is present
677- tableName = collectionTableOverride != null
678- ? collectionTableOverride .table ()
679- : collectionTable .name ();
680- uniqueConstraints = collectionTable .uniqueConstraints ();
681- joins = collectionTable .joinColumns ();
678+ if ( effectiveCollectionTable != null ) {
679+ catalog = effectiveCollectionTable .catalog ();
680+ schema = effectiveCollectionTable .schema ();
681+ tableName = effectiveCollectionTable .name ();
682+ uniqueConstraints = effectiveCollectionTable .uniqueConstraints ();
683+ joins = effectiveCollectionTable .joinColumns ();
682684 inverseJoins = null ;
683- jpaIndexes = collectionTable .indexes ();
684- options = collectionTable .options ();
685+ jpaIndexes = effectiveCollectionTable .indexes ();
686+ options = effectiveCollectionTable .options ();
685687 }
686688 else {
687689 catalog = assocTable .catalog ();
@@ -928,20 +930,20 @@ private static CollectionClassification determineCollectionClassification(
928930
929931 if ( property .hasAnnotationUsage ( OrderColumn .class , modelsContext ) ) {
930932 throw new AnnotationException ( "Attribute '"
931- + qualify (
933+ + qualify (
932934 property .getDeclaringType ().getName (),
933935 property .getName ()
934936 )
935- + "' is annotated '@Bag' and may not also be annotated '@OrderColumn'" );
937+ + "' is annotated '@Bag' and may not also be annotated '@OrderColumn'" );
936938 }
937939
938940 if ( property .hasAnnotationUsage ( ListIndexBase .class , modelsContext ) ) {
939941 throw new AnnotationException ( "Attribute '"
940- + qualify (
942+ + qualify (
941943 property .getDeclaringType ().getName (),
942944 property .getName ()
943945 )
944- + "' is annotated '@Bag' and may not also be annotated '@ListIndexBase'" );
946+ + "' is annotated '@Bag' and may not also be annotated '@ListIndexBase'" );
945947 }
946948
947949 final var collectionJavaType = property .getType ().determineRawClass ().toJavaClass ();
@@ -1078,7 +1080,7 @@ private void setElementType(TypeDetails collectionElementType) {
10781080
10791081 private void setTargetEntity (Class <?> targetEntity ) {
10801082 setTargetEntity ( modelsContext ().getClassDetailsRegistry ()
1081- .resolveClassDetails ( targetEntity .getName () ) );
1083+ .resolveClassDetails ( targetEntity .getName () ) );
10821084 }
10831085
10841086 private void setTargetEntity (ClassDetails targetEntity ) {
@@ -1151,7 +1153,7 @@ private boolean isMutable() {
11511153 private void checkMapKeyColumn () {
11521154 if ( property .hasDirectAnnotationUsage ( MapKeyColumn .class ) && hasMapKeyProperty ) {
11531155 throw new AnnotationException ( "Collection '" + qualify ( propertyHolder .getPath (), propertyName )
1154- + "' is annotated both '@MapKey' and '@MapKeyColumn'" );
1156+ + "' is annotated both '@MapKey' and '@MapKeyColumn'" );
11551157 }
11561158 }
11571159
@@ -1188,49 +1190,49 @@ private void detectMappedByProblem(boolean isMappedBy) {
11881190 if ( property .hasDirectAnnotationUsage ( JoinColumn .class )
11891191 || property .hasDirectAnnotationUsage ( JoinColumns .class ) ) {
11901192 throw new AnnotationException ( "Association '"
1191- + qualify ( propertyHolder .getPath (), propertyName )
1192- + "' is 'mappedBy' another entity and may not specify the '@JoinColumn'" );
1193+ + qualify ( propertyHolder .getPath (), propertyName )
1194+ + "' is 'mappedBy' another entity and may not specify the '@JoinColumn'" );
11931195 }
11941196 if ( propertyHolder .getJoinTable ( property ) != null ) {
11951197 throw new AnnotationException ( "Association '"
1196- + qualify ( propertyHolder .getPath (), propertyName )
1197- + "' is 'mappedBy' another entity and may not specify the '@JoinTable'" );
1198+ + qualify ( propertyHolder .getPath (), propertyName )
1199+ + "' is 'mappedBy' another entity and may not specify the '@JoinTable'" );
11981200 }
11991201 if ( oneToMany ) {
12001202 if ( property .hasDirectAnnotationUsage ( MapKeyColumn .class ) ) {
12011203 BOOT_LOGGER .warn ( "Association '"
1202- + qualify ( propertyHolder .getPath (), propertyName )
1203- + "' is 'mappedBy' another entity and should not specify a '@MapKeyColumn'"
1204- + " (use '@MapKey' instead)" );
1204+ + qualify ( propertyHolder .getPath (), propertyName )
1205+ + "' is 'mappedBy' another entity and should not specify a '@MapKeyColumn'"
1206+ + " (use '@MapKey' instead)" );
12051207 }
12061208 if ( property .hasDirectAnnotationUsage ( OrderColumn .class ) ) {
12071209 BOOT_LOGGER .warn ( "Association '"
1208- + qualify ( propertyHolder .getPath (), propertyName )
1209- + "' is 'mappedBy' another entity and should not specify an '@OrderColumn'"
1210- + " (use '@OrderBy' instead)" );
1210+ + qualify ( propertyHolder .getPath (), propertyName )
1211+ + "' is 'mappedBy' another entity and should not specify an '@OrderColumn'"
1212+ + " (use '@OrderBy' instead)" );
12111213 }
12121214 }
12131215 else {
12141216 if ( property .hasDirectAnnotationUsage ( MapKeyColumn .class ) ) {
12151217 throw new AnnotationException ( "Association '"
1216- + qualify ( propertyHolder .getPath (), propertyName )
1217- + "' is 'mappedBy' another entity and may not specify a '@MapKeyColumn'"
1218- + " (use '@MapKey' instead)" );
1218+ + qualify ( propertyHolder .getPath (), propertyName )
1219+ + "' is 'mappedBy' another entity and may not specify a '@MapKeyColumn'"
1220+ + " (use '@MapKey' instead)" );
12191221 }
12201222 if ( property .hasDirectAnnotationUsage ( OrderColumn .class ) ) {
12211223 throw new AnnotationException ( "Association '"
1222- + qualify ( propertyHolder .getPath (), propertyName )
1223- + "' is 'mappedBy' another entity and may not specify an '@OrderColumn'"
1224- + " (use '@OrderBy' instead)" );
1224+ + qualify ( propertyHolder .getPath (), propertyName )
1225+ + "' is 'mappedBy' another entity and may not specify an '@OrderColumn'"
1226+ + " (use '@OrderBy' instead)" );
12251227 }
12261228 }
12271229 }
12281230 else if ( oneToMany
12291231 && property .hasDirectAnnotationUsage ( OnDelete .class )
12301232 && !hasExplicitJoinColumn () ) {
12311233 throw new AnnotationException ( "Unidirectional '@OneToMany' association '"
1232- + qualify ( propertyHolder .getPath (), propertyName )
1233- + "' is annotated '@OnDelete' and must explicitly specify a '@JoinColumn'" );
1234+ + qualify ( propertyHolder .getPath (), propertyName )
1235+ + "' is annotated '@OnDelete' and must explicitly specify a '@JoinColumn'" );
12341236 }
12351237 }
12361238
@@ -1524,7 +1526,7 @@ TypeDetails getElementType() {
15241526 }
15251527 else {
15261528 throw new AnnotationException ( "Collection '" + safeCollectionRole ()
1527- + "' is declared with a raw type and has an explicit 'targetEntity'" );
1529+ + "' is declared with a raw type and has an explicit 'targetEntity'" );
15281530 }
15291531 }
15301532 else {
@@ -1842,7 +1844,7 @@ private void addFilterJoinTable(boolean hasAssociationTable, FilterJoinTable fil
18421844 }
18431845 else {
18441846 throw new AnnotationException ( "Collection '" + qualify ( propertyHolder .getPath (), propertyName )
1845- + "' is an association with no join table and may not have a '@FilterJoinTable'" );
1847+ + "' is an association with no join table and may not have a '@FilterJoinTable'" );
18461848 }
18471849 }
18481850
@@ -1864,15 +1866,15 @@ private String getDefaultFilterCondition(String name, Annotation annotation) {
18641866 final var definition = getMetadataCollector ().getFilterDefinition ( name );
18651867 if ( definition == null ) {
18661868 throw new AnnotationException ( "Collection '" + qualify ( propertyHolder .getPath (), propertyName )
1867- + "' has a '@" + annotation .annotationType ().getSimpleName ()
1868- + "' for an undefined filter named '" + name + "'" );
1869+ + "' has a '@" + annotation .annotationType ().getSimpleName ()
1870+ + "' for an undefined filter named '" + name + "'" );
18691871 }
18701872 final String defaultCondition = definition .getDefaultFilterCondition ();
18711873 if ( isBlank ( defaultCondition ) ) {
18721874 throw new AnnotationException ( "Collection '" + qualify ( propertyHolder .getPath (), propertyName ) +
1873- "' has a '@" + annotation .annotationType ().getSimpleName ()
1874- + "' with no 'condition' and no default condition was given by the '@FilterDef' named '"
1875- + name + "'" );
1875+ "' has a '@" + annotation .annotationType ().getSimpleName ()
1876+ + "' with no 'condition' and no default condition was given by the '@FilterDef' named '"
1877+ + name + "'" );
18761878 }
18771879 return defaultCondition ;
18781880 }
@@ -2483,8 +2485,8 @@ private static void addCheckToCollection(Table collectionTable, Check check) {
24832485 final String name = check .name ();
24842486 final String constraint = check .constraints ();
24852487 collectionTable .addCheck ( name .isBlank ()
2486- ? new CheckConstraint ( constraint )
2487- : new CheckConstraint ( name , constraint ) );
2488+ ? new CheckConstraint ( constraint )
2489+ : new CheckConstraint ( name , constraint ) );
24882490 }
24892491
24902492 private void processSoftDeletes () {
@@ -2513,7 +2515,7 @@ private void handleUnownedManyToMany(
25132515 boolean isCollectionOfEntities ) {
25142516 if ( !isCollectionOfEntities ) {
25152517 throw new AnnotationException ( "Association '" + safeCollectionRole () + "'"
2516- + targetEntityMessage ( elementType ) );
2518+ + targetEntityMessage ( elementType ) );
25172519 }
25182520
25192521 joinColumns .setManyToManyOwnerSideEntityName ( collectionEntity .getEntityName () );
@@ -2536,7 +2538,7 @@ private void checkCheckAnnotation() {
25362538 if ( property .hasDirectAnnotationUsage ( Checks .class )
25372539 || property .hasDirectAnnotationUsage ( Check .class ) ) {
25382540 throw new AnnotationException ( "Association '" + safeCollectionRole ()
2539- + " is an unowned collection and may not be annotated '@Check'" );
2541+ + " is an unowned collection and may not be annotated '@Check'" );
25402542 }
25412543 }
25422544
@@ -2549,20 +2551,20 @@ private void detectManyToManyProblems(
25492551 if ( property .hasDirectAnnotationUsage ( ManyToMany .class )
25502552 || property .hasDirectAnnotationUsage ( OneToMany .class ) ) {
25512553 throw new AnnotationException ( "Association '" + safeCollectionRole () + "'"
2552- + targetEntityMessage ( elementType ) );
2554+ + targetEntityMessage ( elementType ) );
25532555 }
25542556 else if ( isManyToAny ) {
25552557 if ( propertyHolder .getJoinTable ( property ) == null ) {
25562558 throw new AnnotationException ( "Association '" + safeCollectionRole ()
2557- + "' is a '@ManyToAny' and must specify a '@JoinTable'" );
2559+ + "' is a '@ManyToAny' and must specify a '@JoinTable'" );
25582560 }
25592561 }
25602562 else {
25612563 final var joinTableAnn = propertyHolder .getJoinTable ( property );
25622564 if ( joinTableAnn != null && !ArrayHelper .isEmpty ( joinTableAnn .inverseJoinColumns () ) ) {
25632565 throw new AnnotationException ( "Association '" + safeCollectionRole ()
2564- + " has a '@JoinTable' with 'inverseJoinColumns' and"
2565- + targetEntityMessage ( elementType ) );
2566+ + " has a '@JoinTable' with 'inverseJoinColumns' and"
2567+ + targetEntityMessage ( elementType ) );
25662568 }
25672569 }
25682570 }
0 commit comments