6 - SQM based on JPA type system

This commit is contained in:
Steve Ebersole 2019-05-23 09:17:16 -05:00 committed by Andrea Boriero
parent af2c32e32c
commit f4126082da
58 changed files with 1972 additions and 306 deletions

View File

@ -8,10 +8,18 @@ package org.hibernate;
import javax.persistence.metamodel.EntityType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
/**
* @author Steve Ebersole
*
* @deprecated (since 6.0) Access to JPA's type system and Hibernate's type
* system has been separated into {@link JpaMetamodel}
* and {@link org.hibernate.metamodel.spi.RuntimeModel} respectively.
*/
public interface Metamodel extends javax.persistence.metamodel.Metamodel {
@Deprecated
public interface Metamodel extends JpaMetamodel {
/**
* Access to the SessionFactory that this Metamodel instance is bound to.
*
@ -34,7 +42,7 @@ public interface Metamodel extends javax.persistence.metamodel.Metamodel {
*
* @return The entity descriptor
*/
<X> EntityType<X> entity(String entityName);
<X> EntityDomainType<X> entity(String entityName);
String getImportedClassName(String className);

View File

@ -0,0 +1,52 @@
/*
* 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.collection.internal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Consumer;
import org.hibernate.collection.spi.CollectionSemantics;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.persister.collection.CollectionPersister;
/**
* @author Steve Ebersole
*/
public abstract class AbstractBagSemantics<B extends Collection<?>> implements CollectionSemantics<B> {
@Override
@SuppressWarnings("unchecked")
public B instantiateRaw(
int anticipatedSize,
CollectionPersister collectionDescriptor) {
if ( anticipatedSize < 1 ) {
return (B) new ArrayList();
}
else {
return (B) CollectionHelper.arrayList( anticipatedSize );
}
}
@Override
@SuppressWarnings("unchecked")
public <E> Iterator<E> getElementIterator(B rawCollection) {
if ( rawCollection == null ) {
return null;
}
return (Iterator<E>) rawCollection.iterator();
}
@Override
@SuppressWarnings("unchecked")
public void visitElements(B rawCollection, Consumer action) {
if ( rawCollection != null ) {
rawCollection.forEach( action );
}
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.collection.internal;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.hibernate.collection.spi.MapSemantics;
/**
* @author Steve Ebersole
*/
public abstract class AbstractMapSemantics<M extends Map<?,?>> implements MapSemantics<M> {
@Override
public Iterator getKeyIterator(M rawMap) {
if ( rawMap == null ) {
return null;
}
return rawMap.keySet().iterator();
}
@Override
@SuppressWarnings("unchecked")
public void visitKeys(M rawMap, Consumer action) {
if ( rawMap != null ) {
rawMap.keySet().forEach( action );
}
}
@Override
@SuppressWarnings("unchecked")
public void visitEntries(M rawMap, BiConsumer action) {
if ( rawMap != null ) {
rawMap.forEach( action );
}
}
@Override
public Iterator getElementIterator(Map rawMap) {
if ( rawMap == null ) {
return Collections.emptyIterator();
}
return rawMap.values().iterator();
}
@Override
@SuppressWarnings("unchecked")
public void visitElements(M rawMap, Consumer action) {
if ( rawMap != null ) {
rawMap.values().forEach( action );
}
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.collection.internal;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Consumer;
import org.hibernate.collection.spi.CollectionSemantics;
/**
* @author Steve Ebersole
*/
public abstract class AbstractSetSemantics<S extends Set<?>> implements CollectionSemantics<S> {
@Override
public Iterator getElementIterator(Set rawCollection) {
if ( rawCollection == null ) {
return null;
}
return rawCollection.iterator();
}
@Override
@SuppressWarnings("unchecked")
public void visitElements(S rawCollection, Consumer action) {
if ( rawCollection != null ) {
rawCollection.forEach( action );
}
}
}

View File

@ -0,0 +1,84 @@
/*
* 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.collection.internal;
import java.util.Arrays;
import java.util.Iterator;
import java.util.function.Consumer;
import org.hibernate.collection.spi.CollectionClassification;
import org.hibernate.collection.spi.CollectionSemantics;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;
/**
* CollectionSemantics implementation for arrays
*
* @author Steve Ebersole
*/
public class StandardArraySemantics implements CollectionSemantics<Object[]> {
/**
* Singleton access
*/
public static final StandardArraySemantics INSTANCE = new StandardArraySemantics();
private StandardArraySemantics() {
}
@Override
public CollectionClassification getCollectionClassification() {
return CollectionClassification.ARRAY;
}
@Override
public Object[] instantiateRaw(
int anticipatedSize,
CollectionPersister collectionDescriptor) {
// return (Object[]) Array.newInstance(
// collectionDescriptor.getJavaTypeDescriptor().getJavaType().getComponentType(),
// anticipatedSize
// );
throw new UnsupportedOperationException();
}
@Override
public PersistentCollection instantiateWrapper(
Object key,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentArrayHolder( key, session, collectionDescriptor );
}
@Override
public PersistentCollection wrap(
Object rawCollection,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentArrayHolder( session, collectionDescriptor, rawCollection );
}
@Override
@SuppressWarnings("unchecked")
public <E> Iterator<E> getElementIterator(Object[] rawCollection) {
return (Iterator<E>) Arrays.stream( rawCollection ).iterator();
}
@Override
@SuppressWarnings("unchecked")
public void visitElements(Object[] array, Consumer action) {
if ( array == null ) {
return;
}
for ( Object element : array ) {
action.accept( element );
}
}
}

View File

@ -0,0 +1,52 @@
/*
* 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.collection.internal;
import java.util.Collection;
import org.hibernate.collection.spi.CollectionClassification;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;
/**
* CollectionSemantics for bags
*
* @author Steve Ebersole
*/
public class StandardBagSemantics extends AbstractBagSemantics<Collection<?>> {
/**
* Singleton access
*/
public static final StandardBagSemantics INSTANCE = new StandardBagSemantics();
private StandardBagSemantics() {
}
@Override
public CollectionClassification getCollectionClassification() {
return CollectionClassification.BAG;
}
@Override
public PersistentCollection instantiateWrapper(
Object key,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentBag( session, collectionDescriptor );
}
@Override
@SuppressWarnings("unchecked")
public <E> PersistentCollection<E> wrap(
Object rawCollection,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentBag( session, collectionDescriptor, (Collection) rawCollection );
}
}

View File

@ -0,0 +1,52 @@
/*
* 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.collection.internal;
import java.util.Collection;
import org.hibernate.collection.spi.CollectionClassification;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;
/**
* CollectionSemantics implementation for id-bags
*
* @author Steve Ebersole
*/
public class StandardIdentifierBagSemantics<E> extends AbstractBagSemantics<Collection<?>> {
/**
* Singleton access
*/
public static final StandardIdentifierBagSemantics INSTANCE = new StandardIdentifierBagSemantics();
private StandardIdentifierBagSemantics() {
}
@Override
public CollectionClassification getCollectionClassification() {
return CollectionClassification.IDBAG;
}
@Override
@SuppressWarnings("unchecked")
public PersistentCollection<E> instantiateWrapper(
Object key,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentIdentifierBag( session, collectionDescriptor, key );
}
@Override
@SuppressWarnings("unchecked")
public PersistentCollection<E> wrap(
Object rawCollection,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentIdentifierBag( session, collectionDescriptor, (Collection) rawCollection );
}
}

View File

@ -0,0 +1,74 @@
/*
* 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.collection.internal;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.collection.spi.CollectionClassification;
import org.hibernate.collection.spi.CollectionSemantics;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.persister.collection.CollectionPersister;
/**
* Hibernate's standard CollectionSemantics for Lists
*
* @author Steve Ebersole
*/
public class StandardListSemantics implements CollectionSemantics<List> {
/**
* Singleton access
*/
public static final StandardListSemantics INSTANCE = new StandardListSemantics();
private StandardListSemantics() {
}
@Override
public CollectionClassification getCollectionClassification() {
return CollectionClassification.LIST;
}
@Override
public List instantiateRaw(
int anticipatedSize,
CollectionPersister collectionDescriptor) {
return CollectionHelper.arrayList( anticipatedSize );
}
@Override
@SuppressWarnings("unchecked")
public Iterator getElementIterator(List rawCollection) {
return rawCollection.iterator();
}
@Override
@SuppressWarnings("unchecked")
public void visitElements(List rawCollection, Consumer action) {
rawCollection.forEach( action );
}
@Override
public PersistentCollection instantiateWrapper(
Object key,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentList( session, collectionDescriptor, key );
}
@Override
@SuppressWarnings("unchecked")
public <E> PersistentCollection<E> wrap(
Object rawCollection,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentList( session, collectionDescriptor, (List) rawCollection );
}
}

View File

@ -0,0 +1,58 @@
/*
* 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.collection.internal;
import java.util.Map;
import org.hibernate.collection.spi.CollectionClassification;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.persister.collection.CollectionPersister;
/**
* CollectionSemantics for maps
*
* @author Steve Ebersole
*/
public class StandardMapSemantics extends AbstractMapSemantics<Map<?,?>> {
/**
* Singleton access
*/
public static final StandardMapSemantics INSTANCE = new StandardMapSemantics();
private StandardMapSemantics() {
}
@Override
public CollectionClassification getCollectionClassification() {
return CollectionClassification.MAP;
}
@Override
public Map<?, ?> instantiateRaw(
int anticipatedSize,
CollectionPersister collectionDescriptor) {
return CollectionHelper.mapOfSize( anticipatedSize );
}
@Override
public <E> PersistentCollection<E> instantiateWrapper(
Object key,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentMap( session, collectionDescriptor, key );
}
@Override
public <E> PersistentCollection<E> wrap(
Object rawCollection,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentMap( session, collectionDescriptor, (Map) rawCollection );
}
}

View File

@ -0,0 +1,62 @@
/*
* 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.collection.internal;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import org.hibernate.collection.spi.CollectionClassification;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.model.mapping.PersistentCollectionDescriptor;
/**
* @author Steve Ebersole
*/
public class StandardOrderedMapSemantics extends AbstractMapSemantics<LinkedHashMap<?,?>> {
/**
* Singleton access
*/
public static final StandardOrderedMapSemantics INSTANCE = new StandardOrderedMapSemantics();
private StandardOrderedMapSemantics() {
}
@Override
public CollectionClassification getCollectionClassification() {
return CollectionClassification.ORDERED_MAP;
}
@Override
public LinkedHashMap<?, ?> instantiateRaw(
int anticipatedSize,
PersistentCollectionDescriptor collectionDescriptor) {
return anticipatedSize < 1 ? new LinkedHashMap<>() : new LinkedHashMap<>( anticipatedSize );
}
@Override
public <E> PersistentCollection<E> instantiateWrapper(
Object key,
PersistentCollectionDescriptor<?, LinkedHashMap<?, ?>, E> collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentMap<>( session, collectionDescriptor, key );
}
@Override
public <E> PersistentCollection<E> wrap(
Object rawCollection,
PersistentCollectionDescriptor<?, LinkedHashMap<?, ?>, E> collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentMap<>( session, collectionDescriptor, (Map) rawCollection );
}
@Override
public Iterator getElementIterator(LinkedHashMap rawCollection) {
return rawCollection.entrySet().iterator();
}
}

View File

@ -0,0 +1,62 @@
/*
* 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.collection.internal;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import org.hibernate.collection.spi.CollectionClassification;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.model.mapping.PersistentCollectionDescriptor;
/**
* @author Steve Ebersole
*/
public class StandardOrderedSetSemantics extends AbstractSetSemantics<LinkedHashSet<?>> {
/**
* Singleton access
*/
public static final StandardOrderedSetSemantics INSTANCE = new StandardOrderedSetSemantics();
private StandardOrderedSetSemantics() {
}
@Override
public CollectionClassification getCollectionClassification() {
return CollectionClassification.ORDERED_SET;
}
@Override
public LinkedHashSet<?> instantiateRaw(
int anticipatedSize,
PersistentCollectionDescriptor collectionDescriptor) {
return anticipatedSize < 1 ? new LinkedHashSet() : new LinkedHashSet<>( anticipatedSize );
}
@Override
public <E> PersistentCollection<E> instantiateWrapper(
Object key,
PersistentCollectionDescriptor<?, LinkedHashSet<?>, E> collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentSet( session, collectionDescriptor, key );
}
@Override
public <E> PersistentCollection<E> wrap(
Object rawCollection,
PersistentCollectionDescriptor<?, LinkedHashSet<?>, E> collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentSet( session, collectionDescriptor, (Set) rawCollection );
}
@Override
public Iterator getElementIterator(LinkedHashSet rawCollection) {
return rawCollection.iterator();
}
}

View File

@ -0,0 +1,59 @@
/*
* 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.collection.internal;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.collection.spi.CollectionClassification;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;
/**
* @author Steve Ebersole
*/
public class StandardSetSemantics extends AbstractSetSemantics<Set<?>> {
/**
* Singleton access
*/
public static final StandardSetSemantics INSTANCE = new StandardSetSemantics();
private StandardSetSemantics() {
}
@Override
public CollectionClassification getCollectionClassification() {
return CollectionClassification.SET;
}
@Override
public Set<?> instantiateRaw(
int anticipatedSize,
CollectionPersister collectionDescriptor) {
return anticipatedSize < 1 ? new HashSet<>() : new HashSet<>( anticipatedSize );
}
@Override
public <E> PersistentCollection<E> instantiateWrapper(
Object key,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
//noinspection unchecked
return new PersistentSet( session, collectionDescriptor, key );
}
@Override
public <E> PersistentCollection<E> wrap(
Object rawCollection,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
//noinspection unchecked
return new PersistentSet( session, collectionDescriptor, (Set) rawCollection );
}
}

View File

@ -0,0 +1,58 @@
/*
* 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.collection.internal;
import java.util.SortedMap;
import java.util.TreeMap;
import org.hibernate.collection.spi.CollectionClassification;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;
/**
* @author Steve Ebersole
*/
public class StandardSortedMapSemantics extends AbstractMapSemantics<SortedMap<?,?>> {
/**
* Singleton access
*/
public static final StandardSortedMapSemantics INSTANCE = new StandardSortedMapSemantics();
private StandardSortedMapSemantics() {
}
@Override
public CollectionClassification getCollectionClassification() {
return CollectionClassification.SORTED_MAP;
}
@Override
public TreeMap<?, ?> instantiateRaw(
int anticipatedSize,
CollectionPersister collectionDescriptor) {
return new TreeMap<>( collectionDescriptor.getSortingComparator() );
}
@Override
@SuppressWarnings("unchecked")
public PersistentCollection instantiateWrapper(
Object key,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentSortedMap( session, collectionDescriptor, key );
}
@Override
@SuppressWarnings("unchecked")
public PersistentCollection wrap(
Object rawCollection,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentSortedMap( session, collectionDescriptor, (SortedMap) rawCollection );
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.collection.internal;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
import org.hibernate.collection.spi.CollectionClassification;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;
/**
* @author Steve Ebersole
*/
public class StandardSortedSetSemantics extends AbstractSetSemantics<SortedSet<?>> {
/**
* Singleton access
*/
public static final StandardSortedSetSemantics INSTANCE = new StandardSortedSetSemantics();
private StandardSortedSetSemantics() {
}
@Override
public CollectionClassification getCollectionClassification() {
return CollectionClassification.SORTED_SET;
}
@Override
public SortedSet instantiateRaw(
int anticipatedSize,
CollectionPersister collectionDescriptor) {
return new TreeSet<>( collectionDescriptor.getSortingComparator() );
}
@Override
@SuppressWarnings("unchecked")
public PersistentCollection instantiateWrapper(
Object key,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentSortedSet( session, collectionDescriptor, key );
}
@Override
@SuppressWarnings("unchecked")
public PersistentCollection wrap(
Object rawCollection,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session) {
return new PersistentSortedSet( session, collectionDescriptor, (SortedSet) rawCollection );
}
@Override
@SuppressWarnings("unchecked")
public <E> Iterator<E> getElementIterator(SortedSet<?> rawCollection) {
return (Iterator<E>) rawCollection.iterator();
}
}

View File

@ -0,0 +1,23 @@
/*
* 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.collection.spi;
import org.hibernate.mapping.Collection;
/**
* todo (6.0) ...
*
* Ideally would act as the contract that allows pluggable resolution of
* non-Java Collection types - maybe as part of a generalized reflection
* on the attribute to determine its nature/classification
*
* @author Steve Ebersole
*/
public interface CollectionSemanticsResolver {
// really need some form of access to the attribute site
CollectionSemantics resolveRepresentation(Collection bootDescriptor);
}

View File

@ -0,0 +1,24 @@
/*
* 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.collection.spi;
import java.util.Iterator;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
* Extension of CollectionSemantics for Maps
*
* @author Steve Ebersole
*/
public interface MapSemantics<M> extends CollectionSemantics<M> {
Iterator getKeyIterator(M rawMap);
void visitKeys(M rawMap, Consumer action);
void visitEntries(M rawMap, BiConsumer action);
}

View File

@ -12,7 +12,7 @@ import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
/**
* A container for {@link AttributeNode}s.
* A container for {@link AttributeNode} references.
*
* Acts as a "bridge" between JPA's {@link javax.persistence.EntityGraph} and {@link javax.persistence.Subgraph}
*

View File

@ -12,6 +12,8 @@ import javax.persistence.EntityGraph;
import javax.persistence.Subgraph;
import javax.persistence.metamodel.Attribute;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
/**
* Hibernate extension to the JPA {@link EntityGraph} contract.
*
@ -24,7 +26,7 @@ public interface RootGraph<J> extends Graph<J>, EntityGraph<J> {
boolean appliesTo(String entityName);
boolean appliesTo(Class entityType);
boolean appliesTo(Class<? super J> entityType);
@Override
RootGraph<J> makeRootGraph(String name, boolean mutable);
@ -59,18 +61,20 @@ public interface RootGraph<J> extends Graph<J>, EntityGraph<J> {
}
for ( Attribute<J, ?> attribute : attributes ) {
addAttributeNode( attribute );
addAttributeNode( (PersistentAttribute) attribute );
}
}
@Override
default <X> SubGraph<X> addSubgraph(Attribute<J, X> attribute) {
return addSubGraph( attribute );
//noinspection unchecked
return addSubGraph( (PersistentAttribute) attribute );
}
@Override
default <X> SubGraph<? extends X> addSubgraph(Attribute<J, X> attribute, Class<? extends X> type) {
return addSubGraph( attribute, type );
//noinspection unchecked
return addSubGraph( (PersistentAttribute) attribute, type );
}
@Override
@ -85,12 +89,14 @@ public interface RootGraph<J> extends Graph<J>, EntityGraph<J> {
@Override
default <X> SubGraph<X> addKeySubgraph(Attribute<J, X> attribute) {
return addKeySubGraph( attribute );
//noinspection unchecked
return addKeySubGraph( (PersistentAttribute) attribute );
}
@Override
default <X> SubGraph<? extends X> addKeySubgraph(Attribute<J, X> attribute, Class<? extends X> type) {
return addKeySubGraph( attribute, type );
//noinspection unchecked
return addKeySubGraph( (PersistentAttribute) attribute, type );
}
@Override

View File

@ -12,7 +12,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.AttributeNode;
import org.hibernate.graph.CannotBecomeEntityGraphException;
import org.hibernate.graph.CannotContainSubGraphException;
@ -23,6 +22,7 @@ import org.hibernate.graph.spi.GraphImplementor;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
@ -39,14 +39,14 @@ public abstract class AbstractGraph<J> extends AbstractGraphNode<J> implements G
public AbstractGraph(
ManagedDomainType<J> managedType,
boolean mutable,
SessionFactoryImplementor sessionFactory) {
super( mutable, sessionFactory );
JpaMetamodel jpaMetamodel) {
super( mutable, jpaMetamodel );
this.managedType = managedType;
}
@SuppressWarnings("WeakerAccess")
protected AbstractGraph(boolean mutable, GraphImplementor<J> original) {
this( original.getGraphedType(), mutable, original.sessionFactory() );
this( original.getGraphedType(), mutable, original.jpaMetamodel() );
this.attrNodeMap = CollectionHelper.concurrentMap( original.getAttributeNodeList().size() );
original.visitAttributeNodes(
@ -58,8 +58,8 @@ public abstract class AbstractGraph<J> extends AbstractGraphNode<J> implements G
}
@Override
public SessionFactoryImplementor sessionFactory() {
return super.sessionFactory();
public JpaMetamodel jpaMetamodel() {
return super.jpaMetamodel();
}
@Override
@ -196,7 +196,7 @@ public abstract class AbstractGraph<J> extends AbstractGraphNode<J> implements G
}
if ( attrNode == null ) {
attrNode = new AttributeNodeImpl<>( isMutable(), attribute, sessionFactory() );
attrNode = new AttributeNodeImpl<>( isMutable(), attribute, jpaMetamodel() );
attrNodeMap.put( attribute, attrNode );
}

View File

@ -6,23 +6,23 @@
*/
package org.hibernate.graph.internal;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.spi.GraphNodeImplementor;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
/**
* @author Steve Ebersole
*/
public abstract class AbstractGraphNode<J> implements GraphNodeImplementor<J> {
private final SessionFactoryImplementor sessionFactory;
private final JpaMetamodel jpaMetamodel;
private final boolean mutable;
public AbstractGraphNode(boolean mutable, SessionFactoryImplementor sessionFactory) {
this.sessionFactory = sessionFactory;
public AbstractGraphNode(boolean mutable, JpaMetamodel jpaMetamodel) {
this.jpaMetamodel = jpaMetamodel;
this.mutable = mutable;
}
protected SessionFactoryImplementor sessionFactory() {
return sessionFactory;
protected JpaMetamodel jpaMetamodel() {
return jpaMetamodel;
}
@Override

View File

@ -11,12 +11,12 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.CannotContainSubGraphException;
import org.hibernate.graph.SubGraph;
import org.hibernate.graph.spi.AttributeNodeImplementor;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
@ -40,8 +40,8 @@ public class AttributeNodeImpl<J>
public <X> AttributeNodeImpl(
boolean mutable,
PersistentAttribute<X, J> attribute,
SessionFactoryImplementor sessionFactory) {
this( mutable, attribute, null, null, sessionFactory );
JpaMetamodel jpaMetamodel) {
this( mutable, attribute, null, null, jpaMetamodel );
}
/**
@ -52,8 +52,8 @@ public class AttributeNodeImpl<J>
PersistentAttribute<?, J> attribute,
Map<Class<? extends J>, SubGraphImplementor<? extends J>> subGraphMap,
Map<Class<? extends J>, SubGraphImplementor<? extends J>> keySubGraphMap,
SessionFactoryImplementor sessionFactory) {
super( mutable, sessionFactory );
JpaMetamodel jpaMetamodel) {
super( mutable, jpaMetamodel );
this.attribute = attribute;
this.subGraphMap = subGraphMap;
this.keySubGraphMap = keySubGraphMap;
@ -152,7 +152,7 @@ public class AttributeNodeImpl<J>
@SuppressWarnings({"WeakerAccess", "unchecked"})
protected <S extends J> void internalAddSubGraph(Class<S> subType, SubGraphImplementor<S> subGraph) {
log.tracef( "Adding sub-graph : ( (%s) %s )", subGraph.getGraphedType().getName(), getAttributeName() );
log.tracef( "Adding sub-graph : ( (%s) %s )", subGraph.getGraphedType().getTypeName(), getAttributeName() );
if ( subGraphMap == null ) {
subGraphMap = new HashMap<>();
@ -265,7 +265,7 @@ public class AttributeNodeImpl<J>
this.attribute,
makeMapCopy( mutable, (Map) subGraphMap ),
makeMapCopy( mutable, (Map) keySubGraphMap ),
sessionFactory()
jpaMetamodel()
);
}

View File

@ -9,13 +9,13 @@ package org.hibernate.graph.internal;
import javax.persistence.EntityGraph;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.SubGraph;
import org.hibernate.graph.spi.GraphImplementor;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
/**
* The Hibernate implementation of the JPA EntityGraph contract.
@ -29,17 +29,17 @@ public class RootGraphImpl<J> extends AbstractGraph<J> implements EntityGraph<J>
String name,
EntityDomainType<J> entityType,
boolean mutable,
SessionFactoryImplementor sessionFactory) {
super( entityType, mutable, sessionFactory );
JpaMetamodel jpaMetamodel) {
super( entityType, mutable, jpaMetamodel );
this.name = name;
}
public RootGraphImpl(String name, EntityDomainType<J> entityType, SessionFactoryImplementor sessionFactory) {
public RootGraphImpl(String name, EntityDomainType<J> entityType, JpaMetamodel jpaMetamodel) {
this(
name,
entityType,
true,
sessionFactory
jpaMetamodel
);
}
@ -96,11 +96,11 @@ public class RootGraphImpl<J> extends AbstractGraph<J> implements EntityGraph<J>
@Override
public boolean appliesTo(String entityName) {
return appliesTo( sessionFactory().getMetamodel().entity( entityName ) );
return appliesTo( jpaMetamodel().entity( entityName ) );
}
@Override
public boolean appliesTo(Class entityType) {
return appliesTo( sessionFactory().getMetamodel().entity( entityType ) );
public boolean appliesTo(Class<? super J> type) {
return appliesTo( jpaMetamodel().entity( type ) );
}
}

View File

@ -6,13 +6,9 @@
*/
package org.hibernate.graph.internal;
import javax.persistence.metamodel.Attribute;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.spi.AttributeNodeImplementor;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
/**
* @author Steve Ebersole
@ -21,8 +17,8 @@ public class SubGraphImpl<J> extends AbstractGraph<J> implements SubGraphImpleme
public SubGraphImpl(
ManagedDomainType<J> managedType,
boolean mutable,
SessionFactoryImplementor sessionFactory) {
super( managedType, mutable, sessionFactory );
JpaMetamodel jpaMetamodel) {
super( managedType, mutable, jpaMetamodel );
}
public SubGraphImpl(boolean mutable, AbstractGraph<J> original) {
@ -48,12 +44,6 @@ public class SubGraphImpl<J> extends AbstractGraph<J> implements SubGraphImpleme
return super.addKeySubGraph( attributeName );
}
@Override
@SuppressWarnings("unchecked")
public <AJ> AttributeNodeImplementor<AJ> addAttributeNode(Attribute<? extends J, AJ> attribute) {
return addAttributeNode( (PersistentAttribute) attribute );
}
@Override
public boolean appliesTo(ManagedDomainType<? super J> managedType) {
if ( this.getGraphedType().equals( managedType ) ) {
@ -73,6 +63,6 @@ public class SubGraphImpl<J> extends AbstractGraph<J> implements SubGraphImpleme
@Override
public boolean appliesTo(Class<? super J> javaType) {
return appliesTo( sessionFactory().getMetamodel().managedType( javaType ) );
return appliesTo( jpaMetamodel().managedType( javaType ) );
}
}

View File

@ -9,11 +9,11 @@ package org.hibernate.graph.spi;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.AttributeNode;
import org.hibernate.graph.CannotBecomeEntityGraphException;
import org.hibernate.graph.CannotContainSubGraphException;
import org.hibernate.graph.Graph;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
@ -32,7 +32,7 @@ public interface GraphImplementor<J> extends Graph<J>, GraphNodeImplementor<J> {
@SuppressWarnings("unchecked")
void merge(GraphImplementor<J>... others);
SessionFactoryImplementor sessionFactory();
JpaMetamodel jpaMetamodel();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -20,10 +20,12 @@ import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.Type;
import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.internal.EntityManagerMessageLogger;
import org.hibernate.internal.HEMLogging;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.List;
import org.hibernate.mapping.Map;
import org.hibernate.mapping.OneToMany;
import org.hibernate.mapping.PersistentClass;
@ -46,10 +48,10 @@ import org.hibernate.metamodel.model.domain.internal.SingularAttributeImpl;
import org.hibernate.property.access.internal.PropertyAccessMapImpl;
import org.hibernate.property.access.spi.Getter;
import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.type.ComponentType;
import org.hibernate.type.EmbeddedComponentType;
import org.hibernate.type.EntityType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
/**
* A factory for building {@link Attribute} instances. Exposes 3 main services for building<ol>
@ -233,23 +235,50 @@ public class AttributeFactory {
}
case EMBEDDABLE: {
final Component component = (Component) typeContext.getHibernateValue();
final EmbeddableTypeImpl<Y> embeddableType;
Class javaType;
if ( component.getComponentClassName() == null ) {
javaType = typeContext.getJpaBindableType();
if ( component.getComponentClass() != null
|| component.getComponentClassName() != null ) {
// we should have a non-dynamic embeddable
final Class embeddableClass;
if ( component.getComponentClass() != null ) {
embeddableClass = component.getComponentClass();
}
else {
embeddableClass = context.getSessionFactory()
.getServiceRegistry()
.getService( ClassLoaderService.class )
.classForName( component.getComponentClassName() );
}
final EmbeddableDomainType cached = context.locateEmbeddable( embeddableClass );
if ( cached != null ) {
return cached;
}
final JavaTypeDescriptorRegistry registry = context.getSessionFactory()
.getMetamodel()
.getTypeConfiguration()
.getJavaTypeDescriptorRegistry();
final JavaTypeDescriptor javaTypeDescriptor = registry.resolveDescriptor( embeddableClass );
embeddableType = new EmbeddableTypeImpl<Y>(
javaTypeDescriptor,
context.getSessionFactory().getQueryEngine().getCriteriaBuilder()
);
context.registerEmbeddableType( embeddableType );
return embeddableType;
}
else {
javaType = component.getComponentClass();
embeddableType = new EmbeddableTypeImpl(
component.getRoleName(),
context.getSessionFactory().getQueryEngine().getCriteriaBuilder()
);
}
final EmbeddableTypeImpl<Y> embeddableType = new EmbeddableTypeImpl<Y>(
javaType,
typeContext.getAttributeMetadata().getOwnerType(),
(ComponentType) typeContext.getHibernateValue().getType(),
context.getSessionFactory().getQueryEngine().getCriteriaBuilder()
);
context.registerEmbeddableType( embeddableType );
final EmbeddableTypeImpl.InFlightAccess<Y> inFlightAccess = embeddableType.getInFlightAccess();
final Iterator<Property> subProperties = component.getPropertyIterator();
while ( subProperties.hasNext() ) {
@ -548,6 +577,9 @@ public class AttributeFactory {
indexClassification = AttributeClassification.BASIC;
}
}
else if ( value instanceof List ) {
indexClassification = AttributeClassification.BASIC;
}
else {
indexClassification = null;
}
@ -780,7 +812,7 @@ public class AttributeFactory {
implements PluralAttributeMetadata<X, Y, E> {
private final PluralAttribute.CollectionType attributeCollectionType;
private final AttributeClassification elementClassification;
private final AttributeClassification keyClassification;
private final AttributeClassification listIndexOrMapKeyClassification;
private final Class elementJavaType;
private final Class keyJavaType;
private final ValueContext elementValueContext;
@ -792,14 +824,14 @@ public class AttributeFactory {
Member member,
AttributeClassification attributeClassification,
AttributeClassification elementClassification,
AttributeClassification keyClassification) {
AttributeClassification listIndexOrMapKeyClassification) {
super( propertyMapping, ownerType, member, attributeClassification );
this.attributeCollectionType = determineCollectionType( getJavaType() );
this.elementClassification = elementClassification;
this.keyClassification = keyClassification;
this.listIndexOrMapKeyClassification = listIndexOrMapKeyClassification;
ParameterizedType signatureType = getSignatureType( member );
if ( this.keyClassification == null ) {
if ( this.listIndexOrMapKeyClassification == null ) {
elementJavaType = signatureType != null ?
getClassFromGenericArgument( signatureType.getActualTypeArguments()[0] ) :
Object.class; //FIXME and honor targetEntity?
@ -843,7 +875,7 @@ public class AttributeFactory {
};
// interpret the key, if one
if ( this.keyClassification != null ) {
if ( this.listIndexOrMapKeyClassification != null ) {
this.keyValueContext = new ValueContext() {
public Value getHibernateValue() {
return ( (Map) getPropertyMapping().getValue() ).getIndex();
@ -854,7 +886,7 @@ public class AttributeFactory {
}
public ValueClassification getValueClassification() {
switch ( PluralAttributeMetadataImpl.this.keyClassification ) {
switch ( PluralAttributeMetadataImpl.this.listIndexOrMapKeyClassification ) {
case EMBEDDED: {
return ValueClassification.EMBEDDABLE;
}
@ -968,6 +1000,8 @@ public class AttributeFactory {
final EmbeddableDomainType embeddableType = (EmbeddableDomainType<?>) attributeContext.getOwnerType();
final String attributeName = attributeContext.getPropertyMapping().getName();
final Component component = (Component) attributeContext.getPropertyMapping().getValue();
final Getter getter = embeddableType.getHibernateType()
.getComponentTuplizer()
.getGetter( embeddableType.getHibernateType().getPropertyIndex( attributeName ) );

View File

@ -45,7 +45,6 @@ import org.hibernate.metamodel.model.domain.internal.AttributeContainer;
import org.hibernate.metamodel.model.domain.internal.BasicTypeImpl;
import org.hibernate.metamodel.model.domain.internal.EntityTypeImpl;
import org.hibernate.metamodel.model.domain.internal.MappedSuperclassTypeImpl;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
/**
@ -73,7 +72,7 @@ class MetadataContext {
private Map<String, EntityDomainType<?>> entityTypesByEntityName = new HashMap<>();
private Map<PersistentClass, EntityDomainType<?>> entityTypesByPersistentClass = new HashMap<>();
private Set<EmbeddableDomainType<?>> embeddables = new HashSet<>();
private Map<Class, EmbeddableDomainType<?>> embeddables = new HashMap<>();
private Map<MappedSuperclass, MappedSuperclassDomainType<?>> mappedSuperclassByMappedSuperclassMapping = new HashMap<>();
private Map<MappedSuperclassDomainType<?>, PersistentClass> mappedSuperClassTypeToPersistentClass = new HashMap<>();
@ -113,7 +112,7 @@ class MetadataContext {
}
public Set<EmbeddableDomainType<?>> getEmbeddableTypeSet() {
return Collections.unmodifiableSet( embeddables );
return new HashSet<>( embeddables.values() );
}
public Map<Class<?>, MappedSuperclassType<?>> getMappedSuperclassTypeMap() {
@ -147,9 +146,10 @@ class MetadataContext {
}
/*package*/ void registerEmbeddableType(EmbeddableDomainType<?> embeddableType) {
if ( !( ignoreUnsupported && Map.class.isAssignableFrom( embeddableType.getExpressableJavaTypeDescriptor().getJavaType() ) ) ) {
embeddables.add( embeddableType );
}
assert embeddableType.getJavaType() != null;
assert ! Map.class.isAssignableFrom( embeddableType.getJavaType() );
embeddables.put( embeddableType.getJavaType(), embeddableType );
}
/*package*/ void registerMappedSuperclassType(
@ -170,6 +170,7 @@ class MetadataContext {
*
* @return Tne corresponding JPA {@link org.hibernate.type.EntityType}, or null if not yet processed.
*/
@SuppressWarnings("WeakerAccess")
public EntityDomainType<?> locateEntityType(PersistentClass persistentClass) {
return entityTypesByPersistentClass.get( persistentClass );
}
@ -194,16 +195,17 @@ class MetadataContext {
*
* @return The corresponding JPA {@link org.hibernate.type.EntityType}, or null.
*/
@SuppressWarnings({"unchecked"})
@SuppressWarnings({"unchecked", "WeakerAccess"})
public <E> EntityDomainType<E> locateEntityType(String entityName) {
return (EntityDomainType) entityTypesByEntityName.get( entityName );
}
@SuppressWarnings("WeakerAccess")
public Map<String, EntityDomainType<?>> getEntityTypesByEntityName() {
return Collections.unmodifiableMap( entityTypesByEntityName );
}
@SuppressWarnings({"unchecked"})
@SuppressWarnings({"unchecked", "WeakerAccess"})
public void wrapUp() {
if ( LOG.isTraceEnabled() ) {
LOG.trace( "Wrapping up metadata context..." );
@ -215,7 +217,6 @@ class MetadataContext {
//we need to process types from superclasses to subclasses
for ( Object mapping : orderedMappings ) {
if ( PersistentClass.class.isAssignableFrom( mapping.getClass() ) ) {
@SuppressWarnings("unchecked")
final PersistentClass safeMapping = (PersistentClass) mapping;
if ( LOG.isTraceEnabled() ) {
LOG.trace( "Starting entity [" + safeMapping.getEntityName() + ']' );
@ -258,7 +259,6 @@ class MetadataContext {
}
}
else if ( MappedSuperclass.class.isAssignableFrom( mapping.getClass() ) ) {
@SuppressWarnings("unchecked")
final MappedSuperclass safeMapping = (MappedSuperclass) mapping;
if ( LOG.isTraceEnabled() ) {
LOG.trace( "Starting mapped superclass [" + safeMapping.getMappedClass().getName() + ']' );
@ -299,7 +299,7 @@ class MetadataContext {
}
if ( staticMetamodelScanEnabled ) {
for ( EmbeddableDomainType embeddable : embeddables ) {
for ( EmbeddableDomainType embeddable : embeddables.values() ) {
populateStaticMetamodel( embeddable );
}
}
@ -307,7 +307,7 @@ class MetadataContext {
@SuppressWarnings("unchecked")
private <X> void applyIdMetadata(PersistentClass persistentClass, IdentifiableDomainType<?> identifiableType) {
private void applyIdMetadata(PersistentClass persistentClass, IdentifiableDomainType<?> identifiableType) {
if ( persistentClass.hasIdentifierProperty() ) {
final Property declaredIdentifierProperty = persistentClass.getDeclaredIdentifierProperty();
if ( declaredIdentifierProperty != null ) {
@ -551,13 +551,14 @@ class MetadataContext {
}
public Set<MappedSuperclass> getUnusedMappedSuperclasses() {
return new HashSet<MappedSuperclass>( knownMappedSuperclasses );
return new HashSet<>( knownMappedSuperclasses );
}
private final Map<Class<?>,BasicDomainType<?>> basicDomainTypeMap = new HashMap<>();
public <J> BasicDomainType<J> resolveBasicType(Class<J> javaType) {
return basicDomainTypeMap.computeIfAbsent(
//noinspection unchecked
return (BasicDomainType) basicDomainTypeMap.computeIfAbsent(
javaType,
jt -> {
final JavaTypeDescriptorRegistry registry = getSessionFactory()
@ -566,6 +567,11 @@ class MetadataContext {
.getJavaTypeDescriptorRegistry();
return new BasicTypeImpl<>( registry.resolveDescriptor( javaType ) );
}
)
);
}
public <J> EmbeddableDomainType<J> locateEmbeddable(Class<J> embeddableClass) {
//noinspection unchecked
return (EmbeddableDomainType<J>) embeddables.get( embeddableClass );
}
}

View File

@ -6,27 +6,26 @@
*/
package org.hibernate.metamodel.model.domain;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Steve Ebersole
*/
public abstract class AbstractDomainType<J> implements DomainType<J> {
private final SessionFactoryImplementor sessionFactory;
public abstract class AbstractDomainType<J> implements SimpleDomainType<J> {
private final JpaMetamodel jpaMetamodel;
private final JavaTypeDescriptor<J> javaTypeDescriptor;
@SuppressWarnings("WeakerAccess")
public AbstractDomainType(
JavaTypeDescriptor<J> javaTypeDescriptor,
SessionFactoryImplementor sessionFactory) {
JpaMetamodel jpaMetamodel) {
this.javaTypeDescriptor = javaTypeDescriptor;
this.sessionFactory = sessionFactory;
this.jpaMetamodel = jpaMetamodel;
}
protected SessionFactoryImplementor sessionFactory() {
return sessionFactory;
protected JpaMetamodel jpaMetamodel() {
return jpaMetamodel;
}
@Override

View File

@ -13,8 +13,6 @@ import java.util.function.Consumer;
import javax.persistence.metamodel.IdentifiableType;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.model.domain.internal.AttributeContainer;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
@ -48,8 +46,8 @@ public abstract class AbstractIdentifiableType<J>
boolean hasIdClass,
boolean hasIdentifierProperty,
boolean versioned,
SessionFactoryImplementor sessionFactory) {
super( typeName, javaTypeDescriptor, superType, sessionFactory );
JpaMetamodel jpaMetamodel) {
super( typeName, javaTypeDescriptor, superType, jpaMetamodel );
this.hasIdClass = hasIdClass;
this.hasIdentifierProperty = hasIdentifierProperty;
this.isVersioned = versioned;

View File

@ -12,6 +12,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.CollectionAttribute;
import javax.persistence.metamodel.ListAttribute;
@ -21,7 +22,6 @@ import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SetAttribute;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.internal.SubGraphImpl;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.metamodel.RepresentationMode;
@ -49,8 +49,8 @@ public abstract class AbstractManagedType<J>
String hibernateTypeName,
JavaTypeDescriptor<J> javaTypeDescriptor,
ManagedDomainType<? super J> superType,
SessionFactoryImplementor sessionFactory) {
super( javaTypeDescriptor, sessionFactory );
JpaMetamodel jpaMetamodel) {
super( javaTypeDescriptor, jpaMetamodel );
this.hibernateTypeName = hibernateTypeName;
this.superType = superType;
@ -74,6 +74,20 @@ public abstract class AbstractManagedType<J>
return representationMode;
}
@Override
@SuppressWarnings("unchecked")
public void visitAttributes(Consumer<PersistentAttribute<? super J, ?>> action) {
visitDeclaredAttributes( (Consumer) action );
if ( getSuperType() != null ) {
getSuperType().visitAttributes( (Consumer) action );
}
}
@Override
public void visitDeclaredAttributes(Consumer<PersistentAttribute<J, ?>> action) {
declaredSingularAttributes.values().forEach( action );
declaredPluralAttributes.values().forEach( action );
}
@Override
@SuppressWarnings("unchecked")
@ -555,17 +569,17 @@ public abstract class AbstractManagedType<J>
@SuppressWarnings("unchecked")
@Override
public SubGraphImplementor<J> makeSubGraph() {
return new SubGraphImpl( this, true, sessionFactory() );
return new SubGraphImpl( this, true, jpaMetamodel() );
}
@Override
public <S extends J> ManagedDomainType<S> findSubType(String subTypeName) {
return DomainModelHelper.resolveSubType( this, subTypeName, sessionFactory() );
return DomainModelHelper.resolveSubType( this, subTypeName, jpaMetamodel() );
}
@Override
public <S extends J> ManagedDomainType<S> findSubType(Class<S> subType) {
return DomainModelHelper.resolveSubType( this, subType, sessionFactory() );
return DomainModelHelper.resolveSubType( this, subType, jpaMetamodel() );
}

View File

@ -0,0 +1,86 @@
/*
* 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.metamodel.model.domain;
import java.util.Set;
import java.util.function.Consumer;
import javax.persistence.metamodel.EmbeddableType;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.ManagedType;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Hibernate extension to the JPA {@link javax.persistence.metamodel.Metamodel} contract
*
* @see org.hibernate.metamodel.spi.RuntimeModel
*
* @author Steve Ebersole
*/
public interface JpaMetamodel extends javax.persistence.metamodel.Metamodel {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Context
/**
* todo (6.0) : should we expose JpaMetamodel from TypeConfiguration?
*/
TypeConfiguration getTypeConfiguration();
default ServiceRegistry getServiceRegistry() {
return getTypeConfiguration().getServiceRegistry();
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Extended features
/**
* Access to an entity supporting Hibernate's entity-name feature
*/
<X> EntityDomainType<X> entity(String entityName);
/**
* Specialized handling for resolving entity-name references in
* an HQL query
*/
<X> EntityDomainType<X> resolveHqlEntityReference(String entityName);
void visitManagedTypes(Consumer<ManagedDomainType<?>> action);
void visitEntityTypes(Consumer<EntityDomainType<?>> action);
void visitRootEntityTypes(Consumer<EntityDomainType<?>> action);
void visitEmbeddables(Consumer<EmbeddableDomainType<?>> action);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Covariant returns
@Override
<X> ManagedDomainType<X> managedType(Class<X> cls);
@Override
<X> EntityDomainType<X> entity(Class<X> cls);
@Override
<X> EmbeddableDomainType<X> embeddable(Class<X> cls);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA defined bulk accessors
@Override
Set<ManagedType<?>> getManagedTypes();
@Override
Set<EntityType<?>> getEntities();
@Override
Set<EmbeddableType<?>> getEmbeddables();
}

View File

@ -21,25 +21,24 @@ public interface ManagedDomainType<J> extends SimpleDomainType<J>, ManagedType<J
/**
* Get the type name.
*
* For dynamic models ({@link RepresentationMode#MAP}), this returns the symbolic name
* Generally speaking, this returns the name of the Java class. However, for
* dynamic models ({@link RepresentationMode#MAP}), this returns the symbolic name
* since the Java type is {@link java.util.Map}
*
* For typed models, this returns the name of the Java class
*
* @return The type name.
*
* @see #getRepresentationMode()
*/
String getTypeName();
RepresentationMode getRepresentationMode();
/**
* This type's super type descriptor. Note : we define this on the managed
* type descriptor in anticipation of supporting embeddable inheritance
*/
ManagedDomainType<? super J> getSuperType();
RepresentationMode getRepresentationMode();
void visitAttributes(Consumer<PersistentAttribute<? super J,?>> action);
void visitDeclaredAttributes(Consumer<PersistentAttribute<J,?>> action);

View File

@ -61,11 +61,6 @@ public abstract class AbstractAttribute<D,J,B> implements PersistentAttribute<D,
return name;
}
@Override
public String getPathName() {
return getName();
}
@Override
public Class<J> getJavaType() {
return attributeType.getJavaType();

View File

@ -42,9 +42,9 @@ public abstract class AbstractPluralAttribute<D,C,E>
AbstractManagedType<X> ownerType,
SimpleDomainType<E> attrType,
JavaTypeDescriptor<C> collectionClass,
SimpleDomainType<K> keyType,
SimpleDomainType<K> listIndexOrMapKeyType,
NodeBuilder nodeBuilder) {
return new PluralAttributeBuilder<>( ownerType, attrType, collectionClass, keyType, nodeBuilder );
return new PluralAttributeBuilder<>( ownerType, attrType, collectionClass, listIndexOrMapKeyType, nodeBuilder );
}
private final CollectionClassification classification;
@ -94,6 +94,11 @@ public abstract class AbstractPluralAttribute<D,C,E>
);
}
@Override
public String getPathName() {
return getName();
}
@Override
public CollectionClassification getCollectionClassification() {
return classification;

View File

@ -11,8 +11,11 @@ import java.util.Collection;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.domain.BagPersistentAttribute;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.domain.SqmBagJoin;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
/**
* @author Steve Ebersole
@ -34,4 +37,22 @@ class BagAttributeImpl<X, E>
public SqmPathSource<?> findSubPathSource(String name) {
throw new NotYetImplementedFor6Exception();
}
@Override
public SqmAttributeJoin createSqmJoin(
SqmFrom lhs,
SqmJoinType joinType,
String alias,
boolean fetched,
SqmCreationState creationState) {
//noinspection unchecked
return new SqmBagJoin(
lhs,
this,
alias,
joinType,
fetched,
creationState.getCreationContext().getQueryEngine().getCriteriaBuilder()
);
}
}

View File

@ -16,8 +16,8 @@ import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
@ -33,32 +33,26 @@ public class DomainModelHelper {
public static <T, S extends T> ManagedDomainType<S> resolveSubType(
ManagedDomainType<T> baseType,
String subTypeName,
SessionFactoryImplementor sessionFactory) {
final MetamodelImplementor metamodel = sessionFactory.getMetamodel();
JpaMetamodel jpaMetamodel) {
if ( baseType instanceof EmbeddableDomainType<?> ) {
// todo : at least validate the string is a valid sub-type of the embeddable class?
return (ManagedDomainType) baseType;
}
final String importedClassName = metamodel.getImportedClassName( subTypeName );
if ( importedClassName != null ) {
// first, try to find it by name directly..
ManagedDomainType<S> subManagedType = metamodel.entity( importedClassName );
if ( subManagedType != null ) {
return subManagedType;
}
// first, try to find it by name directly..
ManagedDomainType<S> subManagedType = jpaMetamodel.entity( subTypeName );
if ( subManagedType != null ) {
return subManagedType;
}
// it could still be a mapped-superclass
try {
final Class<S> subTypeClass = sessionFactory.getServiceRegistry()
.getService( ClassLoaderService.class )
.classForName( importedClassName );
return metamodel.managedType( subTypeClass );
}
catch (Exception ignore) {
}
// it could still be a mapped-superclass
try {
final Class javaType = jpaMetamodel.getServiceRegistry()
.getService( ClassLoaderService.class )
.classForName( subTypeName );
return jpaMetamodel.managedType( javaType );
}
catch (Exception ignore) {
}
throw new IllegalArgumentException( "Unknown sub-type name (" + baseType.getTypeName() + ") : " + subTypeName );
@ -67,10 +61,9 @@ public class DomainModelHelper {
public static <S> ManagedDomainType<S> resolveSubType(
ManagedDomainType<? super S> baseType,
Class<S> subTypeClass,
SessionFactoryImplementor sessionFactory) {
JpaMetamodel jpaMetamodel) {
// todo : validate the hierarchy-ness...
final MetamodelImplementor metamodel = sessionFactory.getMetamodel();
return metamodel.managedType( subTypeClass );
return jpaMetamodel.managedType( subTypeClass );
}

View File

@ -9,13 +9,11 @@ package org.hibernate.metamodel.model.domain.internal;
import java.io.Serializable;
import java.util.Map;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.internal.SubGraphImpl;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.metamodel.model.domain.AbstractManagedType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.type.ComponentType;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
@ -29,33 +27,20 @@ public class EmbeddableTypeImpl<J>
extends AbstractManagedType<J>
implements EmbeddableDomainType<J>, Serializable {
private final ManagedDomainType<?> parent;
private final ComponentType hibernateType;
public EmbeddableTypeImpl(
JavaTypeDescriptor<J> javaTypeDescriptor,
ManagedDomainType<?> parent,
ComponentType hibernateType,
SessionFactoryImplementor sessionFactory) {
super( javaTypeDescriptor.getJavaType().getName(), javaTypeDescriptor, null, sessionFactory );
this.parent = parent;
this.hibernateType = hibernateType;
public EmbeddableTypeImpl(JavaTypeDescriptor<J> javaTypeDescriptor, NodeBuilder nodeBuilder) {
super( javaTypeDescriptor.getJavaType().getName(), javaTypeDescriptor, null, nodeBuilder.getDomainModel() );
}
public EmbeddableTypeImpl(
String name,
ManagedDomainType<?> parent,
ComponentType hibernateType,
SessionFactoryImplementor sessionFactory) {
NodeBuilder nodeBuilder) {
//noinspection unchecked
super(
name,
(JavaTypeDescriptor) sessionFactory.getMetamodel().getTypeConfiguration().getJavaTypeDescriptorRegistry().getDescriptor( Map.class ),
(JavaTypeDescriptor) nodeBuilder.getDomainModel().getTypeConfiguration().getJavaTypeDescriptorRegistry().getDescriptor( Map.class ),
null,
sessionFactory
nodeBuilder.getDomainModel()
);
this.parent = parent;
this.hibernateType = hibernateType;
}
@Override
@ -63,17 +48,9 @@ public class EmbeddableTypeImpl<J>
return PersistenceType.EMBEDDABLE;
}
public ManagedDomainType<?> getParent() {
return parent;
}
public ComponentType getHibernateType() {
return hibernateType;
}
@Override
@SuppressWarnings("unchecked")
public <S extends J> SubGraphImplementor<S> makeSubGraph(Class<S> subType) {
return new SubGraphImpl( this, true, sessionFactory() );
return new SubGraphImpl( this, true, jpaMetamodel() );
}
}

View File

@ -9,7 +9,6 @@ package org.hibernate.metamodel.model.domain.internal;
import java.io.Serializable;
import javax.persistence.metamodel.EntityType;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.internal.SubGraphImpl;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.mapping.PersistentClass;
@ -17,8 +16,8 @@ import org.hibernate.metamodel.model.domain.AbstractIdentifiableType;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
@ -34,12 +33,11 @@ public class EntityTypeImpl<J>
implements EntityDomainType<J>, Serializable {
private final String jpaEntityName;
@SuppressWarnings("unchecked")
public EntityTypeImpl(
JavaTypeDescriptor<J> javaTypeDescriptor,
IdentifiableDomainType<? super J> superType,
PersistentClass persistentClass,
SessionFactoryImplementor sessionFactory) {
JpaMetamodel jpaMetamodel) {
super(
persistentClass.getEntityName(),
javaTypeDescriptor,
@ -47,7 +45,7 @@ public class EntityTypeImpl<J>
persistentClass.getDeclaredIdentifierMapper() != null || ( superType != null && superType.hasIdClass() ),
persistentClass.hasIdentifierProperty(),
persistentClass.isVersioned(),
sessionFactory
jpaMetamodel
);
this.jpaEntityName = persistentClass.getJpaEntityName();
}
@ -74,16 +72,7 @@ public class EntityTypeImpl<J>
@Override
public SqmPathSource<?> findSubPathSource(String name) {
return findAttribute( name );
}
@Override
public SemanticPathPart resolvePathPart(
String name,
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
return findAttribute( name );
return (SqmPathSource<?>) findAttribute( name );
}
@Override
@ -124,7 +113,7 @@ public class EntityTypeImpl<J>
);
}
return new SubGraphImpl( this, true, sessionFactory() );
return new SubGraphImpl( this, true, jpaMetamodel() );
}
@Override

View File

@ -0,0 +1,146 @@
/*
* 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.metamodel.model.domain.internal;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
*/
public class JpaMetamodelImpl implements JpaMetamodel {
private static final String INVALID_IMPORT = "";
private final TypeConfiguration typeConfiguration;
private final Map<String, EntityDomainType<?>> entityDescriptorMap;
private final Map<Class, EntityDomainType<?>> strictEntityDescriptorMap;
private final Map<Class, EmbeddableDomainType<?>> embeddableDescriptorMap;
private final Map<Class,String> entityProxyInterfaceMap = new ConcurrentHashMap<>();
private final Map<String,String> nameToImportNameMap = new ConcurrentHashMap<>();
private final Map<Class, SqmPolymorphicRootDescriptor<?>> polymorphicEntityReferenceMap = new ConcurrentHashMap<>();
public JpaMetamodelImpl(TypeConfiguration typeConfiguration) {
this.typeConfiguration = typeConfiguration;
}
@Override
public <X> EntityDomainType<X> resolveHqlEntityReference(String entityName) {
final String rename = resolveImportedName( entityName );
if ( rename != null ) {
entityName = rename;
}
final EntityDomainType<X> entityDescriptor = entity( entityName );
if ( entityDescriptor != null ) {
return entityDescriptor;
}
final Class<X> requestedClass = resolveRequestedClass( entityName );
if ( requestedClass != null ) {
return resolveEntityReference( requestedClass );
}
throw new IllegalArgumentException( "Could not resolve entity reference " + entityName );
}
private String resolveImportedName(String name) {
String result = nameToImportNameMap.get( name );
if ( result == null ) {
// see if the name is a fully-qualified class name
try {
getServiceRegistry().getService( ClassLoaderService.class ).classForName( name );
// it is a fully-qualified class name - add it to the cache
// so we do not keep trying later
nameToImportNameMap.put( name, name );
return name;
}
catch ( ClassLoadingException cnfe ) {
// it is a NOT fully-qualified class name - add a marker entry
// so we do not keep trying later
nameToImportNameMap.put( name, INVALID_IMPORT );
return null;
}
}
else {
// explicitly check for same instance
//noinspection StringEquality
if ( result == INVALID_IMPORT ) {
return null;
}
else {
return result;
}
}
}
private <X> Class<X> resolveRequestedClass(String entityName) {
try {
return getServiceRegistry().getService( ClassLoaderService.class ).classForName( entityName );
}
catch (ClassLoadingException e) {
return null;
}
}
@SuppressWarnings("unchecked")
public <T> EntityDomainType<T> resolveEntityReference(Class<T> javaType) {
// try the incoming Java type as a "strict" entity reference
{
final EntityDomainType<?> descriptor = strictEntityDescriptorMap.get( javaType );
if ( descriptor != null ) {
return (EntityDomainType<T>) descriptor;
}
}
// Next, try it as a proxy interface reference
{
final String proxyEntityName = entityProxyInterfaceMap.get( javaType );
if ( proxyEntityName != null ) {
return (EntityDomainType<T>) entityDescriptorMap.get( proxyEntityName );
}
}
// otherwise, try to handle it as a polymorphic reference
{
if ( polymorphicEntityReferenceMap.containsKey( javaType ) ) {
return (EntityDomainType<T>) polymorphicEntityReferenceMap.get( javaType );
}
final Set<EntityDomainType<?>> matchingDescriptors = new HashSet<>();
visitEntityTypes(
entityDomainType -> {
if ( javaType.isAssignableFrom( entityDomainType.getJavaType() ) ) {
matchingDescriptors.add( entityDomainType );
}
}
);
if ( !matchingDescriptors.isEmpty() ) {
final SqmPolymorphicRootDescriptor descriptor = new SqmPolymorphicRootDescriptor(
typeConfiguration.getJavaTypeDescriptorRegistry().resolveDescriptor( javaType ),
matchingDescriptors
);
polymorphicEntityReferenceMap.put( javaType, descriptor );
return descriptor;
}
}
throw new IllegalArgumentException( "Could not resolve entity reference : " + javaType.getName() );
}
}

View File

@ -8,6 +8,7 @@ package org.hibernate.metamodel.model.domain.internal;
import java.util.List;
import org.hibernate.metamodel.ValueClassification;
import org.hibernate.metamodel.model.domain.ListPersistentAttribute;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
@ -22,10 +23,17 @@ import org.hibernate.query.sqm.tree.from.SqmFrom;
class ListAttributeImpl<X, E> extends AbstractPluralAttribute<X, List<E>, E> implements ListPersistentAttribute<X, E> {
private final SqmPathSource<Integer> indexPathSource;
ListAttributeImpl(PluralAttributeBuilder<X, List<E>, E, ?> xceBuilder) {
super( xceBuilder );
ListAttributeImpl(PluralAttributeBuilder<X, List<E>, E, ?> builder) {
super( builder );
indexPathSource =
//noinspection unchecked
this.indexPathSource = (SqmPathSource) DomainModelHelper.resolveSqmPathSource(
ValueClassification.BASIC,
getName(),
builder.getListIndexOrMapKeyType(),
BindableType.PLURAL_ATTRIBUTE,
builder.getNodeBuilder()
);
}
@Override
@ -33,6 +41,11 @@ class ListAttributeImpl<X, E> extends AbstractPluralAttribute<X, List<E>, E> imp
return CollectionType.LIST;
}
@Override
public SqmPathSource<Integer> getIndexPathSource() {
return indexPathSource;
}
@Override
public SqmAttributeJoin createSqmJoin(
SqmFrom lhs,

View File

@ -7,12 +7,11 @@
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.model.domain.AbstractIdentifiableType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
@ -25,7 +24,7 @@ public class MappedSuperclassTypeImpl<X> extends AbstractIdentifiableType<X> imp
JavaTypeDescriptor<X> javaTypeDescriptor,
MappedSuperclass mappedSuperclass,
IdentifiableDomainType<? super X> superType,
SessionFactoryImplementor sessionFactory) {
JpaMetamodel jpaMetamodel) {
super(
javaTypeDescriptor.getJavaType().getName(),
javaTypeDescriptor,
@ -33,7 +32,7 @@ public class MappedSuperclassTypeImpl<X> extends AbstractIdentifiableType<X> imp
mappedSuperclass.getDeclaredIdentifierMapper() != null || ( superType != null && superType.hasIdClass() ),
mappedSuperclass.hasIdentifierProperty(),
mappedSuperclass.isVersioned(),
sessionFactory
jpaMetamodel
);
}

View File

@ -13,8 +13,8 @@ import java.util.Map;
import java.util.Set;
import org.hibernate.mapping.Property;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.metamodel.AttributeClassification;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.query.sqm.NodeBuilder;
@ -29,7 +29,7 @@ public class PluralAttributeBuilder<D, C, E, K> {
private final NodeBuilder nodeBuilder;
private SimpleDomainType<K> keyType;
private SimpleDomainType<K> listIndexOrMapKeyType;
private AttributeClassification attributeClassification;
private CollectionClassification collectionClassification;
@ -42,12 +42,12 @@ public class PluralAttributeBuilder<D, C, E, K> {
ManagedDomainType<D> ownerType,
SimpleDomainType<E> elementType,
JavaTypeDescriptor<C> collectionJavaTypeDescriptor,
SimpleDomainType<K> keyType,
SimpleDomainType<K> listIndexOrMapKeyType,
NodeBuilder nodeBuilder) {
this.declaringType = ownerType;
this.valueType = elementType;
this.collectionJavaTypeDescriptor = collectionJavaTypeDescriptor;
this.keyType = keyType;
this.listIndexOrMapKeyType = listIndexOrMapKeyType;
this.nodeBuilder = nodeBuilder;
}
@ -67,8 +67,8 @@ public class PluralAttributeBuilder<D, C, E, K> {
return collectionClassification;
}
public SimpleDomainType<K> getKeyType() {
return keyType;
public SimpleDomainType<K> getListIndexOrMapKeyType() {
return listIndexOrMapKeyType;
}
public JavaTypeDescriptor<C> getCollectionJavaTypeDescriptor() {

View File

@ -90,6 +90,11 @@ public class SingularAttributeImpl<D,J>
}
}
@Override
public String getPathName() {
return getName();
}
@Override
public SimpleDomainType<J> getSqmPathType() {
//noinspection unchecked

View File

@ -0,0 +1,175 @@
/*
* 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.metamodel.spi;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.graph.RootGraph;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Access to information about Hibernate's runtime type system
*
* @author Steve Ebersole
*/
public interface RuntimeModel {
TypeConfiguration getTypeConfiguration();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Entity descriptors
/**
* Given a JPA entity domain type, get the associated Hibernate entity descriptor
*/
EntityPersister resolveEntityDescriptor(EntityDomainType<?> entityDomainType);
/**
* Visit all entity mapping descriptors defined in the model
*/
void visitEntityDescriptors(Consumer<EntityPersister> action);
/**
* Get an entity mapping descriptor based on its Hibernate entity-name
*
* @throws IllegalArgumentException if the name does not refer to an entity
*
* @see #findEntityDescriptor
*/
EntityPersister getEntityDescriptor(String entityName);
/**
* Get an entity mapping descriptor based on its NavigableRole.
*
* @throws IllegalArgumentException if the name does not refer to an entity
*
* @see #findEntityDescriptor
*/
EntityPersister getEntityDescriptor(NavigableRole name);
/**
* Get an entity mapping descriptor based on its Class.
*
* @throws IllegalArgumentException if the name does not refer to an entity
*
* @see #findEntityDescriptor
*/
EntityPersister getEntityDescriptor(Class entityJavaType);
/**
* Find an entity mapping descriptor based on its Hibernate entity-name.
*
* @apiNote Returns {@code null} rather than throwing exception
*/
EntityPersister findEntityDescriptor(String entityName);
/**
* Find an entity mapping descriptor based on its Class.
*
* @apiNote Returns {@code null} rather than throwing exception
*/
EntityPersister findEntityDescriptor(Class entityJavaType);
/**
* Locate an entity mapping descriptor by Class. The passed Class might
* refer to either the entity Class directly, or it might name a proxy
* interface for the entity. This method accounts for both, preferring the
* direct entity name.
*
* @throws org.hibernate.UnknownEntityTypeException If a matching EntityPersister cannot be located
*/
EntityPersister locateEntityDescriptor(Class byClass);
/**
* @see #locateEntityDescriptor
*
* @deprecated (since 6.0) use {@link #locateEntityDescriptor(Class)} instead
*/
@Deprecated
default EntityPersister locateEntityPersister(Class byClass) {
return locateEntityDescriptor( byClass );
}
/**
* Locate the entity persister by name.
*
* @return The located EntityPersister, never {@code null}
*
* @throws org.hibernate.UnknownEntityTypeException If a matching EntityPersister cannot be located
*
* @deprecated (since 6.0) - use {@link #getEntityDescriptor(String)} instead
*/
@Deprecated
EntityPersister locateEntityPersister(String byName);
String getImportedName(String name);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Collection descriptors
/**
* Visit the mapping descriptors for all collections defined in the model
*/
void visitCollectionDescriptors(Consumer<CollectionPersister> action);
/**
* Get a collection mapping descriptor based on its role
*
* @throws IllegalArgumentException if the role does not refer to a collection
*
* @see #findCollectionDescriptor
*/
CollectionPersister getCollectionDescriptor(String role);
/**
* Get a collection mapping descriptor based on its role
*
* @throws IllegalArgumentException if the role does not refer to a collection
*
* @see #findCollectionDescriptor
*/
CollectionPersister getCollectionDescriptor(NavigableRole role);
/**
* Find a collection mapping descriptor based on its role. Returns
* {@code null} if the role does not refer to a collection
*
* @see #findCollectionDescriptor
*/
CollectionPersister findCollectionDescriptor(NavigableRole role);
/**
* Find a collection mapping descriptor based on its role. Returns
* {@code null} if the role does not refer to a collection
*
* @see #findCollectionDescriptor
*/
CollectionPersister findCollectionDescriptor(String role);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA entity graphs
RootGraph<?> findNamedGraph(String name);
void visitNamedGraphs(Consumer<RootGraph<?>> action);
RootGraph<?> defaultGraph(String entityName);
RootGraph<?> defaultGraph(Class entityJavaType);
RootGraph<?> defaultGraph(EntityPersister entityDescriptor);
RootGraph<?> defaultGraph(EntityDomainType<?> entityDomainType);
List<RootGraph<?>> findRootGraphsForType(Class baseEntityJavaType);
List<RootGraph<?>> findRootGraphsForType(String baseEntityName);
List<RootGraph<?>> findRootGraphsForType(EntityPersister baseEntityDescriptor);
}

View File

@ -0,0 +1,82 @@
/*
* 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.query;
/**
* Defines the comparison operators. We could also get away with
* only 3 and use negation...
*/
public enum ComparisonOperator {
EQUAL {
public ComparisonOperator negated() {
return NOT_EQUAL;
}
@Override
public String sqlText() {
return "=";
}
},
NOT_EQUAL {
public ComparisonOperator negated() {
return EQUAL;
}
@Override
public String sqlText() {
return "!=";
}
},
LESS_THAN {
public ComparisonOperator negated() {
return GREATER_THAN_OR_EQUAL;
}
@Override
public String sqlText() {
return "<";
}
},
LESS_THAN_OR_EQUAL {
public ComparisonOperator negated() {
return GREATER_THAN;
}
@Override
public String sqlText() {
return "<=";
}
},
GREATER_THAN {
public ComparisonOperator negated() {
return LESS_THAN_OR_EQUAL;
}
@Override
public String sqlText() {
return ">";
}
},
GREATER_THAN_OR_EQUAL {
public ComparisonOperator negated() {
return LESS_THAN;
}
@Override
public String sqlText() {
return ">=";
}
};
public abstract ComparisonOperator negated();
public abstract String sqlText();
}

View File

@ -0,0 +1,37 @@
/*
* 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.query;
import java.util.List;
import java.util.Map;
/**
* Represents the type of instantiation to be performed.
*
* @author Steve Ebersole
*/
public enum DynamicInstantiationNature {
/**
* The target names a Class to be instantiated. This is the only form
* of dynamic instantiation that is JPA-compliant.
*/
CLASS,
/**
* The target identified a {@link Map} instantiation. The
* result for each "row" will be a Map whose key is the alias (or name
* of the selected attribute is no alias) and whose value is the
* corresponding value read from the JDBC results. Similar to JPA's
* named-Tuple support.
*/
MAP,
/**
* The target identified a {@link List} instantiation. The
* result for each "row" will be a List rather than an array. Similar
* to JPA's positional-Tuple support.
*/
LIST
}

View File

@ -0,0 +1,40 @@
/*
* 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.query.hql.internal;
import org.jboss.logging.Logger;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Token;
/**
* Leverages Antlr to build a parse tree from an HQL query
*
* @author Steve Ebersole
*/
public class HqlParseTreeBuilder {
private static final Logger log = Logger.getLogger( HqlParseTreeBuilder.class );
/**
* Singleton access
*/
public static final HqlParseTreeBuilder INSTANCE = new HqlParseTreeBuilder();
public HqlParser parseHql(String hql) {
// Build the lexer
HqlLexer hqlLexer = new HqlLexer( CharStreams.fromString( hql ) );
// Build the parser...
return new HqlParser( new CommonTokenStream( hqlLexer ) ) {
@Override
protected void logUseOfReservedWordAsIdentifier(Token token) {
log.debugf( "Encountered use of reserved word as identifier : " + token.getText() );
}
};
}
}

View File

@ -0,0 +1,133 @@
/*
* 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.query.hql.internal;
import org.hibernate.query.QueryLogger;
import org.jboss.logging.Logger;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
/**
* Used to
* @author Steve Ebersole
*/
@SuppressWarnings("WeakerAccess")
public class HqlParseTreePrinter extends HqlParserBaseListener {
private static final Logger HQL_LOGGER = QueryLogger.subLogger( "hql.parseTree" );
private static final boolean LOG_DEBUG_ENABLED = HQL_LOGGER.isDebugEnabled();
public static void logStatementParseTree(HqlParser parser) {
if ( !LOG_DEBUG_ENABLED ) {
return;
}
final HqlParseTreePrinter walker = new HqlParseTreePrinter( parser );
ParseTreeWalker.DEFAULT.walk( walker, parser.statement() );
HQL_LOGGER.debugf( "HQL parse-tree:\n%s", walker.buffer.toString() );
parser.reset();
}
public static void logOrderByParseTree(HqlParser parser) {
if ( !LOG_DEBUG_ENABLED ) {
return;
}
final HqlParseTreePrinter walker = new HqlParseTreePrinter( parser );
ParseTreeWalker.DEFAULT.walk( walker, parser.orderByClause() );
HQL_LOGGER.debugf( "Mapping order-by parse-tree:\n%s", walker.buffer.toString() );
parser.reset();
}
private final HqlParser parser;
private final StringBuffer buffer = new StringBuffer();
private int depth = 2;
public HqlParseTreePrinter(HqlParser parser) {
this.parser = parser;
}
private enum LineType {
ENTER,
EXIT
}
@Override
public void enterEveryRule(ParserRuleContext ctx) {
final String ruleName = parser.getRuleNames()[ctx.getRuleIndex()];
if ( !ruleName.endsWith( "Keyword" ) ) {
applyLine( LineType.ENTER, ruleName, ruleTypeName( ctx.getClass() ), ctx.getText() );
}
super.enterEveryRule( ctx );
}
private String ruleTypeName(Class<? extends ParserRuleContext> ruleCtxClass) {
final String name = ruleCtxClass.getSimpleName();
final int position = name.lastIndexOf( "Context" );
if ( position > 1 ) {
return name.substring( 0, position );
}
else {
// todo (6.0) : does this ever happen?
return name;
}
}
private void applyLine(
LineType lineType,
String ruleName,
String ruleTypeName,
String ctxText) {
applyLinePadding( lineType );
buffer.append( '[' ).append( ruleName );
if ( ! ruleTypeName.equalsIgnoreCase( ruleName ) ) {
buffer.append( " (" ).append( ruleTypeName ).append( ')' );
}
buffer.append( ']' )
.append( " - `" ).append( ctxText ).append( '`' )
.append( '\n' );
}
private void applyLinePadding(LineType lineType) {
if ( lineType == LineType.ENTER ) {
pad( depth++ );
buffer.append( "-> " );
}
else {
pad( --depth );
buffer.append( "<- " );
}
}
private String pad(int depth) {
for ( int i = 0; i < depth; i++ ) {
buffer.append( " " );
}
return buffer.toString();
}
@Override
public void exitEveryRule(ParserRuleContext ctx) {
super.exitEveryRule( ctx );
final String ruleName = parser.getRuleNames()[ctx.getRuleIndex()];
applyLine( LineType.EXIT, ruleName, ruleTypeName( ctx.getClass() ), ctx.getText() );
}
}

View File

@ -21,26 +21,16 @@ import org.hibernate.NullPrecedence;
import org.hibernate.SortOrder;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.collection.spi.CollectionClassification;
import org.hibernate.internal.util.collections.Stack;
import org.hibernate.internal.util.collections.StandardStack;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.mapping.IdentifiableTypeDescriptor;
import org.hibernate.metamodel.model.mapping.PersistentCollectionDescriptor;
import org.hibernate.metamodel.model.mapping.spi.AllowableFunctionReturnType;
import org.hibernate.metamodel.model.mapping.spi.BagPersistentAttribute;
import org.hibernate.metamodel.model.mapping.spi.EntityValuedNavigable;
import org.hibernate.metamodel.model.mapping.spi.ListPersistentAttribute;
import org.hibernate.metamodel.model.mapping.spi.MapPersistentAttribute;
import org.hibernate.metamodel.model.mapping.spi.Navigable;
import org.hibernate.metamodel.model.mapping.spi.NavigableContainer;
import org.hibernate.metamodel.model.mapping.spi.PluralValuedNavigable;
import org.hibernate.metamodel.model.mapping.spi.SingularPersistentAttribute;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.BinaryArithmeticOperator;
import org.hibernate.query.ComparisonOperator;
import org.hibernate.query.QueryLogger;
import org.hibernate.query.UnaryArithmeticOperator;
import org.hibernate.query.hql.DotIdentifierConsumer;
import org.hibernate.query.spi.ComparisonOperator;
import org.hibernate.query.sqm.LiteralNumberFormatException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.ParsingException;
@ -143,12 +133,8 @@ import org.hibernate.query.sqm.tree.select.SqmSortSpecification;
import org.hibernate.query.sqm.tree.select.SqmSubQuery;
import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
import org.hibernate.sql.TrimSpec;
import org.hibernate.sql.ast.produce.metamodel.spi.BasicValuedExpressableType;
import org.hibernate.sql.ast.produce.metamodel.spi.EntityValuedExpressableType;
import org.hibernate.sql.ast.produce.metamodel.spi.ExpressableType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.spi.BasicJavaDescriptor;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.jboss.logging.Logger;
@ -326,7 +312,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
@Override
public SqmInsertSelectStatement visitInsertStatement(HqlParser.InsertStatementContext ctx) {
final EntityTypeDescriptor<?> targetType = visitEntityName( ctx.insertSpec().intoSpec().entityName() );
final EntityDomainType<?> targetType = visitEntityName( ctx.insertSpec().intoSpec().entityName() );
final SqmRoot<?> root = new SqmRoot<>( targetType, null, creationContext.getNodeBuilder() );
processingStateStack.getCurrent().getPathRegistry().register( root );
@ -636,7 +622,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
final JavaTypeDescriptor jtd = creationContext.getDomainModel()
.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getOrMakeJavaDescriptor( targetJavaType );
.resolveDescriptor( targetJavaType );
dynamicInstantiation = SqmDynamicInstantiation.forClassInstantiation(
jtd,
creationContext.getNodeBuilder()
@ -837,21 +823,21 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
@Override
public EntityTypeDescriptor<?> visitEntityName(HqlParser.EntityNameContext parserEntityName) {
public EntityDomainType<?> visitEntityName(HqlParser.EntityNameContext parserEntityName) {
final String entityName = parserEntityName.dotIdentifierSequence().getText();
final EntityValuedExpressableType entityReference = resolveEntityReference( entityName );
final EntityDomainType entityReference = resolveEntityReference( entityName );
if ( entityReference == null ) {
throw new UnknownEntityException( "Could not resolve entity name [" + entityName + "] as DML target", entityName );
}
return entityReference.getEntityDescriptor();
return entityReference;
}
private EntityValuedExpressableType resolveEntityReference(String entityName) {
private EntityDomainType resolveEntityReference(String entityName) {
log.debugf( "Attempting to resolve path [%s] as entity reference...", entityName );
EntityValuedExpressableType reference = null;
EntityDomainType reference = null;
try {
reference = creationContext.getDomainModel().resolveEntityReference( entityName );
reference = creationContext.getDomainModel().entity( entityName );
}
catch (Exception ignore) {
}
@ -904,12 +890,12 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
log.debugf( "Handling root path - %s", name );
final EntityTypeDescriptor entityDescriptor = getCreationContext().getDomainModel().resolveEntityReference( name );
final EntityDomainType entityDescriptor = getCreationContext().getDomainModel().resolveHqlEntityReference( name );
if ( entityDescriptor instanceof SqmPolymorphicRootDescriptor ) {
if ( getCreationOptions().useStrictJpaCompliance() ) {
throw new StrictJpaComplianceViolation(
"Encountered unmapped polymorphic reference [" + entityDescriptor.getEntityName()
"Encountered unmapped polymorphic reference [" + entityDescriptor.getHibernateEntityName()
+ "], but strict JPQL compliance was requested",
StrictJpaComplianceViolation.Type.UNMAPPED_POLYMORPHISM
);
@ -974,21 +960,21 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
throw new UnsupportedOperationException( "Unexpected call to #visitCrossJoin, see #consumeCrossJoin" );
}
@SuppressWarnings("unchecked")
private void consumeCrossJoin(HqlParser.CrossJoinContext parserJoin, SqmRoot sqmRoot) {
final String name = parserJoin.pathRoot().entityName().getText();
SqmTreeCreationLogger.LOGGER.debugf( "Handling root path - %s", name );
final EntityValuedExpressableType entityType = getCreationContext().getDomainModel().resolveEntityReference( name );
final EntityDomainType entityDescriptor = getCreationContext().getDomainModel().resolveHqlEntityReference( name );
if ( entityType instanceof SqmPolymorphicRootDescriptor ) {
if ( entityDescriptor instanceof SqmPolymorphicRootDescriptor ) {
throw new SemanticException( "Unmapped polymorphic reference cannot be used as a CROSS JOIN target" );
}
final EntityTypeDescriptor entityDescriptor = entityType.getEntityDescriptor();
final SqmCrossJoin join = new SqmCrossJoin(
entityDescriptor, visitIdentificationVariableDef( parserJoin.pathRoot().identificationVariableDef() ),
entityDescriptor,
visitIdentificationVariableDef( parserJoin.pathRoot().identificationVariableDef() ),
sqmRoot
);
@ -1236,7 +1222,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public SqmPredicate visitMemberOfPredicate(HqlParser.MemberOfPredicateContext ctx) {
final SqmPath sqmPluralPath = consumeDomainPath( ctx.path() );
if ( sqmPluralPath.getReferencedPathSource() instanceof PluralValuedNavigable ) {
if ( sqmPluralPath.getReferencedPathSource() instanceof PluralPersistentAttribute ) {
return new SqmMemberOfPredicate( sqmPluralPath, creationContext.getNodeBuilder() );
}
else {

View File

@ -0,0 +1,62 @@
/*
* 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.query.hql.internal;
import org.hibernate.QueryException;
import org.hibernate.query.sqm.InterpretationException;
import org.hibernate.query.hql.SemanticQueryProducer;
import org.hibernate.query.sqm.produce.internal.SqmTreePrinter;
import org.hibernate.query.sqm.produce.spi.SqmCreationContext;
import org.hibernate.query.sqm.produce.spi.SqmCreationOptions;
import org.hibernate.query.sqm.tree.SqmStatement;
/**
* Standard implementation of SemanticQueryInterpreter
*
* @author Steve Ebersole
*/
public class SemanticQueryProducerImpl implements SemanticQueryProducer {
private final SqmCreationContext sqmCreationContext;
private final SqmCreationOptions sqmCreationOptions;
public SemanticQueryProducerImpl(
SqmCreationContext sqmCreationContext,
SqmCreationOptions sqmCreationOptions) {
this.sqmCreationContext = sqmCreationContext;
this.sqmCreationOptions = sqmCreationOptions;
}
@Override
public SqmStatement interpret(String query) {
// final ParsingContext parsingContext = ;
// first, ask Antlr to build the parse tree
final HqlParser parser = HqlParseTreeBuilder.INSTANCE.parseHql( query );
// Log the parse tree (if enabled)
HqlParseTreePrinter.logStatementParseTree( parser );
// then we perform semantic analysis and build the semantic representation...
try {
final SqmStatement sqmStatement = SemanticQueryBuilder.buildSemanticModel(
parser.statement(),
sqmCreationOptions,
sqmCreationContext
);
SqmTreePrinter.logTree( sqmStatement );
return sqmStatement;
}
catch (QueryException e) {
throw e;
}
catch (Exception e) {
throw new InterpretationException( query, e );
}
}
}

View File

@ -32,6 +32,7 @@ import javax.persistence.criteria.Subquery;
import org.hibernate.NullPrecedence;
import org.hibernate.SortOrder;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.query.criteria.JpaCoalesce;
@ -71,7 +72,7 @@ import org.hibernate.type.spi.TypeConfiguration;
*/
@SuppressWarnings("unchecked")
public interface NodeBuilder extends HibernateCriteriaBuilder {
MetamodelImplementor getDomainModel();
JpaMetamodel getDomainModel();
default TypeConfiguration getTypeConfiguration() {
return getDomainModel().getTypeConfiguration();

View File

@ -37,8 +37,8 @@ import org.hibernate.QueryException;
import org.hibernate.SortOrder;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.mapping.spi.AllowableFunctionReturnType;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.BinaryArithmeticOperator;
import org.hibernate.query.UnaryArithmeticOperator;
import org.hibernate.query.criteria.JpaCoalesce;
@ -97,9 +97,7 @@ import org.hibernate.query.sqm.tree.select.SqmSubQuery;
import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.TrimSpec;
import org.hibernate.sql.ast.produce.metamodel.spi.BasicValuedExpressableType;
import org.hibernate.query.sqm.tree.expression.function.SqmFunction;
import org.hibernate.type.spi.StandardSpiBasicTypes;
import static java.util.Arrays.asList;
import static org.hibernate.query.internal.QueryHelper.highestPrecedenceType;
@ -112,12 +110,12 @@ import static org.hibernate.query.internal.QueryHelper.highestPrecedenceType;
*/
public class SqmCriteriaNodeBuilder implements NodeBuilder {
private final QueryEngine queryEngine;
private final MetamodelImplementor domainModel;
private final JpaMetamodel domainModel;
private final ServiceRegistry serviceRegistry;
public SqmCriteriaNodeBuilder(
QueryEngine queryEngine,
MetamodelImplementor domainModel,
JpaMetamodel domainModel,
ServiceRegistry serviceRegistry) {
this.queryEngine = queryEngine;
this.domainModel = domainModel;
@ -125,7 +123,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder {
}
@Override
public MetamodelImplementor getDomainModel() {
public JpaMetamodel getDomainModel() {
return domainModel;
}

View File

@ -7,7 +7,7 @@
package org.hibernate.query.sqm.produce.spi;
import org.hibernate.Incubating;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.service.ServiceRegistry;
@ -22,12 +22,14 @@ public interface SqmCreationContext {
/**
* Access to the domain model metadata
*/
MetamodelImplementor getDomainModel();
JpaMetamodel getDomainModel();
/**
* Access to the ServiceRegistry for the context
*/
ServiceRegistry getServiceRegistry();
default ServiceRegistry getServiceRegistry() {
return getDomainModel().getServiceRegistry();
}
QueryEngine getQueryEngine();

View File

@ -23,14 +23,12 @@ import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SetAttribute;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
@ -38,7 +36,6 @@ import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Acts as the EntityValuedNavigable for a "polymorphic query" grouping
@ -49,17 +46,12 @@ public class SqmPolymorphicRootDescriptor<T> implements EntityDomainType<T> {
private final Set<EntityDomainType<?>> implementors;
private final Map<String, PersistentAttribute<? super T, ?>> commonAttributes;
private final NavigableRole navigableRole;
private final JavaTypeDescriptor<T> polymorphicJavaDescriptor;
private final SessionFactoryImplementor sessionFactory;
public SqmPolymorphicRootDescriptor(
JavaTypeDescriptor<T> polymorphicJavaDescriptor,
Set<EntityDomainType<?>> implementors,
SessionFactoryImplementor sessionFactory) {
Set<EntityDomainType<?>> implementors) {
this.polymorphicJavaDescriptor = polymorphicJavaDescriptor;
this.navigableRole = new NavigableRole( polymorphicJavaDescriptor.getJavaType().getName() );
this.sessionFactory = sessionFactory;
this.implementors = implementors;
@ -99,14 +91,6 @@ public class SqmPolymorphicRootDescriptor<T> implements EntityDomainType<T> {
return new HashSet<>( implementors );
}
public SessionFactoryImplementor getFactory() {
return sessionFactory;
}
public TypeConfiguration getTypeConfiguration() {
return getFactory().getMetamodel().getTypeConfiguration();
}
@Override
public String getName() {
return polymorphicJavaDescriptor.getJavaType().getName();

View File

@ -6,12 +6,12 @@
*/
package org.hibernate.query.sqm.tree.predicate;
import org.hibernate.query.ComparisonOperator;
import org.hibernate.query.internal.QueryHelper;
import org.hibernate.query.spi.ComparisonOperator;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.sql.ast.produce.metamodel.spi.ExpressableType;
/**
* @author Steve Ebersole
@ -31,12 +31,14 @@ public class SqmComparisonPredicate extends AbstractNegatableSqmPredicate {
this.rightHandExpression = rightHandExpression;
this.operator = operator;
final ExpressableType<?> expressableType = QueryHelper.highestPrecedenceType(
final SqmExpressable expressableType = QueryHelper.highestPrecedenceType(
leftHandExpression.getNodeType(),
rightHandExpression.getNodeType()
);
//noinspection unchecked
leftHandExpression.applyInferableType( expressableType );
//noinspection unchecked
rightHandExpression.applyInferableType( expressableType );
}

View File

@ -11,21 +11,20 @@ import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.hibernate.query.DynamicInstantiationNature;
import org.hibernate.query.criteria.JpaCompoundSelection;
import org.hibernate.query.criteria.JpaSelection;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.jpa.AbstractJpaSelection;
import org.hibernate.sql.ast.produce.metamodel.spi.ExpressableType;
import org.hibernate.sql.ast.tree.expression.instantiation.DynamicInstantiationNature;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.jboss.logging.Logger;
import static org.hibernate.sql.ast.tree.expression.instantiation.DynamicInstantiationNature.CLASS;
import static org.hibernate.sql.ast.tree.expression.instantiation.DynamicInstantiationNature.LIST;
import static org.hibernate.sql.ast.tree.expression.instantiation.DynamicInstantiationNature.MAP;
import static org.hibernate.query.DynamicInstantiationNature.CLASS;
import static org.hibernate.query.DynamicInstantiationNature.LIST;
import static org.hibernate.query.DynamicInstantiationNature.MAP;
/**
* Represents a dynamic instantiation ({@code select new XYZ(...) ...}) as part of the SQM.
@ -166,13 +165,12 @@ public class SqmDynamicInstantiation<T>
}
@Override
@SuppressWarnings("unchecked")
public <X> X accept(SemanticQueryWalker<X> walker) {
return walker.visitDynamicInstantiation( this );
}
public SqmDynamicInstantiation makeShallowCopy() {
return new SqmDynamicInstantiation( getInstantiationTarget(), nodeBuilder() );
public SqmDynamicInstantiation<T> makeShallowCopy() {
return new SqmDynamicInstantiation<>( getInstantiationTarget(), nodeBuilder() );
}
private static class DynamicInstantiationTargetImpl<T> implements SqmDynamicInstantiationTarget<T> {
@ -196,14 +194,9 @@ public class SqmDynamicInstantiation<T>
}
@Override
public JavaTypeDescriptor<T> getJavaTypeDescriptor() {
public JavaTypeDescriptor<T> getExpressableJavaTypeDescriptor() {
return getTargetTypeDescriptor();
}
@Override
public PersistenceType getPersistenceType() {
return PersistenceType.BASIC;
}
}
@ -224,6 +217,11 @@ public class SqmDynamicInstantiation<T>
return list;
}
@Override
public String getAlias() {
return null;
}
@Override
public JpaSelection<T> alias(String name) {
return null;
@ -233,19 +231,4 @@ public class SqmDynamicInstantiation<T>
public boolean isCompoundSelection() {
return false;
}
@Override
public String getAlias() {
return null;
}
@Override
public NodeBuilder nodeBuilder() {
return null;
}
@Override
public ExpressableType getNodeType() {
return null;
}
}

View File

@ -6,9 +6,10 @@
*/
package org.hibernate.query.sqm.tree.select;
import org.hibernate.sql.ast.produce.metamodel.spi.ExpressableType;
import org.hibernate.sql.ast.tree.expression.instantiation.DynamicInstantiationNature;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptor;
import org.hibernate.query.DynamicInstantiationNature;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* Represents the thing-to-be-instantiated in a dynamic instantiation expression. Hibernate
@ -16,7 +17,7 @@ import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptor;
*
* @author Steve Ebersole
*/
public interface SqmDynamicInstantiationTarget<T> extends ExpressableType<T> {
public interface SqmDynamicInstantiationTarget<T> extends SqmExpressable<T> {
/**
* Retrieves the enum describing the nature of this target.

View File

@ -0,0 +1,48 @@
/*
* 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.type.descriptor.java.spi;
import java.util.Map;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
/**
* @author Steve Ebersole
*/
public class MapEntryJavaDescriptor extends AbstractTypeDescriptor<Map.Entry> {
/**
* Singleton access
*/
public static final MapEntryJavaDescriptor INSTANCE = new MapEntryJavaDescriptor();
public MapEntryJavaDescriptor() {
super( Map.Entry.class );
}
@Override
public SqlTypeDescriptor getJdbcRecommendedSqlType(SqlTypeDescriptorIndicators context) {
throw new UnsupportedOperationException( "Unsupported attempt to resolve JDBC type for Map.Entry" );
}
@Override
public Map.Entry fromString(String string) {
throw new UnsupportedOperationException( "Unsupported attempt create Map.Entry from String" );
}
@Override
public <X> X unwrap(Map.Entry value, Class<X> type, SharedSessionContractImplementor session) {
throw new UnsupportedOperationException( "Unsupported attempt to unwrap Map.Entry value" );
}
@Override
public <X> Map.Entry wrap(X value, SharedSessionContractImplementor session) {
throw new UnsupportedOperationException( "Unsupported attempt to wrap Map.Entry value" );
}
}

View File

@ -8,6 +8,7 @@ package org.hibernate.type.spi;
import java.io.InvalidObjectException;
import java.io.Serializable;
import java.sql.Types;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@ -36,6 +37,7 @@ import org.hibernate.type.Type;
import org.hibernate.type.TypeFactory;
import org.hibernate.type.TypeResolver;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
import org.hibernate.type.descriptor.sql.spi.SqlTypeDescriptorRegistry;
import org.hibernate.type.internal.TypeConfigurationRegistry;
@ -66,9 +68,9 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
private final String uuid = LocalObjectUuidHelper.generateLocalObjectUuid();
private final Scope scope;
private final transient TypeFactory typeFactory;
// things available during both boot and runtime ("active") lifecycle phases
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// things available during both boot and runtime lifecycle phases
private final transient JavaTypeDescriptorRegistry javaTypeDescriptorRegistry;
private final transient SqlTypeDescriptorRegistry sqlTypeDescriptorRegistry;
private final transient BasicTypeRegistry basicTypeRegistry;
@ -78,14 +80,17 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
private final transient Map<Integer, Set<String>> jdbcToHibernateTypeContributionMap = new HashMap<>();
// temporarily needed to support deprecations
private final transient TypeFactory typeFactory;
private final transient TypeResolver typeResolver;
public TypeConfiguration() {
this.scope = new Scope();
this.scope = new Scope( this );
this.javaTypeDescriptorRegistry = new JavaTypeDescriptorRegistry( this );
this.sqlTypeDescriptorRegistry = new SqlTypeDescriptorRegistry( this );
this.basicTypeRegistry = new BasicTypeRegistry();
this.typeFactory = new TypeFactory( this );
this.typeResolver = new TypeResolver( this, typeFactory );
@ -127,6 +132,10 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
return Collections.unmodifiableMap( importMap );
}
public SqlTypeDescriptorIndicators getCurrentBaseSqlTypeIndicators() {
return scope.getCurrentBaseSqlTypeIndicators();
}
public Map<Integer, Set<String>> getJdbcToHibernateTypeContributionMap() {
return jdbcToHibernateTypeContributionMap;
}
@ -271,16 +280,34 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
* Each stage or phase is consider a "scope" for the TypeConfiguration.
*/
private static class Scope implements Serializable {
private final TypeConfiguration typeConfiguration;
// todo (6.0) : consider a proper contract implemented by both SessionFactory (or its metamodel) and boot's MetadataImplementor
// 1) type-related info from MetadataBuildingOptions
// 2) ServiceRegistry
private transient MetadataBuildingContext metadataBuildingContext;
private transient SessionFactoryImplementor sessionFactory;
private String sessionFactoryName;
private String sessionFactoryUuid;
private transient SqlTypeDescriptorIndicators currentSqlTypeIndicators = new SqlTypeDescriptorIndicators() {
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
@Override
public int getPreferredSqlTypeCodeForBoolean() {
return Types.BOOLEAN;
}
};
public Scope(TypeConfiguration typeConfiguration) {
this.typeConfiguration = typeConfiguration;
}
public SqlTypeDescriptorIndicators getCurrentBaseSqlTypeIndicators() {
return currentSqlTypeIndicators;
}
public MetadataBuildingContext getMetadataBuildingContext() {
if ( metadataBuildingContext == null ) {
throw new HibernateException( "TypeConfiguration is not currently scoped to MetadataBuildingContext" );