From ed9b1af83f067ca44beea6de132c75d518e25b8a Mon Sep 17 00:00:00 2001 From: Dimitris Mandalidis Date: Tue, 29 Apr 2014 20:44:01 +0300 Subject: [PATCH] HHH-8885 MapJoin.key() produces unusable Path object --- .../jpa/criteria/path/MapKeyHelpers.java | 22 +++++++++ .../test/criteria/mapjoin/MapJoinTest.java | 45 +++++++++++++++++++ .../jpa/test/metamodel/MapEntity.java | 35 +++++++++++++++ .../jpa/test/metamodel/MapEntityLocal.java | 19 ++++++++ 4 files changed, 121 insertions(+) create mode 100644 hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/mapjoin/MapJoinTest.java create mode 100644 hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/metamodel/MapEntity.java create mode 100644 hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/metamodel/MapEntityLocal.java diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/path/MapKeyHelpers.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/path/MapKeyHelpers.java index fcf4860458..88a6009e9f 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/path/MapKeyHelpers.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/path/MapKeyHelpers.java @@ -36,8 +36,10 @@ import javax.persistence.metamodel.SingularAttribute; import javax.persistence.metamodel.Type; +import org.hibernate.jpa.criteria.compile.RenderingContext; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.jpa.criteria.CriteriaBuilderImpl; +import org.hibernate.jpa.criteria.PathSource; import org.hibernate.jpa.criteria.MapJoinImplementor; import org.hibernate.jpa.criteria.PathImplementor; import org.hibernate.persister.collection.CollectionPersister; @@ -109,6 +111,20 @@ public MapKeyPath treatAs(Class treatAsType) { // todo : if key is an entity, this is probably not enough return (MapKeyPath) this; } + + @Override + public String render(RenderingContext renderingContext) { + PathSource source = getPathSource(); + String name; + if ( source != null ) { + source.prepareAlias( renderingContext ); + name = source.getPathIdentifier(); + } + else { + name = getAttribute().getName(); + } + return "key(" + name + ")"; + } } /** @@ -164,6 +180,12 @@ protected Attribute locateAttributeInternal(String attributeName) { public > PathImplementor treatAs(Class treatAsType) { throw new UnsupportedOperationException(); } + + @Override + public String getPathIdentifier() { + return mapJoin.getPathIdentifier(); + } + } /** diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/mapjoin/MapJoinTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/mapjoin/MapJoinTest.java new file mode 100644 index 0000000000..b34e0a365b --- /dev/null +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/mapjoin/MapJoinTest.java @@ -0,0 +1,45 @@ +package org.hibernate.jpa.test.criteria.mapjoin; + +import javax.persistence.EntityManager; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.MapJoin; +import javax.persistence.criteria.Root; + +import org.hibernate.jpa.test.metamodel.AbstractMetamodelSpecificTest; +import org.hibernate.jpa.test.metamodel.MapEntity; +import org.hibernate.jpa.test.metamodel.MapEntityLocal; +import org.hibernate.jpa.test.metamodel.MapEntityLocal_; +import org.hibernate.jpa.test.metamodel.MapEntity_; +import org.junit.Test; + +public class MapJoinTest extends AbstractMetamodelSpecificTest { + + @Override + public Class[] getAnnotatedClasses() { + return new Class[] { MapEntity.class, MapEntityLocal.class }; + } + @Test + public void allEntities() { + EntityManager em = getOrCreateEntityManager(); + em.getTransaction().begin(); + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(MapEntity.class); + + Root entity = query.from(MapEntity.class); + MapJoin cname = entity.join(MapEntity_.localized); + + query = query + .select(entity) + .where( + cb.equal( cname.key(), "en" ) + ) + .orderBy( cb.asc( cb.upper( cname.value().get(MapEntityLocal_.shortName) ) ) ); + + em.createQuery(query).getResultList(); + + em.getTransaction().commit(); + em.close(); + } +} diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/metamodel/MapEntity.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/metamodel/MapEntity.java new file mode 100644 index 0000000000..8ec1ece5a3 --- /dev/null +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/metamodel/MapEntity.java @@ -0,0 +1,35 @@ +package org.hibernate.jpa.test.metamodel; + +import java.util.Map; + +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.MapKeyColumn; +import javax.persistence.Table; + +@Entity +@Table( name = "MAP_ENTITY" ) +public class MapEntity { + + @Id + @Column(name="key_") + private String key; + + @ElementCollection(fetch=FetchType.LAZY) + @CollectionTable(name="MAP_ENTITY_NAME", joinColumns=@JoinColumn(name="key_")) + @MapKeyColumn(name="lang_") + private Map localized; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } +} diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/metamodel/MapEntityLocal.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/metamodel/MapEntityLocal.java new file mode 100644 index 0000000000..2972beea5e --- /dev/null +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/metamodel/MapEntityLocal.java @@ -0,0 +1,19 @@ +package org.hibernate.jpa.test.metamodel; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +@Embeddable +public class MapEntityLocal { + + @Column(name="short_name") + private String shortName; + + public String getShortName() { + return shortName; + } + + public void setShortName(String shortName) { + this.shortName = shortName; + } +}