HHH-8630 - random map key column generated when using @AttributeOverrides and @ElementCollection

This commit is contained in:
Steve Ebersole 2016-08-30 18:41:25 -05:00
parent 19834a0046
commit d5cbd8fdf0
4 changed files with 126 additions and 6 deletions

View File

@ -13,6 +13,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.persistence.AttributeConverter; import javax.persistence.AttributeConverter;
import javax.persistence.Converter; import javax.persistence.Converter;
import javax.persistence.Embeddable;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.MappedSuperclass; import javax.persistence.MappedSuperclass;
@ -120,6 +121,9 @@ public class AnnotationMetadataSourceProcessorImpl implements MetadataSourceProc
|| xClass.isAnnotationPresent( MappedSuperclass.class ) ) { || xClass.isAnnotationPresent( MappedSuperclass.class ) ) {
xClasses.add( xClass ); xClasses.add( xClass );
} }
else if ( xClass.isAnnotationPresent( Embeddable.class ) ) {
xClasses.add( xClass );
}
else { else {
log.debugf( "Encountered a non-categorized annotated class [%s]; ignoring", annotatedClass.getName() ); log.debugf( "Encountered a non-categorized annotated class [%s]; ignoring", annotatedClass.getName() );
} }

View File

@ -182,10 +182,8 @@ public class MapBinder extends CollectionBinder {
throw new AnnotationException( "Unable to find class: " + mapKeyType, e ); throw new AnnotationException( "Unable to find class: " + mapKeyType, e );
} }
classType = buildingContext.getMetadataCollector().getClassType( keyXClass ); classType = buildingContext.getMetadataCollector().getClassType( keyXClass );
//force in case of attribute override // force in case of attribute override naming the key
boolean attributeOverride = property.isAnnotationPresent( AttributeOverride.class ) if ( isEmbedded || mappingDefinedAttributeOverrideOnMapKey( property ) ) {
|| property.isAnnotationPresent( AttributeOverrides.class );
if ( isEmbedded || attributeOverride ) {
classType = AnnotatedClassType.EMBEDDABLE; classType = AnnotatedClassType.EMBEDDABLE;
} }
} }
@ -308,6 +306,27 @@ public class MapBinder extends CollectionBinder {
} }
} }
private boolean mappingDefinedAttributeOverrideOnMapKey(XProperty property) {
if ( property.isAnnotationPresent( AttributeOverride.class ) ) {
return namedMapKey( property.getAnnotation( AttributeOverride.class ) );
}
if ( property.isAnnotationPresent( AttributeOverrides.class ) ) {
final AttributeOverrides annotations = property.getAnnotation( AttributeOverrides.class );
for ( AttributeOverride attributeOverride : annotations.value() ) {
if ( namedMapKey( attributeOverride ) ) {
return true;
}
}
}
return false;
}
private boolean namedMapKey(AttributeOverride annotation) {
return annotation.name().startsWith( "key." );
}
protected Value createFormulatedValue( protected Value createFormulatedValue(
Value value, Value value,
Collection collection, Collection collection,

View File

@ -136,10 +136,10 @@ public final class EventType<T> {
} }
private final String eventName; private final String eventName;
private final Class<? extends T> baseListenerInterface; private final Class<T> baseListenerInterface;
private final int ordinal; private final int ordinal;
private EventType(String eventName, Class<? extends T> baseListenerInterface) { private EventType(String eventName, Class<T> baseListenerInterface) {
this.eventName = eventName; this.eventName = eventName;
this.baseListenerInterface = baseListenerInterface; this.baseListenerInterface = baseListenerInterface;
this.ordinal = typeCounter.getAndIncrement(); this.ordinal = typeCounter.getAndIncrement();

View File

@ -0,0 +1,97 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.test.annotations.embeddables.attributeOverrides;
import java.util.Map;
import java.util.UUID;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.MapKeyColumn;
import javax.persistence.Table;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.BasicType;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
import static org.junit.Assert.assertTrue;
/**
* @author Steve Ebersole
*/
public class BasicAttributeOverrideTest extends BaseNonConfigCoreFunctionalTestCase {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { TypeValue.class, AggregatedTypeValue.class };
}
@Test
@TestForIssue( jiraKey = "HHH-8630" )
public void testIt() {
final PersistentClass entityBinding = metadata().getEntityBinding( AggregatedTypeValue.class.getName() );
final Property attributesBinding = entityBinding.getProperty( "attributes" );
final org.hibernate.mapping.Map attributesMap = (org.hibernate.mapping.Map) attributesBinding.getValue();
final SimpleValue mapKey = assertTyping( SimpleValue.class, attributesMap.getIndex() );
final BasicType mapKeyType = assertTyping( BasicType.class, mapKey.getType() );
assertTrue( String.class.equals( mapKeyType.getReturnedClass() ) );
// let's also make sure the @MapKeyColumn got applied
assertThat( mapKey.getColumnSpan(), is(1) );
final org.hibernate.mapping.Column mapKeyColumn = assertTyping( org.hibernate.mapping.Column .class, mapKey.getColumnIterator().next() );
assertThat( mapKeyColumn.getName(), equalTo( "attribute_name" ) );
}
@Embeddable
public static class TypeValue {
String type;
@Column(columnDefinition = "TEXT")
String value;
}
@Entity
@Table( name = "AGG_TYPE" )
public static class AggregatedTypeValue {
@Id
UUID id;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "type", column = @Column(name = "content_type")),
@AttributeOverride(name = "value", column = @Column(name = "content_value"))
})
TypeValue content;
@CollectionTable( name = "ATTRIBUTES" )
@ElementCollection(fetch = FetchType.EAGER)
@MapKeyColumn(name = "attribute_name")
@AttributeOverrides({
@AttributeOverride(name = "value.type", column = @Column(name = "attribute_type")),
@AttributeOverride(name = "value.value", column = @Column(name = "attribute_value"))
})
Map<String, TypeValue> attributes;
}
}