fix the misleading documentation of the @Bag annotation

and improve error reporting when used in a nonsensical way
This commit is contained in:
Gavin 2022-12-31 17:06:07 +01:00
parent a1d52b0bb1
commit 60e5b75282
5 changed files with 34 additions and 12 deletions

View File

@ -9,21 +9,25 @@ package org.hibernate.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import org.hibernate.cfg.AvailableSettings;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Can be used to map a {@link java.util.List}-valued attribute using
* {@link org.hibernate.metamodel.CollectionClassification#BAG} semantics.
* Specifies that an attribute of type {@link java.util.List} is semantically
* a {@linkplain org.hibernate.metamodel.CollectionClassification#BAG bag},
* that is, that the order of the list elements is not significant, and should
* not be persistent.
* <p>
* @apiNote Ignored if either {@link jakarta.persistence.OrderColumn} or
* {@link ListIndexBase} is used.
* This annotation is not necessary, and has no effect, unless the configuration
* property {@value org.hibernate.cfg.AvailableSettings#DEFAULT_LIST_SEMANTICS}
* is set to {@link org.hibernate.metamodel.CollectionClassification#LIST}.
* However, its use is still encouraged, since the explicit annotation serves
* as useful documentation.
*
* @implSpec May also be specified SessionFactory-wide using {@value AvailableSettings#DEFAULT_LIST_SEMANTICS}
* @apiNote This annotation causes an exception if the attribute is also annotated
* {@link jakarta.persistence.OrderColumn} or {@link ListIndexBase}.
*
* @author Steve Ebersole
*/

View File

@ -60,7 +60,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
public @interface Type {
/**
* The implementation class which implements {@link UserType}.
* The class which implements {@link UserType}.
*/
Class<? extends UserType<?>> value();

View File

@ -987,16 +987,26 @@ public abstract class CollectionBinder {
return determineCollectionClassification( determineSemanticJavaType( property ), property, buildingContext );
}
else {
if ( property.isAnnotationPresent( OrderColumn.class ) ) {
throw new AnnotationException( "Attribute '"
+ qualify( property.getDeclaringClass().getName(), property.getName() )
+ "' is annotated '@Bag' and may not also be annotated '@OrderColumn'" );
}
if ( property.isAnnotationPresent( ListIndexBase.class ) ) {
throw new AnnotationException( "Attribute '"
+ qualify( property.getDeclaringClass().getName(), property.getName() )
+ "' is annotated '@Bag' and may not also be annotated '@ListIndexBase'" );
}
final Class<?> collectionJavaType = property.getCollectionClass();
if ( java.util.List.class.equals( collectionJavaType )
|| java.util.Collection.class.equals( collectionJavaType ) ) {
return CollectionClassification.BAG;
}
else {
throw new MappingException(
throw new AnnotationException(
String.format(
Locale.ROOT,
"@Bag annotation encountered on an attribute `%s#%s` of type `%s`; only `%s` and `%s` are supported",
"Attribute '%s.%s' of type '%s' is annotated '@Bag' (bags are of type '%s' or '%s')",
property.getDeclaringClass().getName(),
property.getName(),
collectionJavaType.getName(),

View File

@ -17,9 +17,9 @@ import org.hibernate.boot.MetadataSources;
*/
public interface MetadataSourcesContributor {
/**
* Perform the process of contributing to MetadataSources.
* Perform the process of contributing to the {@link MetadataSources}.
*
* @param metadataSources The MetadataSources, to which to contribute.
* @param metadataSources The {@code MetadataSource}s, to which to contribute.
*/
void contribute(MetadataSources metadataSources);
}

View File

@ -929,8 +929,16 @@ public interface AvailableSettings {
* <li>the (case insensitive) name of a {@code CollectionClassification} (list e.g.)
* <li>a {@link Class} representing either {@link java.util.List} or {@link java.util.Collection}
* </ul>
* <p>
* By default, when this property is not set, an attribute of type {@code List}
* is taken to have the semantics of a
* {@linkplain org.hibernate.metamodel.CollectionClassification#BAG bag} unless
* it is annotated {@link jakarta.persistence.OrderColumn} or
* {@link org.hibernate.annotations.ListIndexBase}.
*
* @since 6.0
*
* @see org.hibernate.annotations.Bag
*/
String DEFAULT_LIST_SEMANTICS = "hibernate.mapping.default_list_semantics";