HHH-18516 - Ignore @AttributeOverride for map key when checking type of map value
This commit is contained in:
parent
d39ba13ee4
commit
ad6f326090
|
@ -2356,8 +2356,7 @@ public abstract class CollectionBinder {
|
|||
}
|
||||
else {
|
||||
//force in case of attribute override
|
||||
final boolean attributeOverride = property.hasDirectAnnotationUsage( AttributeOverride.class )
|
||||
|| property.hasDirectAnnotationUsage( AttributeOverrides.class );
|
||||
final boolean attributeOverride = mappingDefinedAttributeOverrideOnElement(property);
|
||||
// todo : force in the case of Convert annotation(s) with embedded paths (beyond key/value prefixes)?
|
||||
return isEmbedded || attributeOverride
|
||||
? EMBEDDABLE
|
||||
|
@ -2365,6 +2364,11 @@ public abstract class CollectionBinder {
|
|||
}
|
||||
}
|
||||
|
||||
protected boolean mappingDefinedAttributeOverrideOnElement(MemberDetails property) {
|
||||
return property.hasDirectAnnotationUsage( AttributeOverride.class )
|
||||
|| property.hasDirectAnnotationUsage( AttributeOverrides.class );
|
||||
}
|
||||
|
||||
static AnnotatedColumns createElementColumnsIfNecessary(
|
||||
Collection collection,
|
||||
AnnotatedColumns elementColumns,
|
||||
|
|
|
@ -109,6 +109,26 @@ public class MapBinder extends CollectionBinder {
|
|||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mappingDefinedAttributeOverrideOnElement(MemberDetails property) {
|
||||
if ( property.hasDirectAnnotationUsage( AttributeOverride.class ) ) {
|
||||
return namedMapValue( property.getDirectAnnotationUsage( AttributeOverride.class ) );
|
||||
}
|
||||
if ( property.hasDirectAnnotationUsage( AttributeOverrides.class ) ) {
|
||||
final AttributeOverrides annotations = property.getDirectAnnotationUsage( AttributeOverrides.class );
|
||||
for ( AttributeOverride attributeOverride : annotations.value() ) {
|
||||
if ( namedMapValue( attributeOverride ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean namedMapValue(AttributeOverride annotation) {
|
||||
return annotation.name().startsWith( "value." );
|
||||
}
|
||||
|
||||
private void makeOneToManyMapKeyColumnNullableIfNotInProperty(MemberDetails property) {
|
||||
final Map map = (Map) this.collection;
|
||||
if ( map.isOneToMany() && property.hasDirectAnnotationUsage( MapKeyColumn.class ) ) {
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package org.hibernate.orm.test.annotations.attributeoverride;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.metamodel.EntityType;
|
||||
import jakarta.persistence.metamodel.MapAttribute;
|
||||
|
||||
import static jakarta.persistence.metamodel.Type.PersistenceType.BASIC;
|
||||
import static jakarta.persistence.metamodel.Type.PersistenceType.EMBEDDABLE;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
Schedule.class,
|
||||
Route.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
class MapAttributeOverrideTest {
|
||||
|
||||
@Test
|
||||
@JiraKey("HHH-18516")
|
||||
void testMapOfEmbeddableKeysWithAttributeOverridesAndBasicValues(SessionFactoryScope sessionFactoryScope) {
|
||||
sessionFactoryScope.inTransaction(session -> {
|
||||
EntityType<Schedule> scheduleType = session.getMetamodel().entity(Schedule.class);
|
||||
MapAttribute<? super Schedule, ?, ?> departuresMapAttribute = scheduleType.getMap("departures");
|
||||
// Presence of @AttributeOverride-s for the key should only affect the type of the key, but not the type of the value
|
||||
assertThat(departuresMapAttribute.getKeyType().getPersistenceType()).isEqualTo(EMBEDDABLE);
|
||||
assertThat(departuresMapAttribute.getElementType().getPersistenceType()).isEqualTo(BASIC);
|
||||
|
||||
session.persist(new Schedule(Map.of(
|
||||
new Route("Hamburg", "Vienna"), LocalTime.NOON,
|
||||
new Route("Warsaw", "Barcelona"), LocalTime.MIDNIGHT
|
||||
)));
|
||||
assertThat(session.createQuery("FROM Schedule s", Schedule.class).getResultCount()).isOne();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package org.hibernate.orm.test.annotations.attributeoverride;
|
||||
|
||||
import jakarta.persistence.Embeddable;
|
||||
|
||||
@Embeddable
|
||||
public class Route {
|
||||
|
||||
private String origin;
|
||||
private String destination;
|
||||
|
||||
public Route() {
|
||||
}
|
||||
|
||||
public Route(String origin, String destination) {
|
||||
this.origin = origin;
|
||||
this.destination = destination;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.hibernate.orm.test.annotations.attributeoverride;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.persistence.AttributeOverride;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Schedule {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
@ElementCollection
|
||||
@Column(name = "time")
|
||||
@AttributeOverride(name = "key.origin", column = @Column(name = "orig"))
|
||||
@AttributeOverride(name = "key.destination", column = @Column(name = "dest"))
|
||||
private Map<Route, LocalTime> departures;
|
||||
|
||||
public Schedule() {
|
||||
}
|
||||
|
||||
public Schedule(Map<Route, LocalTime> departures) {
|
||||
this.departures = departures;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue