mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-10 05:04:52 +00:00
HHH-15733 Change convert logic to default to value for Map collections of basic types
This commit is contained in:
parent
1bb6fcfe1c
commit
f4e95d96c6
@ -2131,15 +2131,17 @@ private void handleElementCollection(XClass elementType, String hqlOrderBy) {
|
|||||||
propertyHolder,
|
propertyHolder,
|
||||||
buildingContext
|
buildingContext
|
||||||
);
|
);
|
||||||
holder.prepare( property );
|
|
||||||
|
|
||||||
final Class<? extends CompositeUserType<?>> compositeUserType =
|
final Class<? extends CompositeUserType<?>> compositeUserType =
|
||||||
resolveCompositeUserType( property, elementClass, buildingContext );
|
resolveCompositeUserType( property, elementClass, buildingContext );
|
||||||
if ( classType == EMBEDDABLE || compositeUserType != null ) {
|
boolean isComposite = classType == EMBEDDABLE || compositeUserType != null;
|
||||||
|
holder.prepare( property, isComposite );
|
||||||
|
|
||||||
|
if ( isComposite ) {
|
||||||
handleCompositeCollectionElement( hqlOrderBy, elementClass, holder, compositeUserType );
|
handleCompositeCollectionElement( hqlOrderBy, elementClass, holder, compositeUserType );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
handleCollectionElement( elementType, hqlOrderBy, elementClass, holder );
|
handleCollectionElement( elementType, hqlOrderBy, elementClass, holder );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@ public Collection getCollectionBinding() {
|
|||||||
|
|
||||||
private void buildAttributeConversionInfoMaps(
|
private void buildAttributeConversionInfoMaps(
|
||||||
XProperty collectionProperty,
|
XProperty collectionProperty,
|
||||||
|
boolean isComposite,
|
||||||
Map<String,AttributeConversionInfo> elementAttributeConversionInfoMap,
|
Map<String,AttributeConversionInfo> elementAttributeConversionInfoMap,
|
||||||
Map<String,AttributeConversionInfo> keyAttributeConversionInfoMap) {
|
Map<String,AttributeConversionInfo> keyAttributeConversionInfoMap) {
|
||||||
if ( collectionProperty == null ) {
|
if ( collectionProperty == null ) {
|
||||||
@ -88,7 +89,13 @@ private void buildAttributeConversionInfoMaps(
|
|||||||
{
|
{
|
||||||
final Convert convertAnnotation = collectionProperty.getAnnotation( Convert.class );
|
final Convert convertAnnotation = collectionProperty.getAnnotation( Convert.class );
|
||||||
if ( convertAnnotation != null ) {
|
if ( convertAnnotation != null ) {
|
||||||
applyLocalConvert( convertAnnotation, collectionProperty, elementAttributeConversionInfoMap, keyAttributeConversionInfoMap );
|
applyLocalConvert(
|
||||||
|
convertAnnotation,
|
||||||
|
collectionProperty,
|
||||||
|
isComposite,
|
||||||
|
elementAttributeConversionInfoMap,
|
||||||
|
keyAttributeConversionInfoMap
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,6 +106,7 @@ private void buildAttributeConversionInfoMaps(
|
|||||||
applyLocalConvert(
|
applyLocalConvert(
|
||||||
convertAnnotation,
|
convertAnnotation,
|
||||||
collectionProperty,
|
collectionProperty,
|
||||||
|
isComposite,
|
||||||
elementAttributeConversionInfoMap,
|
elementAttributeConversionInfoMap,
|
||||||
keyAttributeConversionInfoMap
|
keyAttributeConversionInfoMap
|
||||||
);
|
);
|
||||||
@ -110,14 +118,15 @@ private void buildAttributeConversionInfoMaps(
|
|||||||
private void applyLocalConvert(
|
private void applyLocalConvert(
|
||||||
Convert convertAnnotation,
|
Convert convertAnnotation,
|
||||||
XProperty collectionProperty,
|
XProperty collectionProperty,
|
||||||
|
boolean isComposite,
|
||||||
Map<String,AttributeConversionInfo> elementAttributeConversionInfoMap,
|
Map<String,AttributeConversionInfo> elementAttributeConversionInfoMap,
|
||||||
Map<String,AttributeConversionInfo> keyAttributeConversionInfoMap) {
|
Map<String,AttributeConversionInfo> keyAttributeConversionInfoMap) {
|
||||||
|
|
||||||
// IMPL NOTE : the rules here are quite more lenient than what JPA says. For example, JPA says
|
// IMPL NOTE : the rules here are quite more lenient than what JPA says. For example, JPA says that @Convert
|
||||||
// that @Convert on a Map always needs to specify attributeName of key/value (or prefixed with
|
// on a Map of basic types should default to "value" but it should explicitly specify attributeName of "key"
|
||||||
// key./value. for embedded paths). However, we try to see if conversion of either is disabled
|
// (or prefixed with "key." for embedded paths) to be applied on the key. However, we try to see if conversion
|
||||||
// for whatever reason. For example, if the Map is annotated with @Enumerated the elements cannot
|
// of either is disabled for whatever reason. For example, if the Map is annotated with @Enumerated the
|
||||||
// be converted so any @Convert likely meant the key, so we apply it to the key
|
// elements cannot be converted so any @Convert likely meant the key, so we apply it to the key
|
||||||
|
|
||||||
final AttributeConversionInfo info = new AttributeConversionInfo( convertAnnotation, collectionProperty );
|
final AttributeConversionInfo info = new AttributeConversionInfo( convertAnnotation, collectionProperty );
|
||||||
if ( collection.isMap() ) {
|
if ( collection.isMap() ) {
|
||||||
@ -132,10 +141,15 @@ private void applyLocalConvert(
|
|||||||
if ( isEmpty( info.getAttributeName() ) ) {
|
if ( isEmpty( info.getAttributeName() ) ) {
|
||||||
// the @Convert did not name an attribute...
|
// the @Convert did not name an attribute...
|
||||||
if ( canElementBeConverted && canKeyBeConverted ) {
|
if ( canElementBeConverted && canKeyBeConverted ) {
|
||||||
throw new IllegalStateException(
|
if ( !isComposite ) {
|
||||||
"@Convert placed on Map attribute [" + collection.getRole()
|
// if element is of basic type default to "value"
|
||||||
+ "] must define attributeName of 'key' or 'value'"
|
elementAttributeConversionInfoMap.put( "", info );
|
||||||
);
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"@Convert placed on Map attribute [" + collection.getRole()
|
||||||
|
+ "] of non-basic types must define attributeName of 'key' or 'value'" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ( canKeyBeConverted ) {
|
else if ( canKeyBeConverted ) {
|
||||||
keyAttributeConversionInfoMap.put( "", info );
|
keyAttributeConversionInfoMap.put( "", info );
|
||||||
@ -325,7 +339,7 @@ public String toString() {
|
|||||||
|
|
||||||
boolean prepared;
|
boolean prepared;
|
||||||
|
|
||||||
public void prepare(XProperty collectionProperty) {
|
public void prepare(XProperty collectionProperty, boolean isComposite) {
|
||||||
// fugly
|
// fugly
|
||||||
if ( prepared ) {
|
if ( prepared ) {
|
||||||
return;
|
return;
|
||||||
@ -377,7 +391,12 @@ else if ( collectionProperty.isAnnotationPresent( CollectionType.class ) ) {
|
|||||||
// Is it valid to reference a collection attribute in a @Convert attached to the owner (entity) by path?
|
// Is it valid to reference a collection attribute in a @Convert attached to the owner (entity) by path?
|
||||||
// if so we should pass in 'clazzToProcess' also
|
// if so we should pass in 'clazzToProcess' also
|
||||||
if ( canKeyBeConverted || canElementBeConverted ) {
|
if ( canKeyBeConverted || canElementBeConverted ) {
|
||||||
buildAttributeConversionInfoMaps( collectionProperty, elementAttributeConversionInfoMap, keyAttributeConversionInfoMap );
|
buildAttributeConversionInfoMaps(
|
||||||
|
collectionProperty,
|
||||||
|
isComposite,
|
||||||
|
elementAttributeConversionInfoMap,
|
||||||
|
keyAttributeConversionInfoMap
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
import org.hibernate.mapping.Value;
|
import org.hibernate.mapping.Value;
|
||||||
import org.hibernate.resource.beans.spi.ManagedBean;
|
import org.hibernate.resource.beans.spi.ManagedBean;
|
||||||
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.usertype.CompositeUserType;
|
import org.hibernate.usertype.CompositeUserType;
|
||||||
import org.hibernate.usertype.UserCollectionType;
|
import org.hibernate.usertype.UserCollectionType;
|
||||||
|
|
||||||
@ -278,7 +279,7 @@ private CollectionPropertyHolder buildCollectionPropertyHolder(
|
|||||||
// 'holder' is the CollectionPropertyHolder.
|
// 'holder' is the CollectionPropertyHolder.
|
||||||
// 'property' is the collection XProperty
|
// 'property' is the collection XProperty
|
||||||
propertyHolder.startingProperty( property );
|
propertyHolder.startingProperty( property );
|
||||||
holder.prepare(property);
|
holder.prepare( property, !( collection.getKey().getType() instanceof BasicType ) );
|
||||||
return holder;
|
return holder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,16 +67,9 @@ public static class Customer {
|
|||||||
private Integer id;
|
private Integer id;
|
||||||
|
|
||||||
@ElementCollection(fetch = FetchType.EAGER)
|
@ElementCollection(fetch = FetchType.EAGER)
|
||||||
@Convert(converter = MyStringConverter.class)
|
@Convert(converter = MyStringConverter.class) // note omitted attributeName
|
||||||
private final Map<String, String> colors = new HashMap<>();
|
private final Map<String, String> colors = new HashMap<>();
|
||||||
|
|
||||||
public Customer() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer(Integer id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getColors() {
|
public Map<String, String> getColors() {
|
||||||
return colors;
|
return colors;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user