Skip to content

Commit 5ecc0f3

Browse files
committed
HHH-19324 - Switch tests using hbm.xml to use mapping.xml
HHH-19422 - Introduce @CollectionIdJavaClass
1 parent 44c4a27 commit 5ecc0f3

File tree

15 files changed

+259
-203
lines changed

15 files changed

+259
-203
lines changed

documentation/src/main/asciidoc/userguide/chapters/domain/collections.adoc

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
[[collections]]
22
=== Collections
3-
:majorMinorVersion: 6.2
43
:root-project-dir: ../../../../../../..
54
:core-project-dir: {root-project-dir}/hibernate-core
65
:core-test-base: {core-project-dir}/src/test/java
76
:example-dir-collection: {core-test-base}/org/hibernate/orm/test/mapping/collections
87
:docs-base: https://docs.jboss.org/hibernate/orm/{majorMinorVersion}
9-
:javadoc-base: {docs-base}/javadoc
8+
:javadoc-base: {docs-base}/javadocs
109
:java-javadoc-base: https://docs.oracle.com/en/java/javase/11/docs/api/java.base
1110
:extrasdir: extras/collections
1211

@@ -285,7 +284,16 @@ is available to have Hibernate interpret a `List` with no `@OrderColumn` and no
285284

286285

287286
An ID_BAG is similar to a BAG, except that it maps a generated, per-row identifier into the collection
288-
table. `@CollectionId` is the annotation to configure this identifier
287+
table. `@CollectionId` is the annotation to configure this identifier.
288+
289+
For details about defining an id-bad identifier, see the Javadocs for:
290+
291+
* link:{javadoc-base}/org/hibernate/annotations/CollectionId.html[@CollectionId]
292+
* link:{javadoc-base}/org/hibernate/annotations/CollectionIdJavaClass.html[@CollectionIdJavaClass]
293+
* link:{javadoc-base}/org/hibernate/annotations/CollectionIdJavaType.html[@CollectionIdJavaType]
294+
* link:{javadoc-base}/org/hibernate/annotations/CollectionIdJdbcType.html[@CollectionIdJdbcType]
295+
* link:{javadoc-base}/org/hibernate/annotations/CollectionIdJdbcTypeCode.html[@CollectionIdJdbcTypeCode]
296+
* link:{javadoc-base}/org/hibernate/annotations/CollectionIdType.html[@CollectionIdType]
289297

290298

291299
// todo (6.0) - finish

hibernate-core/src/main/java/org/hibernate/annotations/CollectionId.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,14 @@
1616
import static java.lang.annotation.RetentionPolicy.RUNTIME;
1717

1818
/**
19-
* Describe an identifier column for a bag.
19+
* Describe the identifier for an id-bag.
20+
*
21+
* @see CollectionIdJavaClass
22+
* @see CollectionIdJavaType
23+
* @see CollectionIdJdbcType
24+
* @see CollectionIdJdbcTypeCode
25+
* @see CollectionIdMutability
26+
* @see CollectionIdType
2027
*
2128
* @author Emmanuel Bernard
2229
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.annotations;
6+
7+
import org.hibernate.Incubating;
8+
9+
import java.lang.annotation.Retention;
10+
import java.lang.annotation.Target;
11+
12+
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
13+
import static java.lang.annotation.ElementType.FIELD;
14+
import static java.lang.annotation.ElementType.METHOD;
15+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
16+
17+
/**
18+
* Specifies the Java class to use for the {@linkplain CollectionId id} of an id-bag mapping.
19+
* An alternative to {@linkplain CollectionIdJavaType}. E.g.
20+
*
21+
* <pre>
22+
* &#64;Bag
23+
* &#64;CollectionId(generator="increment")
24+
* &#64;CollectionIdJavaClass(Integer.class)
25+
* Collection&lt;Person&gt; authors;
26+
* </pre>
27+
*
28+
* @since 7.1
29+
*
30+
* @author Steve Ebersole
31+
*/
32+
@Incubating
33+
@Target({METHOD, FIELD, ANNOTATION_TYPE})
34+
@Retention(RUNTIME)
35+
public @interface CollectionIdJavaClass {
36+
/**
37+
* The Java class to use as the collection-id.
38+
*/
39+
Class<?> idType();
40+
}

hibernate-core/src/main/java/org/hibernate/annotations/CollectionIdJavaType.java

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
/**
1919
* Form of {@link JavaType} for describing the id of an id-bag mapping.
2020
*
21+
* @see CollectionIdJavaClass
22+
*
2123
* @since 6.0
2224
*/
2325
@Inherited

hibernate-core/src/main/java/org/hibernate/boot/model/internal/BasicValueBinder.java

+15-2
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,21 @@ private void prepareCollectionId(MemberDetails attribute) {
397397
implicitJavaTypeAccess = typeConfiguration -> null;
398398

399399
explicitJavaTypeAccess = typeConfiguration -> {
400-
final CollectionIdJavaType javaTypeAnn =
401-
attribute.locateAnnotationUsage( CollectionIdJavaType.class, getSourceModelContext() );
400+
final CollectionIdJavaClass javaClassAnn = attribute.locateAnnotationUsage(
401+
CollectionIdJavaClass.class,
402+
getSourceModelContext()
403+
);
404+
if ( javaClassAnn != null ) {
405+
return (BasicJavaType<?>) buildingContext
406+
.getBootstrapContext()
407+
.getTypeConfiguration()
408+
.getJavaTypeRegistry()
409+
.getDescriptor( javaClassAnn.idType() );
410+
}
411+
final CollectionIdJavaType javaTypeAnn = attribute.locateAnnotationUsage(
412+
CollectionIdJavaType.class,
413+
getSourceModelContext()
414+
);
402415
if ( javaTypeAnn != null ) {
403416
final Class<? extends BasicJavaType<?>> javaTypeClass = javaTypeAnn.value();
404417
if ( javaTypeClass != null ) {

hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java

+2-51
Original file line numberDiff line numberDiff line change
@@ -17,57 +17,7 @@
1717
import org.hibernate.AssertionFailure;
1818
import org.hibernate.FetchMode;
1919
import org.hibernate.MappingException;
20-
import org.hibernate.annotations.Bag;
21-
import org.hibernate.annotations.Cache;
22-
import org.hibernate.annotations.CacheLayout;
23-
import org.hibernate.annotations.Cascade;
24-
import org.hibernate.annotations.Check;
25-
import org.hibernate.annotations.Checks;
26-
import org.hibernate.annotations.CollectionId;
27-
import org.hibernate.annotations.CollectionIdJavaType;
28-
import org.hibernate.annotations.CollectionIdJdbcType;
29-
import org.hibernate.annotations.CollectionIdJdbcTypeCode;
30-
import org.hibernate.annotations.CollectionType;
31-
import org.hibernate.annotations.Columns;
32-
import org.hibernate.annotations.CompositeType;
33-
import org.hibernate.annotations.Fetch;
34-
import org.hibernate.annotations.FetchProfileOverride;
35-
import org.hibernate.annotations.Filter;
36-
import org.hibernate.annotations.FilterJoinTable;
37-
import org.hibernate.annotations.Formula;
38-
import org.hibernate.annotations.HQLSelect;
39-
import org.hibernate.annotations.Immutable;
40-
import org.hibernate.annotations.LazyGroup;
41-
import org.hibernate.annotations.ListIndexBase;
42-
import org.hibernate.annotations.ListIndexJavaType;
43-
import org.hibernate.annotations.ListIndexJdbcType;
44-
import org.hibernate.annotations.ListIndexJdbcTypeCode;
45-
import org.hibernate.annotations.ManyToAny;
46-
import org.hibernate.annotations.MapKeyJavaType;
47-
import org.hibernate.annotations.MapKeyJdbcType;
48-
import org.hibernate.annotations.MapKeyJdbcTypeCode;
49-
import org.hibernate.annotations.MapKeyMutability;
50-
import org.hibernate.annotations.MapKeyType;
51-
import org.hibernate.annotations.NotFound;
52-
import org.hibernate.annotations.NotFoundAction;
53-
import org.hibernate.annotations.OnDelete;
54-
import org.hibernate.annotations.OnDeleteAction;
55-
import org.hibernate.annotations.OptimisticLock;
56-
import org.hibernate.annotations.Parameter;
57-
import org.hibernate.annotations.QueryCacheLayout;
58-
import org.hibernate.annotations.SQLDelete;
59-
import org.hibernate.annotations.SQLDeleteAll;
60-
import org.hibernate.annotations.SQLInsert;
61-
import org.hibernate.annotations.SQLJoinTableRestriction;
62-
import org.hibernate.annotations.SQLOrder;
63-
import org.hibernate.annotations.SQLRestriction;
64-
import org.hibernate.annotations.SQLSelect;
65-
import org.hibernate.annotations.SQLUpdate;
66-
import org.hibernate.annotations.SoftDelete;
67-
import org.hibernate.annotations.SortComparator;
68-
import org.hibernate.annotations.SortNatural;
69-
import org.hibernate.annotations.SqlFragmentAlias;
70-
import org.hibernate.annotations.Synchronize;
20+
import org.hibernate.annotations.*;
7121
import org.hibernate.boot.model.IdentifierGeneratorDefinition;
7222
import org.hibernate.boot.models.JpaAnnotations;
7323
import org.hibernate.boot.models.annotations.internal.JoinColumnJpaAnnotation;
@@ -1004,6 +954,7 @@ private static CollectionClassification determineCollectionClassification(
1004954
}
1005955

1006956
if ( property.hasDirectAnnotationUsage( CollectionId.class )
957+
|| property.hasDirectAnnotationUsage( CollectionIdJavaClass.class )
1007958
|| property.hasDirectAnnotationUsage( CollectionIdJdbcType.class )
1008959
|| property.hasDirectAnnotationUsage( CollectionIdJdbcTypeCode.class )
1009960
|| property.hasDirectAnnotationUsage( CollectionIdJavaType.class ) ) {

hibernate-core/src/main/java/org/hibernate/boot/models/HibernateAnnotations.java

+4
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ public interface HibernateAnnotations {
114114
CollectionId.class,
115115
CollectionIdAnnotation.class
116116
);
117+
OrmAnnotationDescriptor<CollectionIdJavaClass,CollectionIdJavaClassAnnotation> COLLECTION_ID_JAVA_CLASS = new OrmAnnotationDescriptor<>(
118+
CollectionIdJavaClass.class,
119+
CollectionIdJavaClassAnnotation.class
120+
);
117121
OrmAnnotationDescriptor<CollectionIdJavaType,CollectionIdJavaTypeAnnotation> COLLECTION_ID_JAVA_TYPE = new OrmAnnotationDescriptor<>(
118122
CollectionIdJavaType.class,
119123
CollectionIdJavaTypeAnnotation.class
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.boot.models.annotations.internal;
6+
7+
import org.hibernate.annotations.CollectionIdJavaClass;
8+
import org.hibernate.models.spi.ModelsContext;
9+
10+
import java.lang.annotation.Annotation;
11+
import java.util.Map;
12+
13+
/**
14+
* @author Steve Ebersole
15+
*/
16+
@SuppressWarnings({ "ClassExplicitlyAnnotation", "unused" })
17+
public class CollectionIdJavaClassAnnotation implements CollectionIdJavaClass {
18+
private Class<?> idType;
19+
20+
@Override
21+
public Class<?> idType() {
22+
return idType;
23+
}
24+
25+
public void idType(Class<?> idType) {
26+
this.idType = idType;
27+
}
28+
29+
@Override
30+
public Class<? extends Annotation> annotationType() {
31+
return CollectionIdJavaClass.class;
32+
}
33+
34+
/**
35+
* Used in creating dynamic annotation instances (e.g. from XML)
36+
*/
37+
public CollectionIdJavaClassAnnotation(ModelsContext modelContext) {
38+
}
39+
40+
/**
41+
* Used in creating annotation instances from JDK variant
42+
*/
43+
public CollectionIdJavaClassAnnotation(CollectionIdJavaClass annotation, ModelsContext modelContext) {
44+
this.idType = annotation.idType();
45+
}
46+
47+
/**
48+
* Used in creating annotation instances from Jandex variant
49+
*/
50+
public CollectionIdJavaClassAnnotation(Map<String, Object> attributeValues, ModelsContext modelContext) {
51+
this.idType = (Class<?>) attributeValues.get( "idType" );
52+
}
53+
}

hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlAnnotationHelper.java

+18-51
Original file line numberDiff line numberDiff line change
@@ -76,57 +76,7 @@
7676
import org.hibernate.boot.models.HibernateAnnotations;
7777
import org.hibernate.boot.models.JpaAnnotations;
7878
import org.hibernate.boot.models.XmlAnnotations;
79-
import org.hibernate.boot.models.annotations.internal.AssociationOverrideJpaAnnotation;
80-
import org.hibernate.boot.models.annotations.internal.AssociationOverridesJpaAnnotation;
81-
import org.hibernate.boot.models.annotations.internal.AttributeOverrideJpaAnnotation;
82-
import org.hibernate.boot.models.annotations.internal.AttributeOverridesJpaAnnotation;
83-
import org.hibernate.boot.models.annotations.internal.CascadeAnnotation;
84-
import org.hibernate.boot.models.annotations.internal.CheckConstraintJpaAnnotation;
85-
import org.hibernate.boot.models.annotations.internal.CollectionClassificationXmlAnnotation;
86-
import org.hibernate.boot.models.annotations.internal.CollectionIdAnnotation;
87-
import org.hibernate.boot.models.annotations.internal.CollectionTypeAnnotation;
88-
import org.hibernate.boot.models.annotations.internal.ColumnJpaAnnotation;
89-
import org.hibernate.boot.models.annotations.internal.ColumnTransformerAnnotation;
90-
import org.hibernate.boot.models.annotations.internal.ConvertJpaAnnotation;
91-
import org.hibernate.boot.models.annotations.internal.ConvertsJpaAnnotation;
92-
import org.hibernate.boot.models.annotations.internal.DiscriminatorColumnJpaAnnotation;
93-
import org.hibernate.boot.models.annotations.internal.DiscriminatorFormulaAnnotation;
94-
import org.hibernate.boot.models.annotations.internal.DiscriminatorOptionsAnnotation;
95-
import org.hibernate.boot.models.annotations.internal.DiscriminatorValueJpaAnnotation;
96-
import org.hibernate.boot.models.annotations.internal.EntityJpaAnnotation;
97-
import org.hibernate.boot.models.annotations.internal.EntityListenersJpaAnnotation;
98-
import org.hibernate.boot.models.annotations.internal.EnumeratedJpaAnnotation;
99-
import org.hibernate.boot.models.annotations.internal.FilterAnnotation;
100-
import org.hibernate.boot.models.annotations.internal.FilterJoinTableAnnotation;
101-
import org.hibernate.boot.models.annotations.internal.FilterJoinTablesAnnotation;
102-
import org.hibernate.boot.models.annotations.internal.FiltersAnnotation;
103-
import org.hibernate.boot.models.annotations.internal.GeneratedValueJpaAnnotation;
104-
import org.hibernate.boot.models.annotations.internal.GenericGeneratorAnnotation;
105-
import org.hibernate.boot.models.annotations.internal.IdClassJpaAnnotation;
106-
import org.hibernate.boot.models.annotations.internal.IndexJpaAnnotation;
107-
import org.hibernate.boot.models.annotations.internal.InheritanceJpaAnnotation;
108-
import org.hibernate.boot.models.annotations.internal.JavaTypeAnnotation;
109-
import org.hibernate.boot.models.annotations.internal.JdbcTypeAnnotation;
110-
import org.hibernate.boot.models.annotations.internal.JdbcTypeCodeAnnotation;
111-
import org.hibernate.boot.models.annotations.internal.NaturalIdCacheAnnotation;
112-
import org.hibernate.boot.models.annotations.internal.NotFoundAnnotation;
113-
import org.hibernate.boot.models.annotations.internal.ParameterAnnotation;
114-
import org.hibernate.boot.models.annotations.internal.PrimaryKeyJoinColumnJpaAnnotation;
115-
import org.hibernate.boot.models.annotations.internal.PrimaryKeyJoinColumnsJpaAnnotation;
116-
import org.hibernate.boot.models.annotations.internal.RowIdAnnotation;
117-
import org.hibernate.boot.models.annotations.internal.SQLJoinTableRestrictionAnnotation;
118-
import org.hibernate.boot.models.annotations.internal.SQLRestrictionAnnotation;
119-
import org.hibernate.boot.models.annotations.internal.SecondaryRowAnnotation;
120-
import org.hibernate.boot.models.annotations.internal.SecondaryRowsAnnotation;
121-
import org.hibernate.boot.models.annotations.internal.SecondaryTableJpaAnnotation;
122-
import org.hibernate.boot.models.annotations.internal.SecondaryTablesJpaAnnotation;
123-
import org.hibernate.boot.models.annotations.internal.SequenceGeneratorJpaAnnotation;
124-
import org.hibernate.boot.models.annotations.internal.TableGeneratorJpaAnnotation;
125-
import org.hibernate.boot.models.annotations.internal.TableJpaAnnotation;
126-
import org.hibernate.boot.models.annotations.internal.TargetXmlAnnotation;
127-
import org.hibernate.boot.models.annotations.internal.TemporalJpaAnnotation;
128-
import org.hibernate.boot.models.annotations.internal.UniqueConstraintJpaAnnotation;
129-
import org.hibernate.boot.models.annotations.internal.UuidGeneratorAnnotation;
79+
import org.hibernate.boot.models.annotations.internal.*;
13080
import org.hibernate.boot.models.annotations.spi.CustomSqlDetails;
13181
import org.hibernate.boot.models.annotations.spi.DatabaseObjectDetails;
13282
import org.hibernate.boot.models.JpaEventListenerStyle;
@@ -401,6 +351,23 @@ public static void applyCollectionId(
401351
if ( generator != null && isNotEmpty( generator.getGenerator() ) ) {
402352
collectionIdAnn.generator( generator.getGenerator() );
403353
}
354+
355+
if ( StringHelper.isNotEmpty( jaxbCollectionId.getTarget() ) ) {
356+
final SimpleTypeInterpretation simpleTypeInterpretation = SimpleTypeInterpretation.interpret(
357+
jaxbCollectionId.getTarget()
358+
);
359+
assert simpleTypeInterpretation != null;
360+
361+
final CollectionIdJavaClassAnnotation annotationUsage = (CollectionIdJavaClassAnnotation) memberDetails.applyAnnotationUsage(
362+
HibernateAnnotations.COLLECTION_ID_JAVA_CLASS,
363+
xmlDocumentContext.getModelBuildingContext()
364+
);
365+
annotationUsage.idType( simpleTypeInterpretation.getJavaType() );
366+
}
367+
else {
368+
// this will likely lead to an error later.
369+
// should we throw an exception here?
370+
}
404371
}
405372

406373
public static void applyCascading(

hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/attr/CommonPluralAttributeProcessing.java

+4-12
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralFetchModeImpl;
1212
import org.hibernate.boot.models.HibernateAnnotations;
1313
import org.hibernate.boot.models.JpaAnnotations;
14-
import org.hibernate.boot.models.XmlAnnotations;
15-
import org.hibernate.boot.models.annotations.internal.CollectionClassificationXmlAnnotation;
1614
import org.hibernate.boot.models.annotations.internal.FetchAnnotation;
1715
import org.hibernate.boot.models.annotations.internal.MapKeyClassJpaAnnotation;
1816
import org.hibernate.boot.models.annotations.internal.MapKeyColumnJpaAnnotation;
@@ -56,11 +54,11 @@ public static void applyPluralAttributeStructure(
5654
memberDetails.applyAnnotationUsage( HibernateAnnotations.BAG, buildingContext );
5755
}
5856
else {
59-
final CollectionClassificationXmlAnnotation collectionClassificationAnn = (CollectionClassificationXmlAnnotation) memberDetails.applyAnnotationUsage(
60-
XmlAnnotations.COLLECTION_CLASSIFICATION,
61-
buildingContext
57+
XmlAnnotationHelper.applyCollectionClassification(
58+
jaxbPluralAttribute.getClassification(),
59+
memberDetails,
60+
xmlDocumentContext
6261
);
63-
collectionClassificationAnn.value( jaxbPluralAttribute.getClassification() );
6462
}
6563
}
6664

@@ -71,12 +69,6 @@ public static void applyPluralAttributeStructure(
7169

7270
XmlAnnotationHelper.applyCollectionId( jaxbPluralAttribute.getCollectionId(), memberDetails, xmlDocumentContext );
7371

74-
XmlAnnotationHelper.applyCollectionClassification(
75-
jaxbPluralAttribute.getClassification(),
76-
memberDetails,
77-
xmlDocumentContext
78-
);
79-
8072
if ( StringHelper.isNotEmpty( jaxbPluralAttribute.getOrderBy() ) ) {
8173
final OrderByJpaAnnotation orderByAnn = (OrderByJpaAnnotation) memberDetails.applyAnnotationUsage(
8274
JpaAnnotations.ORDER_BY,

0 commit comments

Comments
 (0)