preliminary support for collections - lists and sets tested (excluding entity-valued elements and map-key)
This commit is contained in:
parent
093f410953
commit
c89ee3761a
|
@ -36,7 +36,8 @@ public class EnumeratedValueResolution<E extends Enum<E>> implements BasicValue.
|
||||||
this.domainJtd = domainJtd;
|
this.domainJtd = domainJtd;
|
||||||
this.jdbcJtd = jdbcJtd;
|
this.jdbcJtd = jdbcJtd;
|
||||||
this.std = std;
|
this.std = std;
|
||||||
this.valueConverter = valueConverter;
|
// this.valueConverter = valueConverter;
|
||||||
|
this.valueConverter = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
import org.hibernate.cache.spi.access.AccessType;
|
import org.hibernate.cache.spi.access.AccessType;
|
||||||
import org.hibernate.cfg.MetadataSourceType;
|
import org.hibernate.cfg.MetadataSourceType;
|
||||||
|
import org.hibernate.collection.internal.StandardCollectionSemanticsResolver;
|
||||||
import org.hibernate.collection.spi.CollectionSemanticsResolver;
|
import org.hibernate.collection.spi.CollectionSemanticsResolver;
|
||||||
import org.hibernate.dialect.function.SQLFunction;
|
import org.hibernate.dialect.function.SQLFunction;
|
||||||
import org.hibernate.metamodel.internal.StandardManagedTypeRepresentationResolver;
|
import org.hibernate.metamodel.internal.StandardManagedTypeRepresentationResolver;
|
||||||
|
@ -61,7 +62,8 @@ public interface MetadataBuildingOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
default CollectionSemanticsResolver getPersistentCollectionRepresentationResolver() {
|
default CollectionSemanticsResolver getPersistentCollectionRepresentationResolver() {
|
||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
// for now always return the standard one
|
||||||
|
return StandardCollectionSemanticsResolver.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,6 +21,8 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.loader.CollectionAliases;
|
import org.hibernate.loader.CollectionAliases;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.sql.results.spi.RowProcessingState;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
@ -190,6 +192,31 @@ public class PersistentArrayHolder extends AbstractPersistentCollection {
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object readFrom(
|
||||||
|
RowProcessingState rowProcessingState,
|
||||||
|
DomainResultAssembler elementAssembler,
|
||||||
|
DomainResultAssembler indexAssembler,
|
||||||
|
DomainResultAssembler identifierAssembler,
|
||||||
|
Object owner) throws HibernateException {
|
||||||
|
assert elementAssembler != null;
|
||||||
|
assert indexAssembler != null;
|
||||||
|
assert identifierAssembler == null;
|
||||||
|
|
||||||
|
final Object element = elementAssembler.assemble( rowProcessingState );
|
||||||
|
final int index = (int) indexAssembler.assemble( rowProcessingState );
|
||||||
|
|
||||||
|
for ( int i = tempList.size(); i<=index; i++) {
|
||||||
|
//noinspection unchecked
|
||||||
|
tempList.add( i, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
tempList.set( index, element );
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Iterator entries(CollectionPersister persister) {
|
public Iterator entries(CollectionPersister persister) {
|
||||||
|
|
|
@ -22,6 +22,8 @@ import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.loader.CollectionAliases;
|
import org.hibernate.loader.CollectionAliases;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.sql.results.spi.RowProcessingState;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,6 +135,24 @@ public class PersistentBag extends AbstractPersistentCollection implements List
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object readFrom(
|
||||||
|
RowProcessingState rowProcessingState,
|
||||||
|
DomainResultAssembler elementAssembler,
|
||||||
|
DomainResultAssembler indexAssembler,
|
||||||
|
DomainResultAssembler identifierAssembler,
|
||||||
|
Object owner) throws HibernateException {
|
||||||
|
assert indexAssembler == null;
|
||||||
|
assert identifierAssembler == null;
|
||||||
|
|
||||||
|
final Object element = elementAssembler.assemble( rowProcessingState );
|
||||||
|
if ( element != null ) {
|
||||||
|
//noinspection unchecked
|
||||||
|
bag.add( element );
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
|
public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
|
||||||
this.bag = (List) persister.getCollectionType().instantiate( anticipatedSize );
|
this.bag = (List) persister.getCollectionType().instantiate( anticipatedSize );
|
||||||
|
|
|
@ -22,6 +22,8 @@ import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.loader.CollectionAliases;
|
import org.hibernate.loader.CollectionAliases;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.sql.results.spi.RowProcessingState;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -372,6 +374,30 @@ public class PersistentIdentifierBag extends AbstractPersistentCollection implem
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object readFrom(
|
||||||
|
RowProcessingState rowProcessingState,
|
||||||
|
DomainResultAssembler elementAssembler,
|
||||||
|
DomainResultAssembler indexAssembler,
|
||||||
|
DomainResultAssembler identifierAssembler,
|
||||||
|
Object owner) throws HibernateException {
|
||||||
|
assert indexAssembler == null;
|
||||||
|
final Object element = elementAssembler.assemble( rowProcessingState );
|
||||||
|
final Object identifier = identifierAssembler.assemble( rowProcessingState );
|
||||||
|
|
||||||
|
final Object old = identifiers.put(
|
||||||
|
values.size(),
|
||||||
|
identifier
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( old == null ) {
|
||||||
|
//maintain correct duplication if loaded in a cartesian product
|
||||||
|
values.add( element );
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Serializable getSnapshot(CollectionPersister persister) throws HibernateException {
|
public Serializable getSnapshot(CollectionPersister persister) throws HibernateException {
|
||||||
|
|
|
@ -20,6 +20,8 @@ import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.loader.CollectionAliases;
|
import org.hibernate.loader.CollectionAliases;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.sql.results.spi.RowProcessingState;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -206,9 +208,9 @@ public class PersistentList extends AbstractPersistentCollection implements List
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public boolean containsAll(Collection coll) {
|
public boolean containsAll(Collection coll) {
|
||||||
read();
|
read();
|
||||||
|
//noinspection unchecked
|
||||||
return list.containsAll( coll );
|
return list.containsAll( coll );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,9 +264,9 @@ public class PersistentList extends AbstractPersistentCollection implements List
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public boolean retainAll(Collection coll) {
|
public boolean retainAll(Collection coll) {
|
||||||
initialize( true );
|
initialize( true );
|
||||||
|
//noinspection unchecked
|
||||||
if ( list.retainAll( coll ) ) {
|
if ( list.retainAll( coll ) ) {
|
||||||
dirty();
|
dirty();
|
||||||
return true;
|
return true;
|
||||||
|
@ -275,7 +277,6 @@ public class PersistentList extends AbstractPersistentCollection implements List
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
if ( isClearQueueEnabled() ) {
|
if ( isClearQueueEnabled() ) {
|
||||||
queueOperation( new Clear() );
|
queueOperation( new Clear() );
|
||||||
|
@ -290,7 +291,6 @@ public class PersistentList extends AbstractPersistentCollection implements List
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Object get(int index) {
|
public Object get(int index) {
|
||||||
if ( index < 0 ) {
|
if ( index < 0 ) {
|
||||||
throw new ArrayIndexOutOfBoundsException( "negative index" );
|
throw new ArrayIndexOutOfBoundsException( "negative index" );
|
||||||
|
@ -300,7 +300,6 @@ public class PersistentList extends AbstractPersistentCollection implements List
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Object set(int index, Object value) {
|
public Object set(int index, Object value) {
|
||||||
if (index<0) {
|
if (index<0) {
|
||||||
throw new ArrayIndexOutOfBoundsException("negative index");
|
throw new ArrayIndexOutOfBoundsException("negative index");
|
||||||
|
@ -310,6 +309,7 @@ public class PersistentList extends AbstractPersistentCollection implements List
|
||||||
|
|
||||||
if ( old==UNKNOWN ) {
|
if ( old==UNKNOWN ) {
|
||||||
write();
|
write();
|
||||||
|
//noinspection unchecked
|
||||||
return list.set( index, value );
|
return list.set( index, value );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -319,7 +319,6 @@ public class PersistentList extends AbstractPersistentCollection implements List
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Object remove(int index) {
|
public Object remove(int index) {
|
||||||
if ( index < 0 ) {
|
if ( index < 0 ) {
|
||||||
throw new ArrayIndexOutOfBoundsException( "negative index" );
|
throw new ArrayIndexOutOfBoundsException( "negative index" );
|
||||||
|
@ -338,45 +337,40 @@ public class PersistentList extends AbstractPersistentCollection implements List
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void add(int index, Object value) {
|
public void add(int index, Object value) {
|
||||||
if ( index < 0 ) {
|
if ( index < 0 ) {
|
||||||
throw new ArrayIndexOutOfBoundsException( "negative index" );
|
throw new ArrayIndexOutOfBoundsException( "negative index" );
|
||||||
}
|
}
|
||||||
write();
|
write();
|
||||||
|
//noinspection unchecked
|
||||||
list.add( index, value );
|
list.add( index, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public int indexOf(Object value) {
|
public int indexOf(Object value) {
|
||||||
read();
|
read();
|
||||||
return list.indexOf( value );
|
return list.indexOf( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public int lastIndexOf(Object value) {
|
public int lastIndexOf(Object value) {
|
||||||
read();
|
read();
|
||||||
return list.lastIndexOf( value );
|
return list.lastIndexOf( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public ListIterator listIterator() {
|
public ListIterator listIterator() {
|
||||||
read();
|
read();
|
||||||
return new ListIteratorProxy( list.listIterator() );
|
return new ListIteratorProxy( list.listIterator() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public ListIterator listIterator(int index) {
|
public ListIterator listIterator(int index) {
|
||||||
read();
|
read();
|
||||||
return new ListIteratorProxy( list.listIterator( index ) );
|
return new ListIteratorProxy( list.listIterator( index ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public java.util.List subList(int from, int to) {
|
public java.util.List subList(int from, int to) {
|
||||||
read();
|
read();
|
||||||
return new ListProxy( list.subList( from, to ) );
|
return new ListProxy( list.subList( from, to ) );
|
||||||
|
@ -409,6 +403,32 @@ public class PersistentList extends AbstractPersistentCollection implements List
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object readFrom(
|
||||||
|
RowProcessingState rowProcessingState,
|
||||||
|
DomainResultAssembler elementAssembler,
|
||||||
|
DomainResultAssembler indexAssembler,
|
||||||
|
DomainResultAssembler identifierAssembler,
|
||||||
|
Object owner) throws HibernateException {
|
||||||
|
assert elementAssembler != null;
|
||||||
|
assert indexAssembler != null;
|
||||||
|
assert identifierAssembler == null;
|
||||||
|
|
||||||
|
final Object element = elementAssembler.assemble( rowProcessingState );
|
||||||
|
final int index = (int) indexAssembler.assemble( rowProcessingState );
|
||||||
|
|
||||||
|
//pad with nulls from the current last element up to the new index
|
||||||
|
for ( int i = list.size(); i<=index; i++) {
|
||||||
|
//noinspection unchecked
|
||||||
|
list.add( i, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
list.set( index, element );
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Iterator entries(CollectionPersister persister) {
|
public Iterator entries(CollectionPersister persister) {
|
||||||
|
|
|
@ -22,6 +22,8 @@ import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.loader.CollectionAliases;
|
import org.hibernate.loader.CollectionAliases;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.sql.results.spi.RowProcessingState;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
|
||||||
|
@ -176,7 +178,6 @@ public class PersistentMap extends AbstractPersistentCollection implements Map {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Object put(Object key, Object value) {
|
public Object put(Object key, Object value) {
|
||||||
if ( isPutQueueEnabled() ) {
|
if ( isPutQueueEnabled() ) {
|
||||||
final Object old = readElementByIndex( key );
|
final Object old = readElementByIndex( key );
|
||||||
|
@ -186,6 +187,7 @@ public class PersistentMap extends AbstractPersistentCollection implements Map {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
initialize( true );
|
initialize( true );
|
||||||
|
//noinspection unchecked
|
||||||
final Object old = map.put( key, value );
|
final Object old = map.put( key, value );
|
||||||
// would be better to use the element-type to determine
|
// would be better to use the element-type to determine
|
||||||
// whether the old and the new are equal here; the problem being
|
// whether the old and the new are equal here; the problem being
|
||||||
|
@ -198,7 +200,6 @@ public class PersistentMap extends AbstractPersistentCollection implements Map {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Object remove(Object key) {
|
public Object remove(Object key) {
|
||||||
if ( isPutQueueEnabled() ) {
|
if ( isPutQueueEnabled() ) {
|
||||||
final Object old = readElementByIndex( key );
|
final Object old = readElementByIndex( key );
|
||||||
|
@ -218,7 +219,6 @@ public class PersistentMap extends AbstractPersistentCollection implements Map {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void putAll(Map puts) {
|
public void putAll(Map puts) {
|
||||||
if ( puts.size() > 0 ) {
|
if ( puts.size() > 0 ) {
|
||||||
initialize( true );
|
initialize( true );
|
||||||
|
@ -230,7 +230,6 @@ public class PersistentMap extends AbstractPersistentCollection implements Map {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
if ( isClearQueueEnabled() ) {
|
if ( isClearQueueEnabled() ) {
|
||||||
queueOperation( new Clear() );
|
queueOperation( new Clear() );
|
||||||
|
@ -245,34 +244,29 @@ public class PersistentMap extends AbstractPersistentCollection implements Map {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Set keySet() {
|
public Set keySet() {
|
||||||
read();
|
read();
|
||||||
return new SetProxy( map.keySet() );
|
return new SetProxy( map.keySet() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Collection values() {
|
public Collection values() {
|
||||||
read();
|
read();
|
||||||
return new SetProxy( map.values() );
|
return new SetProxy( map.values() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Set entrySet() {
|
public Set entrySet() {
|
||||||
read();
|
read();
|
||||||
return new EntrySetProxy( map.entrySet() );
|
return new EntrySetProxy( map.entrySet() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public boolean empty() {
|
public boolean empty() {
|
||||||
return map.isEmpty();
|
return map.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
read();
|
read();
|
||||||
return map.toString();
|
return map.toString();
|
||||||
|
@ -281,7 +275,6 @@ public class PersistentMap extends AbstractPersistentCollection implements Map {
|
||||||
private transient List<Object[]> loadingEntries;
|
private transient List<Object[]> loadingEntries;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Object readFrom(
|
public Object readFrom(
|
||||||
ResultSet rs,
|
ResultSet rs,
|
||||||
CollectionPersister persister,
|
CollectionPersister persister,
|
||||||
|
@ -298,6 +291,30 @@ public class PersistentMap extends AbstractPersistentCollection implements Map {
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object readFrom(
|
||||||
|
RowProcessingState rowProcessingState,
|
||||||
|
DomainResultAssembler elementAssembler,
|
||||||
|
DomainResultAssembler indexAssembler,
|
||||||
|
DomainResultAssembler identifierAssembler,
|
||||||
|
Object owner) throws HibernateException {
|
||||||
|
assert elementAssembler != null;
|
||||||
|
assert indexAssembler != null;
|
||||||
|
assert identifierAssembler == null;
|
||||||
|
|
||||||
|
final Object element = elementAssembler.assemble( rowProcessingState );
|
||||||
|
|
||||||
|
if ( element != null ) {
|
||||||
|
final Object index = indexAssembler.assemble( rowProcessingState );
|
||||||
|
if ( loadingEntries == null ) {
|
||||||
|
loadingEntries = new ArrayList<>();
|
||||||
|
}
|
||||||
|
loadingEntries.add( new Object[] { index, element } );
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public boolean endRead() {
|
public boolean endRead() {
|
||||||
|
|
|
@ -21,6 +21,8 @@ import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.loader.CollectionAliases;
|
import org.hibernate.loader.CollectionAliases;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.sql.results.spi.RowProcessingState;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
|
||||||
|
@ -342,6 +344,27 @@ public class PersistentSet extends AbstractPersistentCollection implements java.
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object readFrom(
|
||||||
|
RowProcessingState rowProcessingState,
|
||||||
|
DomainResultAssembler elementAssembler,
|
||||||
|
DomainResultAssembler indexAssembler,
|
||||||
|
DomainResultAssembler identifierAssembler,
|
||||||
|
Object owner) throws HibernateException {
|
||||||
|
assert elementAssembler != null;
|
||||||
|
assert indexAssembler == null;
|
||||||
|
assert identifierAssembler == null;
|
||||||
|
|
||||||
|
final Object element = elementAssembler.assemble( rowProcessingState );
|
||||||
|
|
||||||
|
if ( element != null ) {
|
||||||
|
//noinspection unchecked
|
||||||
|
tempList.add( element );
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void beginRead() {
|
public void beginRead() {
|
||||||
|
|
|
@ -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 org.hibernate.MappingException;
|
||||||
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
|
import org.hibernate.collection.spi.CollectionSemantics;
|
||||||
|
import org.hibernate.collection.spi.CollectionSemanticsResolver;
|
||||||
|
import org.hibernate.mapping.Array;
|
||||||
|
import org.hibernate.mapping.Bag;
|
||||||
|
import org.hibernate.mapping.Collection;
|
||||||
|
import org.hibernate.mapping.IdentifierBag;
|
||||||
|
import org.hibernate.mapping.List;
|
||||||
|
import org.hibernate.mapping.Map;
|
||||||
|
import org.hibernate.mapping.PrimitiveArray;
|
||||||
|
import org.hibernate.mapping.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard implementation of CollectionSemanticsResolver
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class StandardCollectionSemanticsResolver implements CollectionSemanticsResolver {
|
||||||
|
/**
|
||||||
|
* Singleton access
|
||||||
|
*/
|
||||||
|
public static final StandardCollectionSemanticsResolver INSTANCE = new StandardCollectionSemanticsResolver();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionSemantics resolveRepresentation(Collection bootDescriptor) {
|
||||||
|
if ( bootDescriptor instanceof PrimitiveArray ) {
|
||||||
|
throw new NotYetImplementedFor6Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bootDescriptor instanceof Array ) {
|
||||||
|
return StandardArraySemantics.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bootDescriptor instanceof Bag ) {
|
||||||
|
return StandardBagSemantics.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bootDescriptor instanceof IdentifierBag ) {
|
||||||
|
return StandardIdentifierBagSemantics.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bootDescriptor instanceof List ) {
|
||||||
|
return StandardListSemantics.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bootDescriptor instanceof Map ) {
|
||||||
|
if ( bootDescriptor.isSorted() ) {
|
||||||
|
return StandardSortedMapSemantics.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bootDescriptor.hasOrder() ) {
|
||||||
|
return StandardOrderedMapSemantics.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StandardMapSemantics.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bootDescriptor instanceof Set ) {
|
||||||
|
if ( bootDescriptor.isSorted() ) {
|
||||||
|
return StandardSortedSetSemantics.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bootDescriptor.hasOrder() ) {
|
||||||
|
return StandardOrderedSetSemantics.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StandardSetSemantics.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new MappingException(
|
||||||
|
"Unexpected org.hibernate.mapping.Collection impl ["
|
||||||
|
+ bootDescriptor + "]; unknown CollectionSemantics"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ package org.hibernate.collection.spi;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.hibernate.Incubating;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.metamodel.CollectionClassification;
|
import org.hibernate.metamodel.CollectionClassification;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
@ -22,6 +23,7 @@ import org.hibernate.persister.collection.CollectionPersister;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
|
@Incubating
|
||||||
public interface CollectionSemantics<C> {
|
public interface CollectionSemantics<C> {
|
||||||
/**
|
/**
|
||||||
* Get the classification of collections described by this semantic
|
* Get the classification of collections described by this semantic
|
||||||
|
|
|
@ -6,9 +6,12 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.collection.spi;
|
package org.hibernate.collection.spi;
|
||||||
|
|
||||||
|
import org.hibernate.Incubating;
|
||||||
import org.hibernate.mapping.Collection;
|
import org.hibernate.mapping.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Resolve the collection semantics for the given mapped collection
|
||||||
|
*
|
||||||
* todo (6.0) ...
|
* todo (6.0) ...
|
||||||
*
|
*
|
||||||
* Ideally would act as the contract that allows pluggable resolution of
|
* Ideally would act as the contract that allows pluggable resolution of
|
||||||
|
@ -17,6 +20,7 @@ import org.hibernate.mapping.Collection;
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@Incubating
|
||||||
public interface CollectionSemanticsResolver {
|
public interface CollectionSemanticsResolver {
|
||||||
// really need some form of access to the attribute site
|
// really need some form of access to the attribute site
|
||||||
CollectionSemantics resolveRepresentation(Collection bootDescriptor);
|
CollectionSemantics resolveRepresentation(Collection bootDescriptor);
|
||||||
|
|
|
@ -16,6 +16,8 @@ import org.hibernate.HibernateException;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.loader.CollectionAliases;
|
import org.hibernate.loader.CollectionAliases;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.sql.results.spi.RowProcessingState;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -173,6 +175,13 @@ public interface PersistentCollection {
|
||||||
Object readFrom(ResultSet rs, CollectionPersister role, CollectionAliases descriptor, Object owner)
|
Object readFrom(ResultSet rs, CollectionPersister role, CollectionAliases descriptor, Object owner)
|
||||||
throws HibernateException, SQLException;
|
throws HibernateException, SQLException;
|
||||||
|
|
||||||
|
Object readFrom(
|
||||||
|
RowProcessingState rowProcessingState,
|
||||||
|
DomainResultAssembler elementAssembler,
|
||||||
|
DomainResultAssembler indexAssembler,
|
||||||
|
DomainResultAssembler identifierAssembler,
|
||||||
|
Object owner) throws HibernateException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the identifier of the given collection entry. This refers to the collection identifier, not the
|
* Get the identifier of the given collection entry. This refers to the collection identifier, not the
|
||||||
* identifier of the (possibly) entity elements. This is only valid for invocation on the
|
* identifier of the (possibly) entity elements. This is only valid for invocation on the
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* 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.mapping;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.CollectionClassification;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Descriptor for the collection identifier. Only used with {@link CollectionClassification#IDBAG} collections
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface CollectionIdentifierDescriptor {
|
||||||
|
DomainResult createDomainResult(
|
||||||
|
NavigablePath collectionPath,
|
||||||
|
TableGroup tableGroup,
|
||||||
|
DomainResultCreationState creationState);
|
||||||
|
}
|
|
@ -15,5 +15,5 @@ import org.hibernate.collection.spi.CollectionSemantics;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface CollectionMappingType<C> extends MappingType {
|
public interface CollectionMappingType<C> extends MappingType {
|
||||||
CollectionSemantics<C> getCCollectionSemantics();
|
CollectionSemantics<C> getCollectionSemantics();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.metamodel.mapping;
|
||||||
|
|
||||||
|
import org.hibernate.sql.results.spi.Fetchable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface CollectionPart extends ModelPart, Fetchable {
|
||||||
|
enum Nature {
|
||||||
|
ELEMENT( "{element}" ),
|
||||||
|
INDEX( "{index}" );
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
Nature(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Nature fromName(String name) {
|
||||||
|
if ( ELEMENT.name.equals( name ) ) {
|
||||||
|
return ELEMENT;
|
||||||
|
}
|
||||||
|
else if ( INDEX.name.equals( name ) ) {
|
||||||
|
return INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unrecognized CollectionPart Nature name [" + name
|
||||||
|
+ "]; expecting `" + ELEMENT.name + "` or `"
|
||||||
|
+ INDEX.name + "`"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Nature getNature();
|
||||||
|
|
||||||
|
ModelPart getPartTypeDescriptor();
|
||||||
|
}
|
|
@ -102,6 +102,7 @@ public class EmbeddableMappingType implements ManagedMappingType {
|
||||||
CompositeType compositeType,
|
CompositeType compositeType,
|
||||||
MappingModelCreationProcess creationProcess) {
|
MappingModelCreationProcess creationProcess) {
|
||||||
final String containingTableExpression = valueMapping.getContainingTableExpression();
|
final String containingTableExpression = valueMapping.getContainingTableExpression();
|
||||||
|
|
||||||
final List<String> mappedColumnExpressions = valueMapping.getMappedColumnExpressions();
|
final List<String> mappedColumnExpressions = valueMapping.getMappedColumnExpressions();
|
||||||
|
|
||||||
final Type[] subtypes = compositeType.getSubtypes();
|
final Type[] subtypes = compositeType.getSubtypes();
|
||||||
|
@ -196,6 +197,11 @@ public class EmbeddableMappingType implements ManagedMappingType {
|
||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
throw new NotYetImplementedFor6Exception( getClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumberOfFetchables() {
|
||||||
|
return attributeMappings.size();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitFetchables(
|
public void visitFetchables(
|
||||||
Consumer<Fetchable> fetchableConsumer,
|
Consumer<Fetchable> fetchableConsumer,
|
||||||
|
|
|
@ -14,12 +14,13 @@ import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
|
||||||
|
import org.hibernate.sql.results.spi.Fetchable;
|
||||||
import org.hibernate.sql.results.spi.FetchableContainer;
|
import org.hibernate.sql.results.spi.FetchableContainer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface EmbeddableValuedModelPart extends ModelPart, FetchableContainer, TableGroupJoinProducer {
|
public interface EmbeddableValuedModelPart extends ModelPart, Fetchable, FetchableContainer, TableGroupJoinProducer {
|
||||||
EmbeddableMappingType getEmbeddableTypeDescriptor();
|
EmbeddableMappingType getEmbeddableTypeDescriptor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* 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.mapping;
|
||||||
|
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface ForeignKeyDescriptor {
|
||||||
|
DomainResult createDomainResult(NavigablePath collectionPath, TableGroup tableGroup, DomainResultCreationState creationState);
|
||||||
|
}
|
|
@ -6,15 +6,39 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.mapping;
|
package org.hibernate.metamodel.mapping;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
|
||||||
|
import org.hibernate.sql.results.spi.Fetchable;
|
||||||
|
import org.hibernate.sql.results.spi.FetchableContainer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface PluralAttributeMapping extends AttributeMapping, StateArrayContributorMapping {
|
public interface PluralAttributeMapping
|
||||||
|
extends AttributeMapping, StateArrayContributorMapping, TableGroupJoinProducer, FetchableContainer {
|
||||||
|
|
||||||
CollectionPersister getCollectionDescriptor();
|
CollectionPersister getCollectionDescriptor();
|
||||||
|
|
||||||
ModelPart getValueDescriptor();
|
ForeignKeyDescriptor getKeyDescriptor();
|
||||||
|
|
||||||
ModelPart getIndexDescriptor();
|
CollectionPart getIndexDescriptor();
|
||||||
|
|
||||||
|
CollectionPart getElementDescriptor();
|
||||||
|
|
||||||
|
CollectionIdentifierDescriptor getIdentifierDescriptor();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void visitKeyFetchables(Consumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
|
||||||
|
final CollectionPart indexDescriptor = getIndexDescriptor();
|
||||||
|
if ( indexDescriptor != null ) {
|
||||||
|
fetchableConsumer.accept( indexDescriptor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void visitFetchables(Consumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
|
||||||
|
fetchableConsumer.accept( getElementDescriptor() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,17 @@ import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.FetchStrategy;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||||
|
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.mapping.MappingType;
|
import org.hibernate.metamodel.mapping.MappingType;
|
||||||
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||||
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
|
import org.hibernate.sql.results.SqlResultsLogger;
|
||||||
import org.hibernate.sql.results.internal.domain.basic.BasicFetch;
|
import org.hibernate.sql.results.internal.domain.basic.BasicFetch;
|
||||||
import org.hibernate.sql.results.internal.domain.basic.BasicResult;
|
import org.hibernate.sql.results.internal.domain.basic.BasicResult;
|
||||||
import org.hibernate.sql.results.spi.DomainResult;
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
|
@ -36,13 +39,24 @@ import org.hibernate.type.spi.TypeConfiguration;
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class BasicValuedCollectionPart implements BasicValuedModelPart {
|
public class BasicValuedCollectionPart implements CollectionPart, BasicValuedModelPart {
|
||||||
|
|
||||||
|
private final CollectionPersister collectionDescriptor;
|
||||||
|
private final Nature nature;
|
||||||
|
private final BasicType mapper;
|
||||||
|
private final BasicValueConverter valueConverter;
|
||||||
|
|
||||||
|
private final String tableExpression;
|
||||||
|
private final String columnExpression;
|
||||||
|
|
||||||
public BasicValuedCollectionPart(
|
public BasicValuedCollectionPart(
|
||||||
|
CollectionPersister collectionDescriptor,
|
||||||
Nature nature,
|
Nature nature,
|
||||||
BasicType mapper,
|
BasicType mapper,
|
||||||
BasicValueConverter valueConverter,
|
BasicValueConverter valueConverter,
|
||||||
String tableExpression,
|
String tableExpression,
|
||||||
String columnExpression) {
|
String columnExpression) {
|
||||||
|
this.collectionDescriptor = collectionDescriptor;
|
||||||
this.nature = nature;
|
this.nature = nature;
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
this.valueConverter = valueConverter;
|
this.valueConverter = valueConverter;
|
||||||
|
@ -50,14 +64,15 @@ public class BasicValuedCollectionPart implements BasicValuedModelPart {
|
||||||
this.columnExpression = columnExpression;
|
this.columnExpression = columnExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Nature { ELEMENT, INDEX }
|
@Override
|
||||||
|
public Nature getNature() {
|
||||||
|
return nature;
|
||||||
|
}
|
||||||
|
|
||||||
private final Nature nature;
|
@Override
|
||||||
private final BasicType mapper;
|
public BasicType getPartTypeDescriptor() {
|
||||||
private final BasicValueConverter valueConverter;
|
return mapper;
|
||||||
|
}
|
||||||
private final String tableExpression;
|
|
||||||
private final String columnExpression;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getContainingTableExpression() {
|
public String getContainingTableExpression() {
|
||||||
|
@ -91,7 +106,9 @@ public class BasicValuedCollectionPart implements BasicValuedModelPart {
|
||||||
return new BasicResult(
|
return new BasicResult(
|
||||||
sqlSelection.getValuesArrayPosition(),
|
sqlSelection.getValuesArrayPosition(),
|
||||||
resultVariable,
|
resultVariable,
|
||||||
getJavaTypeDescriptor()
|
getJavaTypeDescriptor(),
|
||||||
|
valueConverter,
|
||||||
|
navigablePath
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,9 +117,9 @@ public class BasicValuedCollectionPart implements BasicValuedModelPart {
|
||||||
|
|
||||||
return exprResolver.resolveSqlSelection(
|
return exprResolver.resolveSqlSelection(
|
||||||
exprResolver.resolveSqlExpression(
|
exprResolver.resolveSqlExpression(
|
||||||
SqlExpressionResolver.createColumnReferenceKey( tableExpression, columnExpression ),
|
SqlExpressionResolver.createColumnReferenceKey( tableGroup.getPrimaryTableReference(), columnExpression ),
|
||||||
sqlAstProcessingState -> new ColumnReference(
|
sqlAstProcessingState -> new ColumnReference(
|
||||||
tableGroup.resolveTableReference( tableExpression ).getIdentificationVariable(),
|
tableGroup.getPrimaryTableReference().getIdentificationVariable(),
|
||||||
columnExpression,
|
columnExpression,
|
||||||
mapper,
|
mapper,
|
||||||
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
|
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
|
||||||
|
@ -148,6 +165,12 @@ public class BasicValuedCollectionPart implements BasicValuedModelPart {
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
|
SqlResultsLogger.INSTANCE.debugf(
|
||||||
|
"Generating Fetch for collection-part : `%s` -> `%s`",
|
||||||
|
collectionDescriptor.getRole(),
|
||||||
|
nature.getName()
|
||||||
|
);
|
||||||
|
|
||||||
final SqlSelection sqlSelection = resolveSqlSelection(
|
final SqlSelection sqlSelection = resolveSqlSelection(
|
||||||
creationState.getSqlAstCreationState().getFromClauseAccess().findTableGroup( fetchablePath.getParent() ),
|
creationState.getSqlAstCreationState().getFromClauseAccess().findTableGroup( fetchablePath.getParent() ),
|
||||||
creationState
|
creationState
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* 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.mapping.internal;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
||||||
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
|
import org.hibernate.sql.results.internal.domain.basic.BasicResult;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||||
|
import org.hibernate.type.BasicType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class CollectionIdentifierDescriptorImpl implements CollectionIdentifierDescriptor {
|
||||||
|
private final CollectionPersister collectionDescriptor;
|
||||||
|
private final String columnName;
|
||||||
|
private final BasicType type;
|
||||||
|
|
||||||
|
public CollectionIdentifierDescriptorImpl(
|
||||||
|
CollectionPersister collectionDescriptor,
|
||||||
|
String columnName,
|
||||||
|
BasicType type) {
|
||||||
|
this.collectionDescriptor = collectionDescriptor;
|
||||||
|
this.columnName = columnName;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DomainResult createDomainResult(
|
||||||
|
NavigablePath collectionPath,
|
||||||
|
TableGroup tableGroup,
|
||||||
|
DomainResultCreationState creationState) {
|
||||||
|
|
||||||
|
|
||||||
|
final SqlAstCreationState astCreationState = creationState.getSqlAstCreationState();
|
||||||
|
final SqlAstCreationContext astCreationContext = astCreationState.getCreationContext();
|
||||||
|
final SessionFactoryImplementor sessionFactory = astCreationContext.getSessionFactory();
|
||||||
|
final SqlExpressionResolver sqlExpressionResolver = astCreationState.getSqlExpressionResolver();
|
||||||
|
|
||||||
|
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
||||||
|
sqlExpressionResolver.resolveSqlExpression(
|
||||||
|
SqlExpressionResolver.createColumnReferenceKey(
|
||||||
|
tableGroup.getPrimaryTableReference(),
|
||||||
|
columnName
|
||||||
|
),
|
||||||
|
p -> new ColumnReference(
|
||||||
|
tableGroup.getPrimaryTableReference().getIdentificationVariable(),
|
||||||
|
columnName,
|
||||||
|
type,
|
||||||
|
sessionFactory
|
||||||
|
)
|
||||||
|
),
|
||||||
|
type.getJavaTypeDescriptor(),
|
||||||
|
sessionFactory.getTypeConfiguration()
|
||||||
|
);
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
return new BasicResult(
|
||||||
|
sqlSelection.getValuesArrayPosition(),
|
||||||
|
null,
|
||||||
|
type.getJavaTypeDescriptor(),
|
||||||
|
collectionPath
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getSimpleName() + "(" + collectionDescriptor.getRole() + ")";
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,7 @@ import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.JoinType;
|
import org.hibernate.sql.ast.JoinType;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
|
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
|
@ -39,7 +40,9 @@ import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
||||||
import org.hibernate.sql.ast.tree.from.CompositeTableGroup;
|
import org.hibernate.sql.ast.tree.from.CompositeTableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
||||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableReferenceCollector;
|
||||||
import org.hibernate.sql.results.internal.domain.composite.CompositeFetch;
|
import org.hibernate.sql.results.internal.domain.composite.CompositeFetch;
|
||||||
import org.hibernate.sql.results.internal.domain.composite.CompositeResult;
|
import org.hibernate.sql.results.internal.domain.composite.CompositeResult;
|
||||||
import org.hibernate.sql.results.spi.DomainResult;
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
|
@ -162,6 +165,7 @@ public class EmbeddedAttributeMapping
|
||||||
this,
|
this,
|
||||||
fetchParent,
|
fetchParent,
|
||||||
fetchTiming,
|
fetchTiming,
|
||||||
|
getAttributeMetadataAccess().resolveAttributeMetadata( null ).isNullable(),
|
||||||
creationState
|
creationState
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -245,8 +249,44 @@ public class EmbeddedAttributeMapping
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyTableReferences(
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
JoinType baseJoinType,
|
||||||
|
TableReferenceCollector collector,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
getEmbeddableTypeDescriptor().visitAttributeMappings(
|
||||||
|
attrMapping -> {
|
||||||
|
if ( attrMapping instanceof TableGroupProducer ) {
|
||||||
|
( (TableGroupProducer) attrMapping ).applyTableReferences(
|
||||||
|
sqlAliasBase,
|
||||||
|
baseJoinType,
|
||||||
|
collector,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if ( attrMapping.getMappedTypeDescriptor() instanceof TableGroupProducer ) {
|
||||||
|
( (TableGroupProducer) attrMapping.getMappedTypeDescriptor() ).applyTableReferences(
|
||||||
|
sqlAliasBase,
|
||||||
|
baseJoinType,
|
||||||
|
collector,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSqlAliasStem() {
|
public String getSqlAliasStem() {
|
||||||
return getAttributeName();
|
return getAttributeName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumberOfFetchables() {
|
||||||
|
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
/*
|
||||||
|
* 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.mapping.internal;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
|
import org.hibernate.engine.FetchStrategy;
|
||||||
|
import org.hibernate.engine.FetchTiming;
|
||||||
|
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||||
|
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||||
|
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||||
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
|
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||||
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
|
import org.hibernate.sql.ast.JoinType;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableReferenceCollector;
|
||||||
|
import org.hibernate.sql.results.internal.domain.composite.CompositeFetch;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||||
|
import org.hibernate.sql.results.spi.Fetch;
|
||||||
|
import org.hibernate.sql.results.spi.FetchParent;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedModelPart {
|
||||||
|
private final CollectionPersister collectionDescriptor;
|
||||||
|
private final Nature nature;
|
||||||
|
private final EmbeddableMappingType embeddableMappingType;
|
||||||
|
|
||||||
|
private final String containingTableExpression;
|
||||||
|
|
||||||
|
private final SingularAttributeMapping parentInjectionAttribute;
|
||||||
|
private final List<String> columnExpressions;
|
||||||
|
private final String sqlAliasStem;
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public EmbeddedCollectionPart(
|
||||||
|
CollectionPersister collectionDescriptor,
|
||||||
|
Nature nature,
|
||||||
|
EmbeddableMappingType embeddableMappingType,
|
||||||
|
SingularAttributeMapping parentInjectionAttribute,
|
||||||
|
String containingTableExpression,
|
||||||
|
List<String> columnExpressions,
|
||||||
|
String sqlAliasStem) {
|
||||||
|
this.collectionDescriptor = collectionDescriptor;
|
||||||
|
this.nature = nature;
|
||||||
|
this.embeddableMappingType = embeddableMappingType;
|
||||||
|
this.parentInjectionAttribute = parentInjectionAttribute;
|
||||||
|
this.containingTableExpression = containingTableExpression;
|
||||||
|
this.columnExpressions = columnExpressions;
|
||||||
|
this.sqlAliasStem = sqlAliasStem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Nature getNature() {
|
||||||
|
return nature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmbeddableMappingType getEmbeddableTypeDescriptor() {
|
||||||
|
return embeddableMappingType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmbeddableMappingType getPartTypeDescriptor() {
|
||||||
|
return getEmbeddableTypeDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContainingTableExpression() {
|
||||||
|
return containingTableExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getMappedColumnExpressions() {
|
||||||
|
return columnExpressions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SingularAttributeMapping getParentInjectionAttributeMapping() {
|
||||||
|
return parentInjectionAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFetchableName() {
|
||||||
|
return getNature().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FetchStrategy getMappedFetchStrategy() {
|
||||||
|
return FetchStrategy.IMMEDIATE_JOIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetch generateFetch(
|
||||||
|
FetchParent fetchParent,
|
||||||
|
NavigablePath fetchablePath,
|
||||||
|
FetchTiming fetchTiming,
|
||||||
|
boolean selected,
|
||||||
|
LockMode lockMode,
|
||||||
|
String resultVariable,
|
||||||
|
DomainResultCreationState creationState) {
|
||||||
|
return new CompositeFetch(
|
||||||
|
fetchablePath,
|
||||||
|
this,
|
||||||
|
fetchParent,
|
||||||
|
FetchTiming.IMMEDIATE,
|
||||||
|
false,
|
||||||
|
creationState
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Expression toSqlExpression(
|
||||||
|
TableGroup tableGroup,
|
||||||
|
Clause clause,
|
||||||
|
SqmToSqlAstConverter walker,
|
||||||
|
SqlAstCreationState sqlAstCreationState) {
|
||||||
|
throw new NotYetImplementedFor6Exception( getClass() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableGroupJoin createTableGroupJoin(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup lhs,
|
||||||
|
String explicitSourceAlias,
|
||||||
|
JoinType joinType,
|
||||||
|
LockMode lockMode,
|
||||||
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
throw new NotYetImplementedFor6Exception( getClass() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyTableReferences(
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
JoinType baseJoinType,
|
||||||
|
TableReferenceCollector collector,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
throw new NotYetImplementedFor6Exception( getClass() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSqlAliasStem() {
|
||||||
|
return sqlAliasStem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
||||||
|
return getEmbeddableTypeDescriptor().findSubPart( name, treatTargetType );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSubParts(Consumer<ModelPart> consumer, EntityMappingType treatTargetType) {
|
||||||
|
getEmbeddableTypeDescriptor().visitSubParts( consumer, treatTargetType );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JavaTypeDescriptor getJavaTypeDescriptor() {
|
||||||
|
return getEmbeddableTypeDescriptor().getJavaTypeDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumberOfFetchables() {
|
||||||
|
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* 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.mapping.internal;
|
||||||
|
|
||||||
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
|
import org.hibernate.engine.FetchStrategy;
|
||||||
|
import org.hibernate.engine.FetchTiming;
|
||||||
|
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||||
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
|
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||||
|
import org.hibernate.sql.results.spi.Fetch;
|
||||||
|
import org.hibernate.sql.results.spi.FetchParent;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class EntityCollectionPart implements CollectionPart, EntityValuedModelPart {
|
||||||
|
private final Nature nature;
|
||||||
|
private final EntityMappingType entityMappingType;
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public EntityCollectionPart(Nature nature, EntityMappingType entityMappingType) {
|
||||||
|
this.nature = nature;
|
||||||
|
this.entityMappingType = entityMappingType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Nature getNature() {
|
||||||
|
return nature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityMappingType getPartTypeDescriptor() {
|
||||||
|
return getEntityMappingType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityMappingType getEntityMappingType() {
|
||||||
|
return entityMappingType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JavaTypeDescriptor getJavaTypeDescriptor() {
|
||||||
|
return getEntityMappingType().getJavaTypeDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFetchableName() {
|
||||||
|
return nature.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FetchStrategy getMappedFetchStrategy() {
|
||||||
|
return FetchStrategy.IMMEDIATE_JOIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetch generateFetch(
|
||||||
|
FetchParent fetchParent,
|
||||||
|
NavigablePath fetchablePath,
|
||||||
|
FetchTiming fetchTiming,
|
||||||
|
boolean selected,
|
||||||
|
LockMode lockMode,
|
||||||
|
String resultVariable,
|
||||||
|
DomainResultCreationState creationState) {
|
||||||
|
throw new NotYetImplementedFor6Exception( getClass() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumberOfFetchables() {
|
||||||
|
return entityMappingType.getNumberOfFetchables();
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,10 @@
|
||||||
package org.hibernate.metamodel.mapping.internal;
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.SortedMap;
|
||||||
|
import java.util.SortedSet;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
@ -16,36 +20,35 @@ import org.hibernate.collection.internal.StandardArraySemantics;
|
||||||
import org.hibernate.collection.internal.StandardBagSemantics;
|
import org.hibernate.collection.internal.StandardBagSemantics;
|
||||||
import org.hibernate.collection.internal.StandardIdentifierBagSemantics;
|
import org.hibernate.collection.internal.StandardIdentifierBagSemantics;
|
||||||
import org.hibernate.collection.internal.StandardListSemantics;
|
import org.hibernate.collection.internal.StandardListSemantics;
|
||||||
import org.hibernate.collection.internal.StandardMapSemantics;
|
|
||||||
import org.hibernate.collection.internal.StandardOrderedMapSemantics;
|
|
||||||
import org.hibernate.collection.internal.StandardOrderedSetSemantics;
|
|
||||||
import org.hibernate.collection.internal.StandardSetSemantics;
|
|
||||||
import org.hibernate.collection.internal.StandardSortedMapSemantics;
|
|
||||||
import org.hibernate.collection.internal.StandardSortedSetSemantics;
|
|
||||||
import org.hibernate.collection.spi.CollectionSemantics;
|
import org.hibernate.collection.spi.CollectionSemantics;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.FetchStrategy;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.FetchStyle;
|
import org.hibernate.engine.FetchStyle;
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
import org.hibernate.engine.spi.CascadeStyle;
|
import org.hibernate.engine.spi.CascadeStyle;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.mapping.Array;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.mapping.Bag;
|
|
||||||
import org.hibernate.mapping.BasicValue;
|
import org.hibernate.mapping.BasicValue;
|
||||||
import org.hibernate.mapping.Collection;
|
import org.hibernate.mapping.Collection;
|
||||||
import org.hibernate.mapping.Component;
|
import org.hibernate.mapping.Component;
|
||||||
import org.hibernate.mapping.IdentifierBag;
|
import org.hibernate.mapping.IndexedCollection;
|
||||||
import org.hibernate.mapping.List;
|
import org.hibernate.mapping.OneToMany;
|
||||||
import org.hibernate.mapping.Map;
|
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
import org.hibernate.mapping.PrimitiveArray;
|
|
||||||
import org.hibernate.mapping.Property;
|
import org.hibernate.mapping.Property;
|
||||||
import org.hibernate.mapping.Set;
|
import org.hibernate.mapping.Selectable;
|
||||||
|
import org.hibernate.mapping.ToOne;
|
||||||
|
import org.hibernate.mapping.Value;
|
||||||
|
import org.hibernate.metamodel.CollectionClassification;
|
||||||
import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping;
|
import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping;
|
||||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||||
|
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
||||||
|
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||||
import org.hibernate.metamodel.mapping.MappingType;
|
import org.hibernate.metamodel.mapping.MappingType;
|
||||||
|
@ -54,15 +57,19 @@ import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
|
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
|
||||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
||||||
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||||
|
import org.hibernate.metamodel.spi.DomainMetamodel;
|
||||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.persister.collection.SQLLoadableCollection;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.persister.entity.Joinable;
|
||||||
import org.hibernate.persister.entity.OuterJoinLoadable;
|
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||||
import org.hibernate.persister.walking.internal.FetchStrategyHelper;
|
import org.hibernate.persister.walking.internal.FetchStrategyHelper;
|
||||||
import org.hibernate.property.access.spi.PropertyAccess;
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasStemHelper;
|
||||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
@ -76,6 +83,7 @@ import org.hibernate.sql.results.spi.Fetch;
|
||||||
import org.hibernate.sql.results.spi.FetchParent;
|
import org.hibernate.sql.results.spi.FetchParent;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
|
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
||||||
|
@ -622,75 +630,152 @@ public class MappingModelCreationHelper {
|
||||||
final Collection bootValueMapping = (Collection) bootProperty.getValue();
|
final Collection bootValueMapping = (Collection) bootProperty.getValue();
|
||||||
|
|
||||||
final RuntimeModelCreationContext creationContext = creationProcess.getCreationContext();
|
final RuntimeModelCreationContext creationContext = creationProcess.getCreationContext();
|
||||||
final CollectionPersister collectionDescriptor = creationContext.getDomainModel().findCollectionDescriptor( bootValueMapping.getRole() );
|
final SessionFactoryImplementor sessionFactory = creationContext.getSessionFactory();
|
||||||
|
final Dialect dialect = sessionFactory.getJdbcServices().getJdbcEnvironment().getDialect();
|
||||||
|
final DomainMetamodel domainModel = creationContext.getDomainModel();
|
||||||
|
|
||||||
|
final CollectionPersister collectionDescriptor = domainModel.findCollectionDescriptor( bootValueMapping.getRole() );
|
||||||
assert collectionDescriptor != null;
|
assert collectionDescriptor != null;
|
||||||
|
|
||||||
|
tableExpression = ( (Joinable) collectionDescriptor ).getTableName();
|
||||||
|
|
||||||
|
final String sqlAliasStem = SqlAliasStemHelper.INSTANCE.generateStemFromAttributeName( bootProperty.getName() );
|
||||||
|
|
||||||
final CollectionMappingType<?> collectionMappingType;
|
final CollectionMappingType<?> collectionMappingType;
|
||||||
final JavaTypeDescriptorRegistry jtdRegistry = creationContext.getJavaTypeDescriptorRegistry();
|
final JavaTypeDescriptorRegistry jtdRegistry = creationContext.getJavaTypeDescriptorRegistry();
|
||||||
|
|
||||||
if ( bootValueMapping instanceof Array ) {
|
final ForeignKeyDescriptor keyDescriptor = interpretKeyDescriptor(
|
||||||
if ( bootValueMapping instanceof PrimitiveArray ) {
|
bootProperty,
|
||||||
throw new NotYetImplementedFor6Exception();
|
bootValueMapping,
|
||||||
}
|
dialect,
|
||||||
else {
|
creationProcess
|
||||||
|
);
|
||||||
|
|
||||||
|
final CollectionPart elementDescriptor = interpretElement(
|
||||||
|
bootValueMapping,
|
||||||
|
tableExpression,
|
||||||
|
collectionDescriptor,
|
||||||
|
sqlAliasStem,
|
||||||
|
dialect,
|
||||||
|
creationProcess
|
||||||
|
);
|
||||||
|
final CollectionPart indexDescriptor;
|
||||||
|
CollectionIdentifierDescriptor identifierDescriptor = null;
|
||||||
|
|
||||||
|
final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics();
|
||||||
|
switch ( collectionSemantics.getCollectionClassification() ) {
|
||||||
|
case ARRAY: {
|
||||||
collectionMappingType = new CollectionMappingTypeImpl(
|
collectionMappingType = new CollectionMappingTypeImpl(
|
||||||
jtdRegistry.getDescriptor( Object[].class ),
|
jtdRegistry.getDescriptor( Object[].class ),
|
||||||
StandardArraySemantics.INSTANCE
|
StandardArraySemantics.INSTANCE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final BasicValue index = (BasicValue) ( (IndexedCollection) bootValueMapping ).getIndex();
|
||||||
|
indexDescriptor = new BasicValuedCollectionPart(
|
||||||
|
collectionDescriptor,
|
||||||
|
CollectionPart.Nature.INDEX,
|
||||||
|
creationContext.getTypeConfiguration().getBasicTypeForJavaType( Integer.class ),
|
||||||
|
// no converter
|
||||||
|
null,
|
||||||
|
tableExpression,
|
||||||
|
index.getColumnIterator().next().getText( dialect )
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
case BAG: {
|
||||||
else if ( bootValueMapping instanceof Bag ) {
|
|
||||||
collectionMappingType = new CollectionMappingTypeImpl(
|
|
||||||
jtdRegistry.getDescriptor( java.util.Collection.class ),
|
|
||||||
StandardBagSemantics.INSTANCE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if ( bootValueMapping instanceof IdentifierBag ) {
|
|
||||||
collectionMappingType = new CollectionMappingTypeImpl(
|
|
||||||
jtdRegistry.getDescriptor( java.util.Collection.class ),
|
|
||||||
StandardIdentifierBagSemantics.INSTANCE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if ( bootValueMapping instanceof List ) {
|
|
||||||
collectionMappingType = new CollectionMappingTypeImpl(
|
|
||||||
jtdRegistry.getDescriptor( java.util.List.class ),
|
|
||||||
StandardListSemantics.INSTANCE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if ( bootValueMapping instanceof Map ) {
|
|
||||||
if ( bootValueMapping.isSorted() ) {
|
|
||||||
collectionMappingType = new CollectionMappingTypeImpl(
|
collectionMappingType = new CollectionMappingTypeImpl(
|
||||||
jtdRegistry.getDescriptor( java.util.SortedMap.class ),
|
jtdRegistry.getDescriptor( java.util.Collection.class ),
|
||||||
StandardSortedMapSemantics.INSTANCE
|
StandardBagSemantics.INSTANCE
|
||||||
|
);
|
||||||
|
|
||||||
|
indexDescriptor = null;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IDBAG: {
|
||||||
|
collectionMappingType = new CollectionMappingTypeImpl(
|
||||||
|
jtdRegistry.getDescriptor( java.util.Collection.class ),
|
||||||
|
StandardIdentifierBagSemantics.INSTANCE
|
||||||
|
);
|
||||||
|
|
||||||
|
indexDescriptor = null;
|
||||||
|
|
||||||
|
assert collectionDescriptor instanceof SQLLoadableCollection;
|
||||||
|
final SQLLoadableCollection loadableCollection = (SQLLoadableCollection) collectionDescriptor;
|
||||||
|
final String identifierColumnName = loadableCollection.getIdentifierColumnName();
|
||||||
|
assert identifierColumnName != null;
|
||||||
|
|
||||||
|
identifierDescriptor = new CollectionIdentifierDescriptorImpl(
|
||||||
|
collectionDescriptor,
|
||||||
|
identifierColumnName,
|
||||||
|
(BasicType) loadableCollection.getIdentifierType()
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LIST: {
|
||||||
|
final BasicValue index = (BasicValue) ( (IndexedCollection) bootValueMapping ).getIndex();
|
||||||
|
|
||||||
|
indexDescriptor = new BasicValuedCollectionPart(
|
||||||
|
collectionDescriptor,
|
||||||
|
CollectionPart.Nature.INDEX,
|
||||||
|
creationContext.getTypeConfiguration().getBasicTypeForJavaType( Integer.class ),
|
||||||
|
// no converter
|
||||||
|
null,
|
||||||
|
tableExpression,
|
||||||
|
index.getColumnIterator().next().getText( dialect )
|
||||||
|
);
|
||||||
|
|
||||||
|
collectionMappingType = new CollectionMappingTypeImpl(
|
||||||
|
jtdRegistry.getDescriptor( java.util.List.class ),
|
||||||
|
StandardListSemantics.INSTANCE
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MAP:
|
||||||
|
case ORDERED_MAP:
|
||||||
|
case SORTED_MAP: {
|
||||||
|
final Class<? extends java.util.Map> mapJavaType = collectionSemantics.getCollectionClassification() == CollectionClassification.SORTED_MAP
|
||||||
|
? SortedMap.class
|
||||||
|
: java.util.Map.class;
|
||||||
|
collectionMappingType = new CollectionMappingTypeImpl(
|
||||||
|
jtdRegistry.getDescriptor( mapJavaType ),
|
||||||
|
collectionSemantics
|
||||||
|
);
|
||||||
|
|
||||||
|
indexDescriptor = interpretMapKey(
|
||||||
|
bootValueMapping,
|
||||||
|
collectionDescriptor,
|
||||||
|
tableExpression,
|
||||||
|
sqlAliasStem,
|
||||||
|
dialect,
|
||||||
|
creationProcess
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SET:
|
||||||
|
case ORDERED_SET:
|
||||||
|
case SORTED_SET: {
|
||||||
|
final Class<? extends java.util.Set> setJavaType = collectionSemantics.getCollectionClassification() == CollectionClassification.SORTED_MAP
|
||||||
|
? SortedSet.class
|
||||||
|
: java.util.Set.class;
|
||||||
|
collectionMappingType = new CollectionMappingTypeImpl(
|
||||||
|
jtdRegistry.getDescriptor( setJavaType ),
|
||||||
|
collectionSemantics
|
||||||
|
);
|
||||||
|
|
||||||
|
indexDescriptor = null;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new MappingException(
|
||||||
|
"Unexpected CollectionClassification : " + collectionSemantics.getCollectionClassification()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
collectionMappingType = new CollectionMappingTypeImpl(
|
|
||||||
jtdRegistry.getDescriptor( java.util.Map.class ),
|
|
||||||
bootValueMapping.hasOrder()
|
|
||||||
? StandardOrderedMapSemantics.INSTANCE
|
|
||||||
: StandardMapSemantics.INSTANCE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( bootValueMapping instanceof Set ) {
|
|
||||||
if ( bootValueMapping.isSorted() ) {
|
|
||||||
collectionMappingType = new CollectionMappingTypeImpl(
|
|
||||||
jtdRegistry.getDescriptor( java.util.SortedSet.class ),
|
|
||||||
StandardSortedSetSemantics.INSTANCE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
collectionMappingType = new CollectionMappingTypeImpl(
|
|
||||||
jtdRegistry.getDescriptor( java.util.Set.class ),
|
|
||||||
bootValueMapping.hasOrder()
|
|
||||||
? StandardOrderedSetSemantics.INSTANCE
|
|
||||||
: StandardSetSemantics.INSTANCE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new MappingException( "Unexpected org.hibernate.mapping.Collection impl : " + bootValueMapping );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final StateArrayContributorMetadata contributorMetadata = new StateArrayContributorMetadata() {
|
final StateArrayContributorMetadata contributorMetadata = new StateArrayContributorMetadata() {
|
||||||
|
@ -733,7 +818,7 @@ public class MappingModelCreationHelper {
|
||||||
final FetchStyle style = FetchStrategyHelper.determineFetchStyleByMetadata(
|
final FetchStyle style = FetchStrategyHelper.determineFetchStyleByMetadata(
|
||||||
( (OuterJoinLoadable) declaringType ).getFetchMode( stateArrayPosition ),
|
( (OuterJoinLoadable) declaringType ).getFetchMode( stateArrayPosition ),
|
||||||
collectionDescriptor.getCollectionType(),
|
collectionDescriptor.getCollectionType(),
|
||||||
creationContext.getSessionFactory()
|
sessionFactory
|
||||||
);
|
);
|
||||||
|
|
||||||
return new PluralAttributeMappingImpl(
|
return new PluralAttributeMappingImpl(
|
||||||
|
@ -742,15 +827,15 @@ public class MappingModelCreationHelper {
|
||||||
entityMappingType -> contributorMetadata,
|
entityMappingType -> contributorMetadata,
|
||||||
collectionMappingType,
|
collectionMappingType,
|
||||||
stateArrayPosition,
|
stateArrayPosition,
|
||||||
tableExpression,
|
keyDescriptor,
|
||||||
attrColumnExpressions,
|
elementDescriptor,
|
||||||
null,
|
indexDescriptor,
|
||||||
null,
|
identifierDescriptor,
|
||||||
new FetchStrategy(
|
new FetchStrategy(
|
||||||
FetchStrategyHelper.determineFetchTiming(
|
FetchStrategyHelper.determineFetchTiming(
|
||||||
style,
|
style,
|
||||||
collectionDescriptor.getCollectionType(),
|
collectionDescriptor.getCollectionType(),
|
||||||
creationContext.getSessionFactory()
|
sessionFactory
|
||||||
),
|
),
|
||||||
style
|
style
|
||||||
),
|
),
|
||||||
|
@ -760,6 +845,156 @@ public class MappingModelCreationHelper {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ForeignKeyDescriptor interpretKeyDescriptor(
|
||||||
|
Property bootProperty,
|
||||||
|
Collection bootValueMapping,
|
||||||
|
Dialect dialect,
|
||||||
|
MappingModelCreationProcess creationProcess) {
|
||||||
|
final Type keyType = bootValueMapping.getKey().getType();
|
||||||
|
|
||||||
|
if ( keyType instanceof BasicType ) {
|
||||||
|
assert bootValueMapping.getKey().getColumnSpan() == 1;
|
||||||
|
return new SimpleForeignKeyDescriptor(
|
||||||
|
bootValueMapping.getKey().getColumnIterator().next().getText( dialect ),
|
||||||
|
(BasicType) keyType
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NotYetImplementedFor6Exception(
|
||||||
|
"Support for composite collection foreign-keys not yet implemented: " + bootValueMapping.getRole()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CollectionPart interpretMapKey(
|
||||||
|
Collection bootValueMapping,
|
||||||
|
CollectionPersister collectionDescriptor,
|
||||||
|
String tableExpression,
|
||||||
|
String sqlAliasStem,
|
||||||
|
Dialect dialect,
|
||||||
|
MappingModelCreationProcess creationProcess) {
|
||||||
|
assert bootValueMapping instanceof IndexedCollection;
|
||||||
|
final IndexedCollection indexedCollection = (IndexedCollection) bootValueMapping;
|
||||||
|
final Value bootMapKeyDescriptor = indexedCollection.getIndex();
|
||||||
|
|
||||||
|
if ( bootMapKeyDescriptor instanceof BasicValue ) {
|
||||||
|
final BasicValue basicValue = (BasicValue) bootMapKeyDescriptor;
|
||||||
|
return new BasicValuedCollectionPart(
|
||||||
|
collectionDescriptor,
|
||||||
|
CollectionPart.Nature.INDEX,
|
||||||
|
basicValue.resolve().getResolvedBasicType(),
|
||||||
|
basicValue.resolve().getValueConverter(),
|
||||||
|
tableExpression,
|
||||||
|
basicValue.getColumnIterator().next().getText( dialect )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bootMapKeyDescriptor instanceof Component ) {
|
||||||
|
final Component component = (Component) bootMapKeyDescriptor;
|
||||||
|
final CompositeType compositeType = (CompositeType) component.getType();
|
||||||
|
|
||||||
|
final List<String> columnExpressions = CollectionHelper.arrayList( component.getColumnSpan() );
|
||||||
|
final Iterator<Selectable> columnIterator = component.getColumnIterator();
|
||||||
|
while ( columnIterator.hasNext() ) {
|
||||||
|
columnExpressions.add( columnIterator.next().getText( dialect ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
final EmbeddableMappingType mappingType = EmbeddableMappingType.from(
|
||||||
|
component,
|
||||||
|
compositeType,
|
||||||
|
inflightDescriptor -> new EmbeddedCollectionPart(
|
||||||
|
collectionDescriptor,
|
||||||
|
CollectionPart.Nature.INDEX,
|
||||||
|
inflightDescriptor,
|
||||||
|
// parent-injection
|
||||||
|
null,
|
||||||
|
tableExpression,
|
||||||
|
columnExpressions,
|
||||||
|
sqlAliasStem
|
||||||
|
),
|
||||||
|
creationProcess
|
||||||
|
);
|
||||||
|
|
||||||
|
return (CollectionPart) mappingType.getEmbeddedValueMapping();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NotYetImplementedFor6Exception(
|
||||||
|
"Support for plural attributes with index type [" + bootMapKeyDescriptor + "] not yet implemented"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CollectionPart interpretElement(
|
||||||
|
Collection bootDescriptor,
|
||||||
|
String tableExpression,
|
||||||
|
CollectionPersister collectionDescriptor,
|
||||||
|
String sqlAliasStem,
|
||||||
|
Dialect dialect,
|
||||||
|
MappingModelCreationProcess creationProcess) {
|
||||||
|
final Value element = bootDescriptor.getElement();
|
||||||
|
|
||||||
|
if ( element instanceof BasicValue ) {
|
||||||
|
final BasicValue basicElement = (BasicValue) element;
|
||||||
|
return new BasicValuedCollectionPart(
|
||||||
|
collectionDescriptor,
|
||||||
|
CollectionPart.Nature.ELEMENT,
|
||||||
|
basicElement.resolve().getResolvedBasicType(),
|
||||||
|
basicElement.resolve().getValueConverter(),
|
||||||
|
tableExpression,
|
||||||
|
basicElement.getColumnIterator().next().getText( dialect )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( element instanceof Component ) {
|
||||||
|
final Component component = (Component) element;
|
||||||
|
final CompositeType compositeType = (CompositeType) collectionDescriptor.getElementType();
|
||||||
|
|
||||||
|
final List<String> columnExpressions = CollectionHelper.arrayList( component.getColumnSpan() );
|
||||||
|
final Iterator<Selectable> columnIterator = component.getColumnIterator();
|
||||||
|
while ( columnIterator.hasNext() ) {
|
||||||
|
columnExpressions.add( columnIterator.next().getText( dialect ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
final EmbeddableMappingType mappingType = EmbeddableMappingType.from(
|
||||||
|
component,
|
||||||
|
compositeType,
|
||||||
|
embeddableMappingType -> new EmbeddedCollectionPart(
|
||||||
|
collectionDescriptor,
|
||||||
|
CollectionPart.Nature.ELEMENT,
|
||||||
|
embeddableMappingType,
|
||||||
|
// parent-injection
|
||||||
|
null,
|
||||||
|
tableExpression,
|
||||||
|
columnExpressions,
|
||||||
|
sqlAliasStem
|
||||||
|
),
|
||||||
|
creationProcess
|
||||||
|
);
|
||||||
|
|
||||||
|
return (CollectionPart) mappingType.getEmbeddedValueMapping();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( element instanceof OneToMany || element instanceof ToOne ) {
|
||||||
|
final EntityPersister associatedEntity;
|
||||||
|
|
||||||
|
if ( element instanceof OneToMany ) {
|
||||||
|
associatedEntity = creationProcess.getEntityPersister(
|
||||||
|
( (OneToMany) element ).getReferencedEntityName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// many-to-many
|
||||||
|
associatedEntity = creationProcess.getEntityPersister(
|
||||||
|
( (ToOne) element ).getReferencedEntityName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EntityCollectionPart( CollectionPart.Nature.ELEMENT, associatedEntity );
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NotYetImplementedFor6Exception(
|
||||||
|
"Support for plural attributes with element type [" + element + "] not yet implemented"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private static class CollectionMappingTypeImpl implements CollectionMappingType {
|
private static class CollectionMappingTypeImpl implements CollectionMappingType {
|
||||||
private final JavaTypeDescriptor collectionJtd;
|
private final JavaTypeDescriptor collectionJtd;
|
||||||
private final CollectionSemantics semantics;
|
private final CollectionSemantics semantics;
|
||||||
|
@ -773,7 +1008,7 @@ public class MappingModelCreationHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CollectionSemantics getCCollectionSemantics() {
|
public CollectionSemantics getCollectionSemantics() {
|
||||||
return semantics;
|
return semantics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,17 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.mapping.internal;
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
|
||||||
import org.hibernate.engine.FetchStrategy;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
import org.hibernate.engine.spi.CascadeStyle;
|
import org.hibernate.engine.spi.CascadeStyle;
|
||||||
|
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
||||||
|
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||||
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
|
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
|
@ -20,7 +25,18 @@ import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.property.access.spi.PropertyAccess;
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
|
import org.hibernate.sql.ast.JoinType;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasStemHelper;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroupBuilder;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableReferenceCollector;
|
||||||
|
import org.hibernate.sql.results.internal.domain.collection.DelayedCollectionFetch;
|
||||||
|
import org.hibernate.sql.results.internal.domain.collection.EagerCollectionFetch;
|
||||||
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.spi.Fetch;
|
import org.hibernate.sql.results.spi.Fetch;
|
||||||
import org.hibernate.sql.results.spi.FetchParent;
|
import org.hibernate.sql.results.spi.FetchParent;
|
||||||
|
@ -33,17 +49,18 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
|
||||||
private final PropertyAccess propertyAccess;
|
private final PropertyAccess propertyAccess;
|
||||||
private final StateArrayContributorMetadataAccess stateArrayContributorMetadataAccess;
|
private final StateArrayContributorMetadataAccess stateArrayContributorMetadataAccess;
|
||||||
|
|
||||||
|
private final ForeignKeyDescriptor fkDescriptor;
|
||||||
|
private final CollectionPart elementDescriptor;
|
||||||
|
private final CollectionPart indexDescriptor;
|
||||||
|
private final CollectionIdentifierDescriptor identifierDescriptor;
|
||||||
|
|
||||||
private final FetchStrategy fetchStrategy;
|
private final FetchStrategy fetchStrategy;
|
||||||
|
|
||||||
private final String tableExpression;
|
|
||||||
private final String[] attrColumnExpressions;
|
|
||||||
|
|
||||||
private final ModelPart elementDescriptor;
|
|
||||||
private final ModelPart indexDescriptor;
|
|
||||||
|
|
||||||
private final CascadeStyle cascadeStyle;
|
private final CascadeStyle cascadeStyle;
|
||||||
|
|
||||||
private final CollectionPersister collectionDescriptor;
|
private final CollectionPersister collectionDescriptor;
|
||||||
|
|
||||||
|
private final String sqlAliasStem;
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public PluralAttributeMappingImpl(
|
public PluralAttributeMappingImpl(
|
||||||
String attributeName,
|
String attributeName,
|
||||||
|
@ -51,10 +68,10 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
|
||||||
StateArrayContributorMetadataAccess stateArrayContributorMetadataAccess,
|
StateArrayContributorMetadataAccess stateArrayContributorMetadataAccess,
|
||||||
CollectionMappingType collectionMappingType,
|
CollectionMappingType collectionMappingType,
|
||||||
int stateArrayPosition,
|
int stateArrayPosition,
|
||||||
String tableExpression,
|
ForeignKeyDescriptor fkDescriptor,
|
||||||
String[] attrColumnExpressions,
|
CollectionPart elementDescriptor,
|
||||||
ModelPart elementDescriptor,
|
CollectionPart indexDescriptor,
|
||||||
ModelPart indexDescriptor,
|
CollectionIdentifierDescriptor identifierDescriptor,
|
||||||
FetchStrategy fetchStrategy,
|
FetchStrategy fetchStrategy,
|
||||||
CascadeStyle cascadeStyle,
|
CascadeStyle cascadeStyle,
|
||||||
ManagedMappingType declaringType,
|
ManagedMappingType declaringType,
|
||||||
|
@ -63,36 +80,47 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
|
||||||
this.propertyAccess = propertyAccess;
|
this.propertyAccess = propertyAccess;
|
||||||
this.stateArrayContributorMetadataAccess = stateArrayContributorMetadataAccess;
|
this.stateArrayContributorMetadataAccess = stateArrayContributorMetadataAccess;
|
||||||
this.stateArrayPosition = stateArrayPosition;
|
this.stateArrayPosition = stateArrayPosition;
|
||||||
this.tableExpression = tableExpression;
|
this.fkDescriptor = fkDescriptor;
|
||||||
this.attrColumnExpressions = attrColumnExpressions;
|
|
||||||
this.elementDescriptor = elementDescriptor;
|
this.elementDescriptor = elementDescriptor;
|
||||||
this.indexDescriptor = indexDescriptor;
|
this.indexDescriptor = indexDescriptor;
|
||||||
|
this.identifierDescriptor = identifierDescriptor;
|
||||||
this.fetchStrategy = fetchStrategy;
|
this.fetchStrategy = fetchStrategy;
|
||||||
this.cascadeStyle = cascadeStyle;
|
this.cascadeStyle = cascadeStyle;
|
||||||
this.collectionDescriptor = collectionDescriptor;
|
this.collectionDescriptor = collectionDescriptor;
|
||||||
}
|
|
||||||
|
|
||||||
|
this.sqlAliasStem = SqlAliasStemHelper.INSTANCE.generateStemFromAttributeName( attributeName );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CollectionMappingType getMappedTypeDescriptor() {
|
public CollectionMappingType getMappedTypeDescriptor() {
|
||||||
return (CollectionMappingType) super.getMappedTypeDescriptor();
|
return (CollectionMappingType) super.getMappedTypeDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ForeignKeyDescriptor getKeyDescriptor() {
|
||||||
|
return fkDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CollectionPersister getCollectionDescriptor() {
|
public CollectionPersister getCollectionDescriptor() {
|
||||||
return collectionDescriptor;
|
return collectionDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModelPart getValueDescriptor() {
|
public CollectionPart getElementDescriptor() {
|
||||||
return elementDescriptor;
|
return elementDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModelPart getIndexDescriptor() {
|
public CollectionPart getIndexDescriptor() {
|
||||||
return indexDescriptor;
|
return indexDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionIdentifierDescriptor getIdentifierDescriptor() {
|
||||||
|
return identifierDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStateArrayPosition() {
|
public int getStateArrayPosition() {
|
||||||
return stateArrayPosition;
|
return stateArrayPosition;
|
||||||
|
@ -128,8 +156,119 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
||||||
final TableGroup collectionTableGroup = sqlAstCreationState.getFromClauseAccess().getTableGroup( fetchablePath );
|
|
||||||
|
|
||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
if ( fetchTiming == FetchTiming.IMMEDIATE || selected ) {
|
||||||
|
final TableGroup collectionTableGroup = sqlAstCreationState.getFromClauseAccess().resolveTableGroup(
|
||||||
|
fetchablePath,
|
||||||
|
p -> {
|
||||||
|
final TableGroupJoin tableGroupJoin = createTableGroupJoin(
|
||||||
|
fetchablePath,
|
||||||
|
sqlAstCreationState.getFromClauseAccess().getTableGroup( fetchParent.getNavigablePath() ),
|
||||||
|
null,
|
||||||
|
JoinType.LEFT,
|
||||||
|
lockMode,
|
||||||
|
creationState.getSqlAliasBaseManager(),
|
||||||
|
creationState.getSqlAstCreationState().getSqlExpressionResolver(),
|
||||||
|
creationState.getSqlAstCreationState().getCreationContext()
|
||||||
|
);
|
||||||
|
return tableGroupJoin.getJoinedGroup();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return new EagerCollectionFetch(
|
||||||
|
fetchablePath,
|
||||||
|
this,
|
||||||
|
fkDescriptor.createDomainResult( fetchablePath, collectionTableGroup, creationState ),
|
||||||
|
getAttributeMetadataAccess().resolveAttributeMetadata( null ).isNullable(),
|
||||||
|
fetchParent,
|
||||||
|
creationState
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return new DelayedCollectionFetch(
|
||||||
|
fetchablePath,
|
||||||
|
this,
|
||||||
|
true,
|
||||||
|
fetchParent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSqlAliasStem() {
|
||||||
|
return sqlAliasStem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableGroupJoin createTableGroupJoin(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup lhs,
|
||||||
|
String explicitSourceAlias,
|
||||||
|
JoinType joinType,
|
||||||
|
LockMode lockMode,
|
||||||
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
final String aliasRoot = explicitSourceAlias == null ? sqlAliasStem : explicitSourceAlias;
|
||||||
|
final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( aliasRoot );
|
||||||
|
|
||||||
|
final TableGroupBuilder tableGroupBuilder = TableGroupBuilder.builder(
|
||||||
|
navigablePath,
|
||||||
|
this,
|
||||||
|
lockMode,
|
||||||
|
sqlAliasBase,
|
||||||
|
creationContext.getSessionFactory()
|
||||||
|
);
|
||||||
|
|
||||||
|
applyTableReferences(
|
||||||
|
sqlAliasBase,
|
||||||
|
joinType,
|
||||||
|
tableGroupBuilder,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
);
|
||||||
|
|
||||||
|
return new TableGroupJoin( navigablePath, joinType, tableGroupBuilder.build() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyTableReferences(
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
JoinType baseJoinType,
|
||||||
|
TableReferenceCollector collector,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
getCollectionDescriptor().applyTableReferences( sqlAliasBase, baseJoinType, collector, sqlExpressionResolver, creationContext );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
||||||
|
final CollectionPart.Nature nature = CollectionPart.Nature.fromName( name );
|
||||||
|
if ( nature == CollectionPart.Nature.ELEMENT ) {
|
||||||
|
return elementDescriptor;
|
||||||
|
}
|
||||||
|
else if ( nature == CollectionPart.Nature.INDEX ) {
|
||||||
|
return indexDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSubParts(Consumer<ModelPart> consumer, EntityMappingType treatTargetType) {
|
||||||
|
consumer.accept( elementDescriptor );
|
||||||
|
if ( indexDescriptor != null ) {
|
||||||
|
consumer.accept( indexDescriptor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumberOfFetchables() {
|
||||||
|
return indexDescriptor == null ? 1 : 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PluralAttribute(" + getCollectionDescriptor().getRole() + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* 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.mapping.internal;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
|
import org.hibernate.sql.results.internal.domain.basic.BasicResult;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor {
|
||||||
|
private final String keyColumnExpression;
|
||||||
|
private final JdbcMapping jdbcMapping;
|
||||||
|
|
||||||
|
public SimpleForeignKeyDescriptor(String keyColumnExpression, JdbcMapping jdbcMapping) {
|
||||||
|
this.keyColumnExpression = keyColumnExpression;
|
||||||
|
this.jdbcMapping = jdbcMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DomainResult createDomainResult(
|
||||||
|
NavigablePath collectionPath,
|
||||||
|
TableGroup tableGroup,
|
||||||
|
DomainResultCreationState creationState) {
|
||||||
|
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
||||||
|
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
||||||
|
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
||||||
|
sqlExpressionResolver.resolveSqlExpression(
|
||||||
|
SqlExpressionResolver.createColumnReferenceKey(
|
||||||
|
tableGroup.getPrimaryTableReference(),
|
||||||
|
keyColumnExpression
|
||||||
|
),
|
||||||
|
s -> new ColumnReference(
|
||||||
|
tableGroup.getPrimaryTableReference().getIdentificationVariable(),
|
||||||
|
keyColumnExpression,
|
||||||
|
jdbcMapping,
|
||||||
|
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
|
||||||
|
)
|
||||||
|
),
|
||||||
|
jdbcMapping.getJavaTypeDescriptor(),
|
||||||
|
sqlAstCreationState.getCreationContext().getDomainModel().getTypeConfiguration()
|
||||||
|
);
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
return new BasicResult(
|
||||||
|
sqlSelection.getValuesArrayPosition(),
|
||||||
|
null,
|
||||||
|
jdbcMapping.getJavaTypeDescriptor()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,12 +7,12 @@
|
||||||
package org.hibernate.metamodel.mapping.internal;
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
import org.hibernate.engine.FetchStrategy;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||||
import org.hibernate.metamodel.mapping.MappingType;
|
|
||||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
||||||
import org.hibernate.property.access.spi.PropertyAccess;
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
|
@ -29,7 +29,7 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
|
||||||
int stateArrayPosition,
|
int stateArrayPosition,
|
||||||
StateArrayContributorMetadataAccess attributeMetadataAccess,
|
StateArrayContributorMetadataAccess attributeMetadataAccess,
|
||||||
FetchStrategy mappedFetchStrategy,
|
FetchStrategy mappedFetchStrategy,
|
||||||
MappingType type,
|
EntityMappingType type,
|
||||||
ManagedMappingType declaringType,
|
ManagedMappingType declaringType,
|
||||||
PropertyAccess propertyAccess) {
|
PropertyAccess propertyAccess) {
|
||||||
super(
|
super(
|
||||||
|
@ -43,9 +43,14 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityMappingType getMappedTypeDescriptor() {
|
||||||
|
return (EntityMappingType) super.getMappedTypeDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityMappingType getEntityMappingType() {
|
public EntityMappingType getEntityMappingType() {
|
||||||
return null;
|
return getMappedTypeDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -57,6 +62,11 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
return null;
|
throw new NotYetImplementedFor6Exception( getClass() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumberOfFetchables() {
|
||||||
|
return getEntityMappingType().getNumberOfFetchables();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.FetchMode;
|
import org.hibernate.FetchMode;
|
||||||
|
@ -33,6 +32,7 @@ import org.hibernate.cache.spi.entry.CacheEntryStructure;
|
||||||
import org.hibernate.cache.spi.entry.StructuredCollectionCacheEntry;
|
import org.hibernate.cache.spi.entry.StructuredCollectionCacheEntry;
|
||||||
import org.hibernate.cache.spi.entry.StructuredMapCacheEntry;
|
import org.hibernate.cache.spi.entry.StructuredMapCacheEntry;
|
||||||
import org.hibernate.cache.spi.entry.UnstructuredCacheEntry;
|
import org.hibernate.cache.spi.entry.UnstructuredCacheEntry;
|
||||||
|
import org.hibernate.collection.spi.CollectionSemantics;
|
||||||
import org.hibernate.collection.spi.PersistentCollection;
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
|
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
|
||||||
|
@ -56,6 +56,7 @@ import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
import org.hibernate.jdbc.Expectation;
|
import org.hibernate.jdbc.Expectation;
|
||||||
import org.hibernate.jdbc.Expectations;
|
import org.hibernate.jdbc.Expectations;
|
||||||
import org.hibernate.loader.collection.CollectionInitializer;
|
import org.hibernate.loader.collection.CollectionInitializer;
|
||||||
|
import org.hibernate.mapping.BasicValue;
|
||||||
import org.hibernate.mapping.Collection;
|
import org.hibernate.mapping.Collection;
|
||||||
import org.hibernate.mapping.Column;
|
import org.hibernate.mapping.Column;
|
||||||
import org.hibernate.mapping.Formula;
|
import org.hibernate.mapping.Formula;
|
||||||
|
@ -64,9 +65,9 @@ import org.hibernate.mapping.IndexedCollection;
|
||||||
import org.hibernate.mapping.List;
|
import org.hibernate.mapping.List;
|
||||||
import org.hibernate.mapping.Selectable;
|
import org.hibernate.mapping.Selectable;
|
||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
|
import org.hibernate.mapping.Value;
|
||||||
import org.hibernate.metadata.CollectionMetadata;
|
import org.hibernate.metadata.CollectionMetadata;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
|
||||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.entity.PropertyMapping;
|
import org.hibernate.persister.entity.PropertyMapping;
|
||||||
|
@ -84,18 +85,23 @@ import org.hibernate.persister.walking.spi.CompositeCollectionElementDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
import org.hibernate.sql.Alias;
|
import org.hibernate.sql.Alias;
|
||||||
import org.hibernate.sql.SelectFragment;
|
import org.hibernate.sql.SelectFragment;
|
||||||
import org.hibernate.sql.SimpleSelect;
|
import org.hibernate.sql.SimpleSelect;
|
||||||
import org.hibernate.sql.Template;
|
import org.hibernate.sql.Template;
|
||||||
|
import org.hibernate.sql.ast.JoinType;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableReferenceCollector;
|
||||||
import org.hibernate.type.AnyType;
|
import org.hibernate.type.AnyType;
|
||||||
import org.hibernate.type.AssociationType;
|
import org.hibernate.type.AssociationType;
|
||||||
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.CollectionType;
|
import org.hibernate.type.CollectionType;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
import org.hibernate.type.EntityType;
|
import org.hibernate.type.EntityType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
@ -234,10 +240,26 @@ public abstract class AbstractCollectionPersister
|
||||||
private final Comparator comparator;
|
private final Comparator comparator;
|
||||||
|
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// "mapping model"
|
||||||
|
|
||||||
|
private final CollectionSemantics collectionSemantics;
|
||||||
|
|
||||||
|
private final BasicValueConverter elementConverter;
|
||||||
|
private final BasicValueConverter indexConverter;
|
||||||
|
|
||||||
|
// temprary
|
||||||
|
private final BasicType convertedElementType;
|
||||||
|
private final BasicType convertedIndexType;
|
||||||
|
|
||||||
public AbstractCollectionPersister(
|
public AbstractCollectionPersister(
|
||||||
Collection collectionBinding,
|
Collection collectionBootDescriptor,
|
||||||
CollectionDataAccess cacheAccessStrategy,
|
CollectionDataAccess cacheAccessStrategy,
|
||||||
PersisterCreationContext creationContext) throws MappingException, CacheException {
|
PersisterCreationContext creationContext) throws MappingException, CacheException {
|
||||||
|
final Value elementBootDescriptor = collectionBootDescriptor.getElement();
|
||||||
|
final Value indexBootDescriptor = collectionBootDescriptor instanceof IndexedCollection
|
||||||
|
? ( (IndexedCollection) collectionBootDescriptor ).getIndex()
|
||||||
|
: null;
|
||||||
|
|
||||||
final Database database = creationContext.getMetadata().getDatabase();
|
final Database database = creationContext.getMetadata().getDatabase();
|
||||||
final JdbcEnvironment jdbcEnvironment = database.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = database.getJdbcEnvironment();
|
||||||
|
@ -245,7 +267,7 @@ public abstract class AbstractCollectionPersister
|
||||||
this.factory = creationContext.getSessionFactory();
|
this.factory = creationContext.getSessionFactory();
|
||||||
this.cacheAccessStrategy = cacheAccessStrategy;
|
this.cacheAccessStrategy = cacheAccessStrategy;
|
||||||
if ( factory.getSessionFactoryOptions().isStructuredCacheEntriesEnabled() ) {
|
if ( factory.getSessionFactoryOptions().isStructuredCacheEntriesEnabled() ) {
|
||||||
cacheEntryStructure = collectionBinding.isMap()
|
cacheEntryStructure = collectionBootDescriptor.isMap()
|
||||||
? StructuredMapCacheEntry.INSTANCE
|
? StructuredMapCacheEntry.INSTANCE
|
||||||
: StructuredCollectionCacheEntry.INSTANCE;
|
: StructuredCollectionCacheEntry.INSTANCE;
|
||||||
}
|
}
|
||||||
|
@ -255,54 +277,54 @@ public abstract class AbstractCollectionPersister
|
||||||
|
|
||||||
dialect = factory.getDialect();
|
dialect = factory.getDialect();
|
||||||
sqlExceptionHelper = factory.getSQLExceptionHelper();
|
sqlExceptionHelper = factory.getSQLExceptionHelper();
|
||||||
collectionType = collectionBinding.getCollectionType();
|
collectionType = collectionBootDescriptor.getCollectionType();
|
||||||
navigableRole = new NavigableRole( collectionBinding.getRole() );
|
navigableRole = new NavigableRole( collectionBootDescriptor.getRole() );
|
||||||
entityName = collectionBinding.getOwnerEntityName();
|
entityName = collectionBootDescriptor.getOwnerEntityName();
|
||||||
ownerPersister = factory.getEntityPersister( entityName );
|
ownerPersister = factory.getEntityPersister( entityName );
|
||||||
queryLoaderName = collectionBinding.getLoaderName();
|
queryLoaderName = collectionBootDescriptor.getLoaderName();
|
||||||
isMutable = collectionBinding.isMutable();
|
isMutable = collectionBootDescriptor.isMutable();
|
||||||
mappedByProperty = collectionBinding.getMappedByProperty();
|
mappedByProperty = collectionBootDescriptor.getMappedByProperty();
|
||||||
|
|
||||||
Table table = collectionBinding.getCollectionTable();
|
Table table = collectionBootDescriptor.getCollectionTable();
|
||||||
fetchMode = collectionBinding.getElement().getFetchMode();
|
fetchMode = elementBootDescriptor.getFetchMode();
|
||||||
elementType = collectionBinding.getElement().getType();
|
elementType = elementBootDescriptor.getType();
|
||||||
// isSet = collectionBinding.isSet();
|
// isSet = collectionBinding.isSet();
|
||||||
// isSorted = collectionBinding.isSorted();
|
// isSorted = collectionBinding.isSorted();
|
||||||
isPrimitiveArray = collectionBinding.isPrimitiveArray();
|
isPrimitiveArray = collectionBootDescriptor.isPrimitiveArray();
|
||||||
isArray = collectionBinding.isArray();
|
isArray = collectionBootDescriptor.isArray();
|
||||||
subselectLoadable = collectionBinding.isSubselectLoadable();
|
subselectLoadable = collectionBootDescriptor.isSubselectLoadable();
|
||||||
|
|
||||||
qualifiedTableName = determineTableName( table, jdbcEnvironment );
|
qualifiedTableName = determineTableName( table, jdbcEnvironment );
|
||||||
|
|
||||||
int spacesSize = 1 + collectionBinding.getSynchronizedTables().size();
|
int spacesSize = 1 + collectionBootDescriptor.getSynchronizedTables().size();
|
||||||
spaces = new String[spacesSize];
|
spaces = new String[spacesSize];
|
||||||
spaces[0] = qualifiedTableName;
|
spaces[0] = qualifiedTableName;
|
||||||
Iterator iter = collectionBinding.getSynchronizedTables().iterator();
|
Iterator iter = collectionBootDescriptor.getSynchronizedTables().iterator();
|
||||||
for ( int i = 1; i < spacesSize; i++ ) {
|
for ( int i = 1; i < spacesSize; i++ ) {
|
||||||
spaces[i] = (String) iter.next();
|
spaces[i] = (String) iter.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlWhereString = StringHelper.isNotEmpty( collectionBinding.getWhere() ) ? "( " + collectionBinding.getWhere() + ") " : null;
|
sqlWhereString = StringHelper.isNotEmpty( collectionBootDescriptor.getWhere() ) ? "( " + collectionBootDescriptor.getWhere() + ") " : null;
|
||||||
hasWhere = sqlWhereString != null;
|
hasWhere = sqlWhereString != null;
|
||||||
sqlWhereStringTemplate = hasWhere ?
|
sqlWhereStringTemplate = hasWhere ?
|
||||||
Template.renderWhereStringTemplate( sqlWhereString, dialect, factory.getSqlFunctionRegistry() ) :
|
Template.renderWhereStringTemplate( sqlWhereString, dialect, factory.getSqlFunctionRegistry() ) :
|
||||||
null;
|
null;
|
||||||
|
|
||||||
hasOrphanDelete = collectionBinding.hasOrphanDelete();
|
hasOrphanDelete = collectionBootDescriptor.hasOrphanDelete();
|
||||||
|
|
||||||
int batch = collectionBinding.getBatchSize();
|
int batch = collectionBootDescriptor.getBatchSize();
|
||||||
if ( batch == -1 ) {
|
if ( batch == -1 ) {
|
||||||
batch = factory.getSessionFactoryOptions().getDefaultBatchFetchSize();
|
batch = factory.getSessionFactoryOptions().getDefaultBatchFetchSize();
|
||||||
}
|
}
|
||||||
batchSize = batch;
|
batchSize = batch;
|
||||||
|
|
||||||
isVersioned = collectionBinding.isOptimisticLocked();
|
isVersioned = collectionBootDescriptor.isOptimisticLocked();
|
||||||
|
|
||||||
// KEY
|
// KEY
|
||||||
|
|
||||||
keyType = collectionBinding.getKey().getType();
|
keyType = collectionBootDescriptor.getKey().getType();
|
||||||
iter = collectionBinding.getKey().getColumnIterator();
|
iter = collectionBootDescriptor.getKey().getColumnIterator();
|
||||||
int keySpan = collectionBinding.getKey().getColumnSpan();
|
int keySpan = collectionBootDescriptor.getKey().getColumnSpan();
|
||||||
keyColumnNames = new String[keySpan];
|
keyColumnNames = new String[keySpan];
|
||||||
keyColumnAliases = new String[keySpan];
|
keyColumnAliases = new String[keySpan];
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
@ -328,7 +350,7 @@ public abstract class AbstractCollectionPersister
|
||||||
elementPersister = null;
|
elementPersister = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int elementSpan = collectionBinding.getElement().getColumnSpan();
|
int elementSpan = elementBootDescriptor.getColumnSpan();
|
||||||
elementColumnAliases = new String[elementSpan];
|
elementColumnAliases = new String[elementSpan];
|
||||||
elementColumnNames = new String[elementSpan];
|
elementColumnNames = new String[elementSpan];
|
||||||
elementColumnWriters = new String[elementSpan];
|
elementColumnWriters = new String[elementSpan];
|
||||||
|
@ -341,13 +363,13 @@ public abstract class AbstractCollectionPersister
|
||||||
elementColumnIsInPrimaryKey = new boolean[elementSpan];
|
elementColumnIsInPrimaryKey = new boolean[elementSpan];
|
||||||
boolean isPureFormula = true;
|
boolean isPureFormula = true;
|
||||||
boolean hasNotNullableColumns = false;
|
boolean hasNotNullableColumns = false;
|
||||||
boolean oneToMany = collectionBinding.isOneToMany();
|
boolean oneToMany = collectionBootDescriptor.isOneToMany();
|
||||||
boolean[] columnInsertability = null;
|
boolean[] columnInsertability = null;
|
||||||
if ( !oneToMany ) {
|
if ( !oneToMany ) {
|
||||||
columnInsertability = collectionBinding.getElement().getColumnInsertability();
|
columnInsertability = elementBootDescriptor.getColumnInsertability();
|
||||||
}
|
}
|
||||||
int j = 0;
|
int j = 0;
|
||||||
iter = collectionBinding.getElement().getColumnIterator();
|
iter = elementBootDescriptor.getColumnIterator();
|
||||||
while ( iter.hasNext() ) {
|
while ( iter.hasNext() ) {
|
||||||
Selectable selectable = (Selectable) iter.next();
|
Selectable selectable = (Selectable) iter.next();
|
||||||
elementColumnAliases[j] = selectable.getAlias( dialect, table );
|
elementColumnAliases[j] = selectable.getAlias( dialect, table );
|
||||||
|
@ -390,10 +412,10 @@ public abstract class AbstractCollectionPersister
|
||||||
|
|
||||||
// INDEX AND ROW SELECT
|
// INDEX AND ROW SELECT
|
||||||
|
|
||||||
hasIndex = collectionBinding.isIndexed();
|
hasIndex = collectionBootDescriptor.isIndexed();
|
||||||
if ( hasIndex ) {
|
if ( hasIndex ) {
|
||||||
// NativeSQL: collect index column and auto-aliases
|
// NativeSQL: collect index column and auto-aliases
|
||||||
IndexedCollection indexedCollection = (IndexedCollection) collectionBinding;
|
IndexedCollection indexedCollection = (IndexedCollection) collectionBootDescriptor;
|
||||||
indexType = indexedCollection.getIndex().getType();
|
indexType = indexedCollection.getIndex().getType();
|
||||||
int indexSpan = indexedCollection.getIndex().getColumnSpan();
|
int indexSpan = indexedCollection.getIndex().getColumnSpan();
|
||||||
boolean[] indexColumnInsertability = indexedCollection.getIndex().getColumnInsertability();
|
boolean[] indexColumnInsertability = indexedCollection.getIndex().getColumnInsertability();
|
||||||
|
@ -440,12 +462,12 @@ public abstract class AbstractCollectionPersister
|
||||||
baseIndex = 0;
|
baseIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasIdentifier = collectionBinding.isIdentified();
|
hasIdentifier = collectionBootDescriptor.isIdentified();
|
||||||
if ( hasIdentifier ) {
|
if ( hasIdentifier ) {
|
||||||
if ( collectionBinding.isOneToMany() ) {
|
if ( collectionBootDescriptor.isOneToMany() ) {
|
||||||
throw new MappingException( "one-to-many collections with identifiers are not supported" );
|
throw new MappingException( "one-to-many collections with identifiers are not supported" );
|
||||||
}
|
}
|
||||||
IdentifierCollection idColl = (IdentifierCollection) collectionBinding;
|
IdentifierCollection idColl = (IdentifierCollection) collectionBootDescriptor;
|
||||||
identifierType = idColl.getIdentifier().getType();
|
identifierType = idColl.getIdentifier().getType();
|
||||||
iter = idColl.getIdentifier().getColumnIterator();
|
iter = idColl.getIdentifier().getColumnIterator();
|
||||||
Column col = (Column) iter.next();
|
Column col = (Column) iter.next();
|
||||||
|
@ -473,68 +495,68 @@ public abstract class AbstractCollectionPersister
|
||||||
// sqlSelectString = sqlSelectString();
|
// sqlSelectString = sqlSelectString();
|
||||||
// sqlSelectRowString = sqlSelectRowString();
|
// sqlSelectRowString = sqlSelectRowString();
|
||||||
|
|
||||||
if ( collectionBinding.getCustomSQLInsert() == null ) {
|
if ( collectionBootDescriptor.getCustomSQLInsert() == null ) {
|
||||||
sqlInsertRowString = generateInsertRowString();
|
sqlInsertRowString = generateInsertRowString();
|
||||||
insertCallable = false;
|
insertCallable = false;
|
||||||
insertCheckStyle = ExecuteUpdateResultCheckStyle.COUNT;
|
insertCheckStyle = ExecuteUpdateResultCheckStyle.COUNT;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sqlInsertRowString = collectionBinding.getCustomSQLInsert();
|
sqlInsertRowString = collectionBootDescriptor.getCustomSQLInsert();
|
||||||
insertCallable = collectionBinding.isCustomInsertCallable();
|
insertCallable = collectionBootDescriptor.isCustomInsertCallable();
|
||||||
insertCheckStyle = collectionBinding.getCustomSQLInsertCheckStyle() == null
|
insertCheckStyle = collectionBootDescriptor.getCustomSQLInsertCheckStyle() == null
|
||||||
? ExecuteUpdateResultCheckStyle.determineDefault( collectionBinding.getCustomSQLInsert(), insertCallable )
|
? ExecuteUpdateResultCheckStyle.determineDefault( collectionBootDescriptor.getCustomSQLInsert(), insertCallable )
|
||||||
: collectionBinding.getCustomSQLInsertCheckStyle();
|
: collectionBootDescriptor.getCustomSQLInsertCheckStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( collectionBinding.getCustomSQLUpdate() == null ) {
|
if ( collectionBootDescriptor.getCustomSQLUpdate() == null ) {
|
||||||
sqlUpdateRowString = generateUpdateRowString();
|
sqlUpdateRowString = generateUpdateRowString();
|
||||||
updateCallable = false;
|
updateCallable = false;
|
||||||
updateCheckStyle = ExecuteUpdateResultCheckStyle.COUNT;
|
updateCheckStyle = ExecuteUpdateResultCheckStyle.COUNT;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sqlUpdateRowString = collectionBinding.getCustomSQLUpdate();
|
sqlUpdateRowString = collectionBootDescriptor.getCustomSQLUpdate();
|
||||||
updateCallable = collectionBinding.isCustomUpdateCallable();
|
updateCallable = collectionBootDescriptor.isCustomUpdateCallable();
|
||||||
updateCheckStyle = collectionBinding.getCustomSQLUpdateCheckStyle() == null
|
updateCheckStyle = collectionBootDescriptor.getCustomSQLUpdateCheckStyle() == null
|
||||||
? ExecuteUpdateResultCheckStyle.determineDefault( collectionBinding.getCustomSQLUpdate(), insertCallable )
|
? ExecuteUpdateResultCheckStyle.determineDefault( collectionBootDescriptor.getCustomSQLUpdate(), insertCallable )
|
||||||
: collectionBinding.getCustomSQLUpdateCheckStyle();
|
: collectionBootDescriptor.getCustomSQLUpdateCheckStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( collectionBinding.getCustomSQLDelete() == null ) {
|
if ( collectionBootDescriptor.getCustomSQLDelete() == null ) {
|
||||||
sqlDeleteRowString = generateDeleteRowString();
|
sqlDeleteRowString = generateDeleteRowString();
|
||||||
deleteCallable = false;
|
deleteCallable = false;
|
||||||
deleteCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
|
deleteCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sqlDeleteRowString = collectionBinding.getCustomSQLDelete();
|
sqlDeleteRowString = collectionBootDescriptor.getCustomSQLDelete();
|
||||||
deleteCallable = collectionBinding.isCustomDeleteCallable();
|
deleteCallable = collectionBootDescriptor.isCustomDeleteCallable();
|
||||||
deleteCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
|
deleteCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( collectionBinding.getCustomSQLDeleteAll() == null ) {
|
if ( collectionBootDescriptor.getCustomSQLDeleteAll() == null ) {
|
||||||
sqlDeleteString = generateDeleteString();
|
sqlDeleteString = generateDeleteString();
|
||||||
deleteAllCallable = false;
|
deleteAllCallable = false;
|
||||||
deleteAllCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
|
deleteAllCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sqlDeleteString = collectionBinding.getCustomSQLDeleteAll();
|
sqlDeleteString = collectionBootDescriptor.getCustomSQLDeleteAll();
|
||||||
deleteAllCallable = collectionBinding.isCustomDeleteAllCallable();
|
deleteAllCallable = collectionBootDescriptor.isCustomDeleteAllCallable();
|
||||||
deleteAllCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
|
deleteAllCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlSelectSizeString = generateSelectSizeString( collectionBinding.isIndexed() && !collectionBinding.isMap() );
|
sqlSelectSizeString = generateSelectSizeString( collectionBootDescriptor.isIndexed() && !collectionBootDescriptor.isMap() );
|
||||||
sqlDetectRowByIndexString = generateDetectRowByIndexString();
|
sqlDetectRowByIndexString = generateDetectRowByIndexString();
|
||||||
sqlDetectRowByElementString = generateDetectRowByElementString();
|
sqlDetectRowByElementString = generateDetectRowByElementString();
|
||||||
sqlSelectRowByIndexString = generateSelectRowByIndexString();
|
sqlSelectRowByIndexString = generateSelectRowByIndexString();
|
||||||
|
|
||||||
logStaticSQL();
|
logStaticSQL();
|
||||||
|
|
||||||
isLazy = collectionBinding.isLazy();
|
isLazy = collectionBootDescriptor.isLazy();
|
||||||
isExtraLazy = collectionBinding.isExtraLazy();
|
isExtraLazy = collectionBootDescriptor.isExtraLazy();
|
||||||
|
|
||||||
isInverse = collectionBinding.isInverse();
|
isInverse = collectionBootDescriptor.isInverse();
|
||||||
|
|
||||||
if ( collectionBinding.isArray() ) {
|
if ( collectionBootDescriptor.isArray() ) {
|
||||||
elementClass = ( (org.hibernate.mapping.Array) collectionBinding ).getElementClass();
|
elementClass = ( (org.hibernate.mapping.Array) collectionBootDescriptor ).getElementClass();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// for non-arrays, we don't need to know the element class
|
// for non-arrays, we don't need to know the element class
|
||||||
|
@ -569,9 +591,9 @@ public abstract class AbstractCollectionPersister
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasOrder = collectionBinding.getOrderBy() != null;
|
hasOrder = collectionBootDescriptor.getOrderBy() != null;
|
||||||
if ( hasOrder ) {
|
if ( hasOrder ) {
|
||||||
LOG.debugf( "Translating order-by fragment [%s] for collection role : %s", collectionBinding.getOrderBy(), getRole() );
|
LOG.debugf( "Translating order-by fragment [%s] for collection role : %s", collectionBootDescriptor.getOrderBy(), getRole() );
|
||||||
// orderByTranslation = Template.translateOrderBy(
|
// orderByTranslation = Template.translateOrderBy(
|
||||||
// collectionBinding.getOrderBy(),
|
// collectionBinding.getOrderBy(),
|
||||||
// new ColumnMapperImpl(),
|
// new ColumnMapperImpl(),
|
||||||
|
@ -587,20 +609,20 @@ public abstract class AbstractCollectionPersister
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle any filters applied to this collectionBinding
|
// Handle any filters applied to this collectionBinding
|
||||||
filterHelper = new FilterHelper( collectionBinding.getFilters(), factory);
|
filterHelper = new FilterHelper( collectionBootDescriptor.getFilters(), factory);
|
||||||
|
|
||||||
// Handle any filters applied to this collectionBinding for many-to-many
|
// Handle any filters applied to this collectionBinding for many-to-many
|
||||||
manyToManyFilterHelper = new FilterHelper( collectionBinding.getManyToManyFilters(), factory);
|
manyToManyFilterHelper = new FilterHelper( collectionBootDescriptor.getManyToManyFilters(), factory);
|
||||||
manyToManyWhereString = StringHelper.isNotEmpty( collectionBinding.getManyToManyWhere() ) ?
|
manyToManyWhereString = StringHelper.isNotEmpty( collectionBootDescriptor.getManyToManyWhere() ) ?
|
||||||
"( " + collectionBinding.getManyToManyWhere() + ")" :
|
"( " + collectionBootDescriptor.getManyToManyWhere() + ")" :
|
||||||
null;
|
null;
|
||||||
manyToManyWhereTemplate = manyToManyWhereString == null ?
|
manyToManyWhereTemplate = manyToManyWhereString == null ?
|
||||||
null :
|
null :
|
||||||
Template.renderWhereStringTemplate( manyToManyWhereString, factory.getDialect(), factory.getSqlFunctionRegistry() );
|
Template.renderWhereStringTemplate( manyToManyWhereString, factory.getDialect(), factory.getSqlFunctionRegistry() );
|
||||||
|
|
||||||
hasManyToManyOrder = collectionBinding.getManyToManyOrdering() != null;
|
hasManyToManyOrder = collectionBootDescriptor.getManyToManyOrdering() != null;
|
||||||
if ( hasManyToManyOrder ) {
|
if ( hasManyToManyOrder ) {
|
||||||
LOG.debugf( "Translating many-to-many order-by fragment [%s] for collection role : %s", collectionBinding.getOrderBy(), getRole() );
|
LOG.debugf( "Translating many-to-many order-by fragment [%s] for collection role : %s", collectionBootDescriptor.getOrderBy(), getRole() );
|
||||||
// manyToManyOrderByTranslation = Template.translateOrderBy(
|
// manyToManyOrderByTranslation = Template.translateOrderBy(
|
||||||
// collectionBinding.getManyToManyOrdering(),
|
// collectionBinding.getManyToManyOrdering(),
|
||||||
// new ColumnMapperImpl(),
|
// new ColumnMapperImpl(),
|
||||||
|
@ -614,9 +636,37 @@ public abstract class AbstractCollectionPersister
|
||||||
// manyToManyOrderByTranslation = null;
|
// manyToManyOrderByTranslation = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
comparator = collectionBinding.getComparator();
|
comparator = collectionBootDescriptor.getComparator();
|
||||||
|
|
||||||
initCollectionPropertyMap();
|
initCollectionPropertyMap();
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// "mapping model"
|
||||||
|
|
||||||
|
this.collectionSemantics = creationContext.getBootstrapContext()
|
||||||
|
.getMetadataBuildingOptions()
|
||||||
|
.getPersistentCollectionRepresentationResolver()
|
||||||
|
.resolveRepresentation( collectionBootDescriptor );
|
||||||
|
|
||||||
|
if ( elementBootDescriptor instanceof BasicValue ) {
|
||||||
|
final BasicValue.Resolution<?> basicTypeResolution = ( (BasicValue) elementBootDescriptor ).resolve();
|
||||||
|
this.elementConverter = basicTypeResolution.getValueConverter();
|
||||||
|
this.convertedElementType = basicTypeResolution.getResolvedBasicType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.elementConverter = null;
|
||||||
|
this.convertedElementType = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( indexBootDescriptor instanceof BasicValue ) {
|
||||||
|
final BasicValue.Resolution<?> basicTypeResolution = ( (BasicValue) indexBootDescriptor ).resolve();
|
||||||
|
this.indexConverter = basicTypeResolution.getValueConverter();
|
||||||
|
this.convertedIndexType = basicTypeResolution.getResolvedBasicType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.indexConverter = null;
|
||||||
|
this.convertedIndexType = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -872,6 +922,16 @@ public abstract class AbstractCollectionPersister
|
||||||
return elementType;
|
return elementType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BasicValueConverter getElementConverter() {
|
||||||
|
return elementConverter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BasicValueConverter getIndexConverter() {
|
||||||
|
return indexConverter;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the element class of an array, or null otherwise. needed by arrays
|
* Return the element class of an array, or null otherwise. needed by arrays
|
||||||
*/
|
*/
|
||||||
|
@ -947,7 +1007,14 @@ public abstract class AbstractCollectionPersister
|
||||||
*/
|
*/
|
||||||
protected int writeElement(PreparedStatement st, Object elt, int i, SharedSessionContractImplementor session)
|
protected int writeElement(PreparedStatement st, Object elt, int i, SharedSessionContractImplementor session)
|
||||||
throws HibernateException, SQLException {
|
throws HibernateException, SQLException {
|
||||||
getElementType().nullSafeSet( st, elt, i, elementColumnIsSettable, session );
|
if ( elementConverter != null ) {
|
||||||
|
//noinspection unchecked
|
||||||
|
final Object converted = elementConverter.toRelationalValue( elt );
|
||||||
|
convertedElementType.getJdbcValueBinder().bind( st, converted, i, session );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
getElementType().nullSafeSet( st, elt, i, elementColumnIsSettable, session );
|
||||||
|
}
|
||||||
return i + ArrayHelper.countTrue( elementColumnIsSettable );
|
return i + ArrayHelper.countTrue( elementColumnIsSettable );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -957,7 +1024,16 @@ public abstract class AbstractCollectionPersister
|
||||||
*/
|
*/
|
||||||
protected int writeIndex(PreparedStatement st, Object index, int i, SharedSessionContractImplementor session)
|
protected int writeIndex(PreparedStatement st, Object index, int i, SharedSessionContractImplementor session)
|
||||||
throws HibernateException, SQLException {
|
throws HibernateException, SQLException {
|
||||||
getIndexType().nullSafeSet( st, incrementIndexByBase( index ), i, indexColumnIsSettable, session );
|
if ( indexConverter != null ) {
|
||||||
|
//noinspection unchecked
|
||||||
|
final Object converted = indexConverter.toRelationalValue( index );
|
||||||
|
//noinspection unchecked
|
||||||
|
convertedIndexType.getJdbcValueBinder().bind( st, converted, i, session );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
getIndexType().nullSafeSet( st, incrementIndexByBase( index ), i, indexColumnIsSettable, session );
|
||||||
|
}
|
||||||
|
|
||||||
return i + ArrayHelper.countTrue( indexColumnIsSettable );
|
return i + ArrayHelper.countTrue( indexColumnIsSettable );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -976,7 +1052,13 @@ public abstract class AbstractCollectionPersister
|
||||||
if ( elementIsPureFormula ) {
|
if ( elementIsPureFormula ) {
|
||||||
throw new AssertionFailure( "cannot use a formula-based element in the where condition" );
|
throw new AssertionFailure( "cannot use a formula-based element in the where condition" );
|
||||||
}
|
}
|
||||||
getElementType().nullSafeSet( st, elt, i, elementColumnIsInPrimaryKey, session );
|
if ( elementConverter != null ) {
|
||||||
|
final Object converted = elementConverter.toRelationalValue( elt );
|
||||||
|
convertedElementType.getJdbcValueBinder().bind( st, converted, i, session );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
getElementType().nullSafeSet( st, elt, i, elementColumnIsInPrimaryKey, session );
|
||||||
|
}
|
||||||
return i + elementColumnAliases.length;
|
return i + elementColumnAliases.length;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -989,7 +1071,13 @@ public abstract class AbstractCollectionPersister
|
||||||
if ( indexContainsFormula ) {
|
if ( indexContainsFormula ) {
|
||||||
throw new AssertionFailure( "cannot use a formula-based index in the where condition" );
|
throw new AssertionFailure( "cannot use a formula-based index in the where condition" );
|
||||||
}
|
}
|
||||||
getIndexType().nullSafeSet( st, incrementIndexByBase( index ), i, session );
|
if ( indexConverter != null ) {
|
||||||
|
final Object converted = indexConverter.toRelationalValue( index );
|
||||||
|
convertedIndexType.getJdbcValueBinder().bind( st, converted, i, session );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
getIndexType().nullSafeSet( st, incrementIndexByBase( index ), i, session );
|
||||||
|
}
|
||||||
return i + indexColumnAliases.length;
|
return i + indexColumnAliases.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2297,4 +2385,51 @@ public abstract class AbstractCollectionPersister
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// "mapping model"
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyTableReferences(
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
JoinType baseJoinType,
|
||||||
|
TableReferenceCollector collector,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
if ( isOneToMany() ) {
|
||||||
|
// one-to-many does not define a "collection table"
|
||||||
|
assert elementPersister != null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// we do have a "collection table" - apply it first
|
||||||
|
collector.applySecondaryTableReferences(
|
||||||
|
new TableReference( qualifiedTableName, sqlAliasBase.generateNewAlias(), false, getFactory() ),
|
||||||
|
baseJoinType,
|
||||||
|
(lhs, rhs, joinType) -> {
|
||||||
|
// create the join-predicate between the owner table and the collection table
|
||||||
|
throw new NotYetImplementedFor6Exception( getClass() );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( elementPersister != null ) {
|
||||||
|
elementPersister.applyTableReferences(
|
||||||
|
sqlAliasBase,
|
||||||
|
// todo (6.0) : determine the proper join-type to use
|
||||||
|
JoinType.LEFT,
|
||||||
|
collector,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionSemantics getCollectionSemantics() {
|
||||||
|
return collectionSemantics;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.loader.collection.BatchingCollectionInitializerBuilder;
|
||||||
import org.hibernate.loader.collection.CollectionInitializer;
|
import org.hibernate.loader.collection.CollectionInitializer;
|
||||||
import org.hibernate.loader.collection.SubselectCollectionLoader;
|
import org.hibernate.loader.collection.SubselectCollectionLoader;
|
||||||
import org.hibernate.mapping.Collection;
|
import org.hibernate.mapping.Collection;
|
||||||
|
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||||
import org.hibernate.persister.entity.Joinable;
|
import org.hibernate.persister.entity.Joinable;
|
||||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
|
|
|
@ -14,17 +14,26 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
import org.hibernate.cache.spi.access.CollectionDataAccess;
|
import org.hibernate.cache.spi.access.CollectionDataAccess;
|
||||||
import org.hibernate.cache.spi.entry.CacheEntryStructure;
|
import org.hibernate.cache.spi.entry.CacheEntryStructure;
|
||||||
|
import org.hibernate.collection.spi.CollectionSemantics;
|
||||||
import org.hibernate.collection.spi.PersistentCollection;
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.id.IdentifierGenerator;
|
import org.hibernate.id.IdentifierGenerator;
|
||||||
import org.hibernate.metadata.CollectionMetadata;
|
import org.hibernate.metadata.CollectionMetadata;
|
||||||
import org.hibernate.metamodel.CollectionClassification;
|
import org.hibernate.metamodel.CollectionClassification;
|
||||||
|
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
|
import org.hibernate.sql.ast.JoinType;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableReferenceCollector;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableReferenceContributor;
|
||||||
import org.hibernate.type.CollectionType;
|
import org.hibernate.type.CollectionType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
@ -62,7 +71,7 @@ import org.hibernate.type.Type;
|
||||||
* @see org.hibernate.collection.spi.PersistentCollection
|
* @see org.hibernate.collection.spi.PersistentCollection
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public interface CollectionPersister extends CollectionDefinition {
|
public interface CollectionPersister extends CollectionDefinition, TableReferenceContributor {
|
||||||
/**
|
/**
|
||||||
* Initialize the given collection with the given key
|
* Initialize the given collection with the given key
|
||||||
* TODO: add owner argument!!
|
* TODO: add owner argument!!
|
||||||
|
@ -103,6 +112,21 @@ public interface CollectionPersister extends CollectionDefinition {
|
||||||
* Return the element class of an array, or null otherwise
|
* Return the element class of an array, or null otherwise
|
||||||
*/
|
*/
|
||||||
Class getElementClass();
|
Class getElementClass();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value converter for the element values of this collection
|
||||||
|
*/
|
||||||
|
default BasicValueConverter getElementConverter() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value converter for index values of this collection (effectively map keys only)
|
||||||
|
*/
|
||||||
|
default BasicValueConverter getIndexConverter() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the key from a row of the JDBC <tt>ResultSet</tt>
|
* Read the key from a row of the JDBC <tt>ResultSet</tt>
|
||||||
*/
|
*/
|
||||||
|
@ -332,4 +356,30 @@ public interface CollectionPersister extends CollectionDefinition {
|
||||||
* @see CollectionClassification#SORTED_SET
|
* @see CollectionClassification#SORTED_SET
|
||||||
*/
|
*/
|
||||||
Comparator<?> getSortingComparator();
|
Comparator<?> getSortingComparator();
|
||||||
|
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// mapping model
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void applyTableReferences(
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
JoinType baseJoinType,
|
||||||
|
TableReferenceCollector collector,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
throw new NotYetImplementedFor6Exception(
|
||||||
|
"The persister used for this collection [" + getNavigableRole()
|
||||||
|
+ "] does not yet implement support for use in SQL AST creation;"
|
||||||
|
+ " should implement `TableReferenceContributor#applyTableReferences`"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
default CollectionSemantics getCollectionSemantics() {
|
||||||
|
throw new NotYetImplementedFor6Exception(
|
||||||
|
"The persister used for this collection [" + getNavigableRole()
|
||||||
|
+ "] does not yet implement support for `"
|
||||||
|
+ CollectionSemantics.class.getName() + "`"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,9 @@ import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
|
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
|
||||||
import org.hibernate.sql.ast.tree.from.StandardTableGroup;
|
import org.hibernate.sql.ast.tree.from.StandardTableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroupBuilder;
|
||||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableReferenceCollector;
|
||||||
import org.hibernate.sql.ast.tree.from.TableReferenceJoin;
|
import org.hibernate.sql.ast.tree.from.TableReferenceJoin;
|
||||||
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
|
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
|
||||||
import org.hibernate.sql.ast.tree.predicate.Junction;
|
import org.hibernate.sql.ast.tree.predicate.Junction;
|
||||||
|
@ -1187,20 +1189,23 @@ public abstract class AbstractEntityPersister
|
||||||
SqlAstCreationContext creationContext) {
|
SqlAstCreationContext creationContext) {
|
||||||
final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( getSqlAliasStem() );
|
final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( getSqlAliasStem() );
|
||||||
|
|
||||||
final TableReference primaryTableReference = resolvePrimaryTableReference( sqlAliasBase, sqlExpressionResolver );
|
final TableGroupBuilder builder = TableGroupBuilder.builder(
|
||||||
|
|
||||||
final List<TableReferenceJoin> joins = new ArrayList<>( );
|
|
||||||
resolveTableReferenceJoins( primaryTableReference, sqlAliasBase, tableReferenceJoinType, joins::add, sqlExpressionResolver );
|
|
||||||
|
|
||||||
return new StandardTableGroup(
|
|
||||||
navigablePath,
|
navigablePath,
|
||||||
this,
|
this,
|
||||||
lockMode,
|
lockMode,
|
||||||
primaryTableReference,
|
|
||||||
joins,
|
|
||||||
sqlAliasBase,
|
sqlAliasBase,
|
||||||
getFactory()
|
creationContext.getSessionFactory()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
applyTableReferences(
|
||||||
|
sqlAliasBase,
|
||||||
|
tableReferenceJoinType,
|
||||||
|
builder,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
);
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TableReference resolvePrimaryTableReference(
|
protected TableReference resolvePrimaryTableReference(
|
||||||
|
@ -1228,6 +1233,33 @@ public abstract class AbstractEntityPersister
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyTableReferences(
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
org.hibernate.sql.ast.JoinType baseJoinType,
|
||||||
|
TableReferenceCollector collector,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
final TableReference primaryTableReference = resolvePrimaryTableReference(
|
||||||
|
sqlAliasBase,
|
||||||
|
sqlExpressionResolver
|
||||||
|
);
|
||||||
|
|
||||||
|
collector.applyPrimaryReference( primaryTableReference );
|
||||||
|
|
||||||
|
for ( int i = 1; i < getSubclassTableSpan(); i++ ) {
|
||||||
|
collector.addTableReferenceJoin(
|
||||||
|
createTableReferenceJoin(
|
||||||
|
i,
|
||||||
|
primaryTableReference,
|
||||||
|
baseJoinType,
|
||||||
|
sqlAliasBase,
|
||||||
|
sqlExpressionResolver
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected TableReferenceJoin createTableReferenceJoin(
|
protected TableReferenceJoin createTableReferenceJoin(
|
||||||
int subClassTablePosition,
|
int subClassTablePosition,
|
||||||
TableReference rootTableReference,
|
TableReference rootTableReference,
|
||||||
|
@ -6483,6 +6515,11 @@ public abstract class AbstractEntityPersister
|
||||||
// otherwise, nothing to do
|
// otherwise, nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumberOfFetchables() {
|
||||||
|
return attributeMappings.size();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitFetchables(
|
public void visitFetchables(
|
||||||
Consumer<Fetchable> fetchableConsumer,
|
Consumer<Fetchable> fetchableConsumer,
|
||||||
|
|
|
@ -38,8 +38,13 @@ import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
|
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
|
||||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
|
import org.hibernate.sql.ast.JoinType;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
import org.hibernate.sql.ast.spi.SqlAliasStemHelper;
|
import org.hibernate.sql.ast.spi.SqlAliasStemHelper;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
import org.hibernate.sql.ast.tree.from.RootTableGroupProducer;
|
import org.hibernate.sql.ast.tree.from.RootTableGroupProducer;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableReferenceCollector;
|
||||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
@ -93,6 +98,11 @@ public interface EntityPersister extends EntityDefinition, EntityValuedModelPart
|
||||||
@Deprecated
|
@Deprecated
|
||||||
void generateEntityDefinition();
|
void generateEntityDefinition();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default int getNumberOfFetchables() {
|
||||||
|
return getNumberOfAttributeMappings();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finish the initialization of this object. {@link #prepareMappingModel}
|
* Finish the initialization of this object. {@link #prepareMappingModel}
|
||||||
* must be called for all entity persisters before calling this method.
|
* must be called for all entity persisters before calling this method.
|
||||||
|
@ -906,6 +916,4 @@ public interface EntityPersister extends EntityDefinition, EntityValuedModelPart
|
||||||
default boolean canIdentityInsertBeDelayed() {
|
default boolean canIdentityInsertBeDelayed() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -499,6 +499,7 @@ public abstract class BaseSqmToSqlAstConverter
|
||||||
creationContext
|
creationContext
|
||||||
);
|
);
|
||||||
|
|
||||||
|
lhsTableGroup.addTableGroupJoin( tableGroupJoin );
|
||||||
fromClauseIndex.register( sqmJoin, tableGroupJoin.getJoinedGroup() );
|
fromClauseIndex.register( sqmJoin, tableGroupJoin.getJoinedGroup() );
|
||||||
|
|
||||||
// add any additional join restrictions
|
// add any additional join restrictions
|
||||||
|
|
|
@ -37,7 +37,6 @@ public class FromClauseIndex extends SimpleFromClauseAccessImpl {
|
||||||
* Holds *explicitly* fetched joins
|
* Holds *explicitly* fetched joins
|
||||||
*/
|
*/
|
||||||
private Map<NavigablePath, SqmAttributeJoin> fetchesByPath;
|
private Map<NavigablePath, SqmAttributeJoin> fetchesByPath;
|
||||||
private Map<NavigablePath, Map<NavigablePath, SqmAttributeJoin>> fetchesByParentPath;
|
|
||||||
|
|
||||||
private final Set<String> affectedTableNames = new HashSet<>();
|
private final Set<String> affectedTableNames = new HashSet<>();
|
||||||
|
|
||||||
|
@ -61,6 +60,20 @@ public class FromClauseIndex extends SimpleFromClauseAccessImpl {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( sqmPath instanceof SqmAttributeJoin ) {
|
||||||
|
final SqmAttributeJoin sqmJoin = (SqmAttributeJoin) sqmPath;
|
||||||
|
if ( sqmJoin.isFetched() ) {
|
||||||
|
registerJoinFetch( sqmJoin );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerJoinFetch(SqmAttributeJoin sqmJoin) {
|
||||||
|
if ( fetchesByPath == null ) {
|
||||||
|
fetchesByPath = new HashMap<>();
|
||||||
|
}
|
||||||
|
fetchesByPath.put( sqmJoin.getNavigablePath(), sqmJoin );
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isResolved(SqmFrom fromElement) {
|
public boolean isResolved(SqmFrom fromElement) {
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.hibernate.query.spi.QueryParameterBindings;
|
||||||
import org.hibernate.query.sqm.internal.DomainParameterXref;
|
import org.hibernate.query.sqm.internal.DomainParameterXref;
|
||||||
import org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter;
|
import org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
||||||
|
import org.hibernate.query.sqm.sql.SqmSelectToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
||||||
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
|
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
||||||
|
@ -67,7 +68,7 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class StandardSqmSelectToSqlAstConverter
|
public class StandardSqmSelectToSqlAstConverter
|
||||||
extends BaseSqmToSqlAstConverter
|
extends BaseSqmToSqlAstConverter
|
||||||
implements DomainResultCreationState, org.hibernate.query.sqm.sql.SqmSelectToSqlAstConverter {
|
implements DomainResultCreationState, SqmSelectToSqlAstConverter {
|
||||||
private final LoadQueryInfluencers fetchInfluencers;
|
private final LoadQueryInfluencers fetchInfluencers;
|
||||||
private final CircularFetchDetector circularFetchDetector = new CircularFetchDetector();
|
private final CircularFetchDetector circularFetchDetector = new CircularFetchDetector();
|
||||||
|
|
||||||
|
@ -155,7 +156,7 @@ public class StandardSqmSelectToSqlAstConverter
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Fetch> visitFetches(FetchParent fetchParent) {
|
public List<Fetch> visitFetches(FetchParent fetchParent) {
|
||||||
final List<Fetch> fetches = CollectionHelper.arrayList( fetchParent.getReferencedMappingType().getNumberOfAttributeMappings() );
|
final List<Fetch> fetches = CollectionHelper.arrayList( fetchParent.getReferencedMappingType().getNumberOfFetchables() );
|
||||||
|
|
||||||
//noinspection Convert2Lambda
|
//noinspection Convert2Lambda
|
||||||
final Consumer<Fetchable> fetchableConsumer = new Consumer<Fetchable>() {
|
final Consumer<Fetchable> fetchableConsumer = new Consumer<Fetchable>() {
|
||||||
|
@ -214,7 +215,7 @@ public class StandardSqmSelectToSqlAstConverter
|
||||||
|
|
||||||
if ( fetchedJoin != null ) {
|
if ( fetchedJoin != null ) {
|
||||||
// there was an explicit fetch in the SQM
|
// there was an explicit fetch in the SQM
|
||||||
// there should be a TableGroupJoin registered n SqmJoin registered for this `fetchablePath` already
|
// there should be a TableGroupJoin registered for this `fetchablePath` already
|
||||||
// because it
|
// because it
|
||||||
assert getFromClauseIndex().getTableGroup( fetchablePath ) != null;
|
assert getFromClauseIndex().getTableGroup( fetchablePath ) != null;
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,18 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.sql.ast.tree.from;
|
package org.hibernate.sql.ast.tree.from;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.sql.ast.JoinType;
|
||||||
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -23,7 +28,7 @@ public class StandardTableGroup extends AbstractTableGroup {
|
||||||
|
|
||||||
public StandardTableGroup(
|
public StandardTableGroup(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
RootTableGroupProducer tableGroupProducer,
|
TableGroupProducer tableGroupProducer,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
TableReference primaryTableReference,
|
TableReference primaryTableReference,
|
||||||
List<TableReferenceJoin> tableJoins,
|
List<TableReferenceJoin> tableJoins,
|
||||||
|
@ -34,11 +39,6 @@ public class StandardTableGroup extends AbstractTableGroup {
|
||||||
this.tableJoins = tableJoins;
|
this.tableJoins = tableJoins;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public RootTableGroupProducer getModelPart() {
|
|
||||||
return (RootTableGroupProducer) super.getModelPart();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyAffectedTableNames(Consumer<String> nameCollector) {
|
public void applyAffectedTableNames(Consumer<String> nameCollector) {
|
||||||
// todo (6.0) : if we implement dynamic TableReference creation, this still needs to return the expressions for all mapped tables not just the ones with a TableReference at this time
|
// todo (6.0) : if we implement dynamic TableReference creation, this still needs to return the expressions for all mapped tables not just the ones with a TableReference at this time
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* 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.sql.ast.tree.from;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.sql.ast.JoinType;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class TableGroupBuilder implements TableReferenceCollector {
|
||||||
|
public static TableGroupBuilder builder(
|
||||||
|
NavigablePath path,
|
||||||
|
TableGroupProducer producer,
|
||||||
|
LockMode lockMode,
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
SessionFactoryImplementor sessionFactory) {
|
||||||
|
return new TableGroupBuilder( path, producer, lockMode, sqlAliasBase, sessionFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
private final NavigablePath path;
|
||||||
|
private final TableGroupProducer producer;
|
||||||
|
private final SessionFactoryImplementor sessionFactory;
|
||||||
|
|
||||||
|
private final SqlAliasBase sqlAliasBase;
|
||||||
|
private final LockMode lockMode;
|
||||||
|
|
||||||
|
private final Function<TableReference,TableReferenceJoin> primaryJoinProducer;
|
||||||
|
|
||||||
|
private TableReference primaryTableReference;
|
||||||
|
private TableReference secondaryTableLhs;
|
||||||
|
|
||||||
|
private java.util.List<TableReferenceJoin> tableJoins;
|
||||||
|
|
||||||
|
private TableGroupBuilder(
|
||||||
|
NavigablePath path,
|
||||||
|
TableGroupProducer producer,
|
||||||
|
LockMode lockMode,
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
SessionFactoryImplementor sessionFactory) {
|
||||||
|
this( path, producer, lockMode, sqlAliasBase, null, sessionFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
private TableGroupBuilder(
|
||||||
|
NavigablePath path,
|
||||||
|
TableGroupProducer producer,
|
||||||
|
LockMode lockMode,
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
Function<TableReference,TableReferenceJoin> primaryJoinProducer,
|
||||||
|
SessionFactoryImplementor sessionFactory) {
|
||||||
|
this.path = path;
|
||||||
|
this.producer = producer;
|
||||||
|
this.lockMode = lockMode;
|
||||||
|
this.sqlAliasBase = sqlAliasBase;
|
||||||
|
this.primaryJoinProducer = primaryJoinProducer;
|
||||||
|
this.sessionFactory = sessionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableGroup build() {
|
||||||
|
if ( primaryTableReference == null ) {
|
||||||
|
throw new IllegalStateException( "Primary TableReference was not specified : " + path );
|
||||||
|
}
|
||||||
|
|
||||||
|
return new StandardTableGroup(
|
||||||
|
path,
|
||||||
|
producer,
|
||||||
|
lockMode,
|
||||||
|
primaryTableReference,
|
||||||
|
tableJoins == null ? Collections.emptyList() : tableJoins,
|
||||||
|
sqlAliasBase,
|
||||||
|
sessionFactory
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyPrimaryReference(TableReference tableReference) {
|
||||||
|
if ( primaryTableReference != null ) {
|
||||||
|
assert primaryJoinProducer != null;
|
||||||
|
|
||||||
|
addTableReferenceJoin( primaryJoinProducer.apply( tableReference ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
primaryTableReference = tableReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
secondaryTableLhs = tableReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applySecondaryTableReferences(
|
||||||
|
TableReference tableReference,
|
||||||
|
JoinType tableReferenceJoinType,
|
||||||
|
TableReferenceJoinPredicateProducer predicateProducer) {
|
||||||
|
if ( primaryTableReference == null ) {
|
||||||
|
primaryTableReference = tableReference;
|
||||||
|
secondaryTableLhs = primaryTableReference;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addTableReferenceJoin(
|
||||||
|
new TableReferenceJoin(
|
||||||
|
tableReferenceJoinType,
|
||||||
|
tableReference,
|
||||||
|
predicateProducer.producePredicate(
|
||||||
|
secondaryTableLhs,
|
||||||
|
tableReference,
|
||||||
|
tableReferenceJoinType
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTableReferenceJoin(TableReferenceJoin join) {
|
||||||
|
if ( tableJoins == null ) {
|
||||||
|
tableJoins = new ArrayList<>();
|
||||||
|
}
|
||||||
|
tableJoins.add( join );
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ import org.hibernate.query.sqm.sql.SqlAliasBaseManager;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @author Andrea Boriero
|
* @author Andrea Boriero
|
||||||
*/
|
*/
|
||||||
public interface TableGroupProducer extends ModelPartContainer {
|
public interface TableGroupProducer extends ModelPartContainer, TableReferenceContributor {
|
||||||
/**
|
/**
|
||||||
* Get the "stem" used as the base for generating SQL table aliases for table
|
* Get the "stem" used as the base for generating SQL table aliases for table
|
||||||
* references that are part of the TableGroup being generated
|
* references that are part of the TableGroup being generated
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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.sql.ast.tree.from;
|
||||||
|
|
||||||
|
import org.hibernate.sql.ast.JoinType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used in constructing {@link TableGroup} references to collect the individual table
|
||||||
|
* references
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface TableReferenceCollector {
|
||||||
|
void applyPrimaryReference(TableReference tableReference);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collect a table reference as part of the TableGroup.
|
||||||
|
*
|
||||||
|
* @param tableReference The TableReference.
|
||||||
|
* @param joinType The type of join indicated by the mapping of the table, if it is to be joined
|
||||||
|
* @param predicateProducer Function for creating the join predicate, if it is to be joined. The first
|
||||||
|
* argument passed to the function is the LHS reference. The second is the same as `tableReference`.
|
||||||
|
* The result is a SQL AST Predicate to use as the join-predicate
|
||||||
|
*/
|
||||||
|
void applySecondaryTableReferences(
|
||||||
|
TableReference tableReference,
|
||||||
|
JoinType joinType,
|
||||||
|
TableReferenceJoinPredicateProducer predicateProducer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directly add a TableReferenceJoin
|
||||||
|
*/
|
||||||
|
void addTableReferenceJoin(TableReferenceJoin join);
|
||||||
|
}
|
|
@ -6,19 +6,22 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.sql.ast.tree.from;
|
package org.hibernate.sql.ast.tree.from;
|
||||||
|
|
||||||
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
import org.hibernate.sql.ast.JoinType;
|
import org.hibernate.sql.ast.JoinType;
|
||||||
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface TableReferenceContributor {
|
public interface TableReferenceContributor {
|
||||||
// /**
|
/**
|
||||||
// * Apply the Tables mapped by this producer to the collector as TableReferences
|
* Apply the Tables mapped by this producer to the collector as TableReferences
|
||||||
// */
|
*/
|
||||||
// void applyTableReferenceJoins(
|
void applyTableReferences(
|
||||||
// ColumnReferenceQualifier lhs,
|
SqlAliasBase sqlAliasBase,
|
||||||
// JoinType joinType,
|
JoinType baseJoinType,
|
||||||
// SqlAliasBase sqlAliasBase,
|
TableReferenceCollector collector,
|
||||||
// TableReferenceJoinCollector joinCollector);
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.sql.ast.tree.from;
|
||||||
|
|
||||||
|
import org.hibernate.sql.ast.JoinType;
|
||||||
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functional contract for producing the join-predicate related to a {@link TableReferenceJoin}.
|
||||||
|
*
|
||||||
|
* @see TableReferenceJoin#getJoinPredicate
|
||||||
|
* @see TableReferenceCollector#applySecondaryTableReferences
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public
|
||||||
|
interface TableReferenceJoinPredicateProducer {
|
||||||
|
Predicate producePredicate(TableReference lhs, TableReference rhs, JoinType joinType);
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.sql.results.internal;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
|
import org.hibernate.engine.spi.CollectionEntry;
|
||||||
|
import org.hibernate.engine.spi.PersistenceContext;
|
||||||
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||||
|
import org.hibernate.sql.results.spi.CollectionInitializer;
|
||||||
|
import org.hibernate.sql.results.spi.LoadingCollectionEntry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a collection currently being loaded.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class LoadingCollectionEntryImpl implements LoadingCollectionEntry {
|
||||||
|
private final CollectionPersister collectionDescriptor;
|
||||||
|
private final CollectionInitializer initializer;
|
||||||
|
private final Object key;
|
||||||
|
private final PersistentCollection collectionInstance;
|
||||||
|
|
||||||
|
public LoadingCollectionEntryImpl(
|
||||||
|
CollectionPersister collectionDescriptor,
|
||||||
|
CollectionInitializer initializer,
|
||||||
|
Object key,
|
||||||
|
PersistentCollection collectionInstance) {
|
||||||
|
this.collectionDescriptor = collectionDescriptor;
|
||||||
|
this.initializer = initializer;
|
||||||
|
this.key = key;
|
||||||
|
this.collectionInstance = collectionInstance;
|
||||||
|
|
||||||
|
collectionInstance.beforeInitialize( getCollectionDescriptor(), -1 );
|
||||||
|
collectionInstance.beginRead();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public CollectionPersister getCollectionDescriptor() {
|
||||||
|
return collectionDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access to the initializer that is responsible for initializing this collection
|
||||||
|
*/
|
||||||
|
@Override public CollectionInitializer getInitializer() {
|
||||||
|
return initializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public Serializable getKey() {
|
||||||
|
// todo (6.0) : change from Serializable to Object
|
||||||
|
return (Serializable) key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public PersistentCollection getCollectionInstance() {
|
||||||
|
return collectionInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getSimpleName() + "(" + getCollectionDescriptor().getNavigableRole().getFullPath() + "#" + getKey() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void finishLoading(ExecutionContext executionContext) {
|
||||||
|
collectionInstance.endRead();
|
||||||
|
|
||||||
|
final SharedSessionContractImplementor session = executionContext.getSession();
|
||||||
|
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||||
|
final CollectionPersister collectionDescriptor = getCollectionDescriptor();
|
||||||
|
|
||||||
|
CollectionEntry collectionEntry = persistenceContext.getCollectionEntry( collectionInstance );
|
||||||
|
if ( collectionEntry == null ) {
|
||||||
|
collectionEntry = persistenceContext.addInitializedCollection(
|
||||||
|
collectionDescriptor,
|
||||||
|
getCollectionInstance(),
|
||||||
|
getKey()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
collectionEntry.postInitialize( collectionInstance );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( collectionDescriptor.getCollectionType().hasHolder() ) {
|
||||||
|
persistenceContext.addCollectionHolder( collectionInstance );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// todo (6.0) : there is other logic still needing to be implemented here. caching, etc
|
||||||
|
// see org.hibernate.engine.loading.internal.CollectionLoadContext#endLoadingCollection in 5.x
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,9 @@ import java.util.List;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.named.RowReaderMemento;
|
import org.hibernate.query.named.RowReaderMemento;
|
||||||
import org.hibernate.sql.exec.spi.Callback;
|
import org.hibernate.sql.exec.spi.Callback;
|
||||||
|
import org.hibernate.sql.results.spi.CollectionInitializer;
|
||||||
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.sql.results.spi.EntityInitializer;
|
||||||
import org.hibernate.sql.results.spi.Initializer;
|
import org.hibernate.sql.results.spi.Initializer;
|
||||||
import org.hibernate.sql.results.spi.JdbcValuesSourceProcessingOptions;
|
import org.hibernate.sql.results.spi.JdbcValuesSourceProcessingOptions;
|
||||||
import org.hibernate.sql.results.spi.JdbcValuesSourceProcessingState;
|
import org.hibernate.sql.results.spi.JdbcValuesSourceProcessingState;
|
||||||
|
@ -125,7 +127,17 @@ public class StandardRowReader<T> implements RowReader<T> {
|
||||||
// old
|
// old
|
||||||
|
|
||||||
for ( int i = 0; i < initializers.size(); i++ ) {
|
for ( int i = 0; i < initializers.size(); i++ ) {
|
||||||
initializers.get( i ).resolveKey( rowProcessingState );
|
final Initializer initializer = initializers.get( i );
|
||||||
|
if ( ! ( initializer instanceof CollectionInitializer ) ) {
|
||||||
|
initializer.resolveKey( rowProcessingState );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int i = 0; i < initializers.size(); i++ ) {
|
||||||
|
final Initializer initializer = initializers.get( i );
|
||||||
|
if ( initializer instanceof CollectionInitializer ) {
|
||||||
|
initializer.resolveKey( rowProcessingState );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( int i = 0; i < initializers.size(); i++ ) {
|
for ( int i = 0; i < initializers.size(); i++ ) {
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* 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.sql.results.internal.domain.collection;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
|
import org.hibernate.sql.results.spi.Fetch;
|
||||||
|
import org.hibernate.sql.results.spi.FetchParent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public abstract class CollectionFetch implements Fetch {
|
||||||
|
private final NavigablePath fetchedPath;
|
||||||
|
private final PluralAttributeMapping fetchedAttribute;
|
||||||
|
|
||||||
|
private final boolean nullable;
|
||||||
|
|
||||||
|
private final FetchParent fetchParent;
|
||||||
|
|
||||||
|
public CollectionFetch(
|
||||||
|
NavigablePath fetchedPath,
|
||||||
|
PluralAttributeMapping fetchedAttribute,
|
||||||
|
boolean nullable,
|
||||||
|
FetchParent fetchParent) {
|
||||||
|
this.fetchedPath = fetchedPath;
|
||||||
|
this.fetchedAttribute = fetchedAttribute;
|
||||||
|
this.fetchParent = fetchParent;
|
||||||
|
this.nullable = nullable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FetchParent getFetchParent() {
|
||||||
|
return fetchParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PluralAttributeMapping getFetchedMapping() {
|
||||||
|
return fetchedAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NavigablePath getNavigablePath() {
|
||||||
|
return fetchedPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNullable() {
|
||||||
|
return nullable;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* 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.sql.results.internal.domain.collection;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.hibernate.collection.spi.CollectionSemantics;
|
||||||
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
|
import org.hibernate.engine.spi.CollectionKey;
|
||||||
|
import org.hibernate.engine.spi.PersistenceContext;
|
||||||
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.sql.results.spi.AssemblerCreationState;
|
||||||
|
import org.hibernate.sql.results.spi.CollectionInitializer;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.sql.results.spi.FetchParentAccess;
|
||||||
|
import org.hibernate.sql.results.spi.Initializer;
|
||||||
|
import org.hibernate.sql.results.spi.JdbcValuesSourceProcessingOptions;
|
||||||
|
import org.hibernate.sql.results.spi.LoadingCollectionEntry;
|
||||||
|
import org.hibernate.sql.results.spi.RowProcessingState;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class DelayedCollectionAssembler implements DomainResultAssembler {
|
||||||
|
private final PluralAttributeMapping fetchedMapping;
|
||||||
|
private final FetchParentAccess parentAccess;
|
||||||
|
|
||||||
|
private final CollectionInitializer initializer;
|
||||||
|
|
||||||
|
public DelayedCollectionAssembler(
|
||||||
|
NavigablePath fetchPath,
|
||||||
|
PluralAttributeMapping fetchedMapping,
|
||||||
|
FetchParentAccess parentAccess,
|
||||||
|
Consumer<Initializer> collector,
|
||||||
|
AssemblerCreationState creationState) {
|
||||||
|
this.fetchedMapping = fetchedMapping;
|
||||||
|
this.parentAccess = parentAccess;
|
||||||
|
this.initializer = new InitializerImpl( fetchPath, fetchedMapping, parentAccess, creationState );
|
||||||
|
collector.accept( initializer );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options) {
|
||||||
|
return initializer.getCollectionInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JavaTypeDescriptor getAssembledJavaTypeDescriptor() {
|
||||||
|
return fetchedMapping.getJavaTypeDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class InitializerImpl implements CollectionInitializer {
|
||||||
|
private final NavigablePath fetchedPath;
|
||||||
|
private final PluralAttributeMapping fetchedMapping;
|
||||||
|
private final FetchParentAccess parentAccess;
|
||||||
|
|
||||||
|
private CollectionKey collectionKey;
|
||||||
|
private PersistentCollection instance;
|
||||||
|
|
||||||
|
public InitializerImpl(
|
||||||
|
NavigablePath fetchedPath,
|
||||||
|
PluralAttributeMapping fetchedMapping,
|
||||||
|
FetchParentAccess parentAccess,
|
||||||
|
AssemblerCreationState creationState) {
|
||||||
|
this.fetchedPath = fetchedPath;
|
||||||
|
this.fetchedMapping = fetchedMapping;
|
||||||
|
this.parentAccess = parentAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NavigablePath getNavigablePath() {
|
||||||
|
return fetchedPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolveKey(RowProcessingState rowProcessingState) {
|
||||||
|
if ( collectionKey != null ) {
|
||||||
|
// already resolved
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
collectionKey = new CollectionKey(
|
||||||
|
fetchedMapping.getCollectionDescriptor(),
|
||||||
|
parentAccess.getParentKey()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolveInstance(RowProcessingState rowProcessingState) {
|
||||||
|
final SharedSessionContractImplementor session = rowProcessingState.getSession();
|
||||||
|
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||||
|
final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts().findLoadingCollectionEntry( collectionKey );
|
||||||
|
final PersistentCollection registeredInstance = persistenceContext.getCollection( collectionKey );
|
||||||
|
|
||||||
|
if ( loadingEntry != null ) {
|
||||||
|
instance = loadingEntry.getCollectionInstance();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( registeredInstance != null ) {
|
||||||
|
this.instance = registeredInstance;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.instance = makePersistentCollection( fetchedMapping, collectionKey, rowProcessingState );
|
||||||
|
persistenceContext.addUninitializedCollection(
|
||||||
|
getInitializingCollectionDescriptor(),
|
||||||
|
instance,
|
||||||
|
(Serializable) collectionKey.getKey()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PersistentCollection makePersistentCollection(
|
||||||
|
PluralAttributeMapping fetchedMapping,
|
||||||
|
CollectionKey collectionKey,
|
||||||
|
RowProcessingState rowProcessingState) {
|
||||||
|
final CollectionPersister collectionDescriptor = fetchedMapping.getCollectionDescriptor();
|
||||||
|
final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics();
|
||||||
|
return collectionSemantics.instantiateWrapper(
|
||||||
|
collectionKey.getKey(),
|
||||||
|
collectionDescriptor,
|
||||||
|
rowProcessingState.getSession()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initializeInstance(RowProcessingState rowProcessingState) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finishUpRow(RowProcessingState rowProcessingState) {
|
||||||
|
collectionKey = null;
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionPersister getInitializingCollectionDescriptor() {
|
||||||
|
return fetchedMapping.getCollectionDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PersistentCollection getCollectionInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* 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.sql.results.internal.domain.collection;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.sql.results.spi.AssemblerCreationState;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.sql.results.spi.FetchParent;
|
||||||
|
import org.hibernate.sql.results.spi.FetchParentAccess;
|
||||||
|
import org.hibernate.sql.results.spi.Initializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class DelayedCollectionFetch extends CollectionFetch {
|
||||||
|
public DelayedCollectionFetch(
|
||||||
|
NavigablePath fetchedPath,
|
||||||
|
PluralAttributeMapping fetchedAttribute,
|
||||||
|
boolean nullable,
|
||||||
|
FetchParent fetchParent) {
|
||||||
|
super( fetchedPath, fetchedAttribute, nullable, fetchParent );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DomainResultAssembler createAssembler(
|
||||||
|
FetchParentAccess parentAccess,
|
||||||
|
Consumer<Initializer> collector,
|
||||||
|
AssemblerCreationState creationState) {
|
||||||
|
return new DelayedCollectionAssembler(
|
||||||
|
getNavigablePath(),
|
||||||
|
getFetchedMapping(),
|
||||||
|
parentAccess,
|
||||||
|
collector,
|
||||||
|
creationState
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,258 @@
|
||||||
|
/*
|
||||||
|
* 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.sql.results.internal.domain.collection;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.hibernate.collection.spi.CollectionSemantics;
|
||||||
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
|
import org.hibernate.engine.spi.CollectionKey;
|
||||||
|
import org.hibernate.engine.spi.PersistenceContext;
|
||||||
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.sql.results.internal.LoadingCollectionEntryImpl;
|
||||||
|
import org.hibernate.sql.results.spi.AssemblerCreationState;
|
||||||
|
import org.hibernate.sql.results.spi.CollectionInitializer;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.sql.results.spi.Fetch;
|
||||||
|
import org.hibernate.sql.results.spi.FetchParentAccess;
|
||||||
|
import org.hibernate.sql.results.spi.Initializer;
|
||||||
|
import org.hibernate.sql.results.spi.JdbcValuesSourceProcessingOptions;
|
||||||
|
import org.hibernate.sql.results.spi.LoadContexts;
|
||||||
|
import org.hibernate.sql.results.spi.LoadingCollectionEntry;
|
||||||
|
import org.hibernate.sql.results.spi.RowProcessingState;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class EagerCollectionAssembler implements DomainResultAssembler {
|
||||||
|
private final PluralAttributeMapping fetchedMapping;
|
||||||
|
private final FetchParentAccess parentAccess;
|
||||||
|
|
||||||
|
private final CollectionInitializer initializer;
|
||||||
|
|
||||||
|
public EagerCollectionAssembler(
|
||||||
|
NavigablePath fetchPath,
|
||||||
|
PluralAttributeMapping fetchedMapping,
|
||||||
|
DomainResult fkResult,
|
||||||
|
Fetch elementFetch,
|
||||||
|
Fetch indexFetch,
|
||||||
|
DomainResult identifierResult,
|
||||||
|
FetchParentAccess parentAccess,
|
||||||
|
Consumer<Initializer> collector,
|
||||||
|
AssemblerCreationState creationState) {
|
||||||
|
this.fetchedMapping = fetchedMapping;
|
||||||
|
this.parentAccess = parentAccess;
|
||||||
|
|
||||||
|
this.initializer = new InitializerImpl(
|
||||||
|
fetchPath,
|
||||||
|
fetchedMapping,
|
||||||
|
parentAccess,
|
||||||
|
fkResult,
|
||||||
|
elementFetch,
|
||||||
|
indexFetch,
|
||||||
|
identifierResult,
|
||||||
|
collector,
|
||||||
|
creationState
|
||||||
|
);
|
||||||
|
|
||||||
|
collector.accept( initializer );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options) {
|
||||||
|
return initializer.getCollectionInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JavaTypeDescriptor getAssembledJavaTypeDescriptor() {
|
||||||
|
return fetchedMapping.getJavaTypeDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class InitializerImpl implements CollectionInitializer {
|
||||||
|
private final NavigablePath fetchedPath;
|
||||||
|
private final PluralAttributeMapping fetchedMapping;
|
||||||
|
private final FetchParentAccess parentAccess;
|
||||||
|
|
||||||
|
private final DomainResultAssembler fkAssembler;
|
||||||
|
private final DomainResultAssembler elementAssembler;
|
||||||
|
private final DomainResultAssembler indexAssembler;
|
||||||
|
private final DomainResultAssembler identifierAssembler;
|
||||||
|
|
||||||
|
private CollectionKey collectionKey;
|
||||||
|
|
||||||
|
private boolean managing;
|
||||||
|
private Object fkValue;
|
||||||
|
|
||||||
|
// todo (6.0) : consider using the initializer itself as the holder of the various "temp" collections
|
||||||
|
// used while reading a collection. that would mean collection-type specific initializers (List, versus Set)
|
||||||
|
private PersistentCollection instance;
|
||||||
|
|
||||||
|
public InitializerImpl(
|
||||||
|
NavigablePath fetchedPath,
|
||||||
|
PluralAttributeMapping fetchedMapping,
|
||||||
|
FetchParentAccess parentAccess,
|
||||||
|
DomainResult fkResult,
|
||||||
|
Fetch elementFetch,
|
||||||
|
Fetch indexFetch,
|
||||||
|
DomainResult identifierResult,
|
||||||
|
Consumer<Initializer> collector,
|
||||||
|
AssemblerCreationState creationState) {
|
||||||
|
this.fetchedPath = fetchedPath;
|
||||||
|
this.fetchedMapping = fetchedMapping;
|
||||||
|
this.parentAccess = parentAccess;
|
||||||
|
|
||||||
|
this.fkAssembler = fkResult.createResultAssembler( collector, creationState );
|
||||||
|
|
||||||
|
// questionable what should be the parent access here
|
||||||
|
this.elementAssembler = elementFetch.createAssembler( parentAccess, collector, creationState );
|
||||||
|
this.indexAssembler = indexFetch == null
|
||||||
|
? null
|
||||||
|
: indexFetch.createAssembler( parentAccess, collector, creationState );
|
||||||
|
this.identifierAssembler = identifierResult == null
|
||||||
|
? null
|
||||||
|
: identifierResult.createResultAssembler( collector, creationState );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionPersister getInitializingCollectionDescriptor() {
|
||||||
|
return fetchedMapping.getCollectionDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PersistentCollection getCollectionInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NavigablePath getNavigablePath() {
|
||||||
|
return fetchedPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finishUpRow(RowProcessingState rowProcessingState) {
|
||||||
|
collectionKey = null;
|
||||||
|
managing = false;
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolveKey(RowProcessingState rowProcessingState) {
|
||||||
|
if ( collectionKey != null ) {
|
||||||
|
// already resolved
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
collectionKey = new CollectionKey(
|
||||||
|
fetchedMapping.getCollectionDescriptor(),
|
||||||
|
parentAccess.getParentKey()
|
||||||
|
);
|
||||||
|
|
||||||
|
final Object fkValue = fkAssembler.assemble( rowProcessingState );
|
||||||
|
if ( fkValue == null ) {
|
||||||
|
// this row has no collection element
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolveInstance(RowProcessingState rowProcessingState) {
|
||||||
|
if ( instance != null ) {
|
||||||
|
// already resolved
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final PersistenceContext persistenceContext = rowProcessingState.getSession().getPersistenceContext();
|
||||||
|
|
||||||
|
// see if the collection is already being initialized
|
||||||
|
|
||||||
|
final LoadContexts loadContexts = persistenceContext.getLoadContexts();
|
||||||
|
final LoadingCollectionEntry existingEntry = loadContexts.findLoadingCollectionEntry( collectionKey );
|
||||||
|
|
||||||
|
if ( existingEntry != null ) {
|
||||||
|
this.instance = existingEntry.getCollectionInstance();
|
||||||
|
if ( existingEntry.getInitializer() == this ) {
|
||||||
|
this.managing = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// see if it has been already registered with the Session
|
||||||
|
|
||||||
|
final PersistentCollection registeredInstance = persistenceContext.getCollection( collectionKey );
|
||||||
|
if ( registeredInstance != null ) {
|
||||||
|
this.instance = registeredInstance;
|
||||||
|
// it was already registered, so use that wrapper.
|
||||||
|
if ( ! registeredInstance.wasInitialized() ) {
|
||||||
|
// if the existing wrapper is not initialized, we will take responsibility for initializing it
|
||||||
|
managing = true;
|
||||||
|
rowProcessingState.getJdbcValuesSourceProcessingState().registerLoadingCollection(
|
||||||
|
collectionKey,
|
||||||
|
new LoadingCollectionEntryImpl(
|
||||||
|
getInitializingCollectionDescriptor(),
|
||||||
|
this,
|
||||||
|
collectionKey,
|
||||||
|
registeredInstance
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.instance = makePersistentCollection( fetchedMapping, collectionKey, rowProcessingState );
|
||||||
|
this.managing = true;
|
||||||
|
|
||||||
|
rowProcessingState.getJdbcValuesSourceProcessingState().registerLoadingCollection(
|
||||||
|
collectionKey,
|
||||||
|
new LoadingCollectionEntryImpl(
|
||||||
|
fetchedMapping.getCollectionDescriptor(),
|
||||||
|
this,
|
||||||
|
collectionKey.getKey(),
|
||||||
|
instance
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PersistentCollection makePersistentCollection(
|
||||||
|
PluralAttributeMapping fetchedMapping,
|
||||||
|
CollectionKey collectionKey,
|
||||||
|
RowProcessingState rowProcessingState) {
|
||||||
|
final CollectionPersister collectionDescriptor = fetchedMapping.getCollectionDescriptor();
|
||||||
|
final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics();
|
||||||
|
return collectionSemantics.instantiateWrapper(
|
||||||
|
collectionKey.getKey(),
|
||||||
|
collectionDescriptor,
|
||||||
|
rowProcessingState.getSession()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initializeInstance(RowProcessingState rowProcessingState) {
|
||||||
|
if ( ! managing ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Object fkValue = fkAssembler.assemble( rowProcessingState );
|
||||||
|
if ( fkValue == null ) {
|
||||||
|
// this row contains no collection element
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCollectionInstance().readFrom(
|
||||||
|
rowProcessingState,
|
||||||
|
elementAssembler,
|
||||||
|
indexAssembler,
|
||||||
|
identifierAssembler,
|
||||||
|
parentAccess.getFetchParentInstance()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* 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.sql.results.internal.domain.collection;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
||||||
|
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||||
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
|
import org.hibernate.sql.results.spi.AssemblerCreationState;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||||
|
import org.hibernate.sql.results.spi.Fetch;
|
||||||
|
import org.hibernate.sql.results.spi.FetchParent;
|
||||||
|
import org.hibernate.sql.results.spi.FetchParentAccess;
|
||||||
|
import org.hibernate.sql.results.spi.FetchableContainer;
|
||||||
|
import org.hibernate.sql.results.spi.Initializer;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class EagerCollectionFetch extends CollectionFetch implements FetchParent {
|
||||||
|
private final DomainResult fkResult;
|
||||||
|
|
||||||
|
private final Fetch elementFetch;
|
||||||
|
private final Fetch indexFetch;
|
||||||
|
private final DomainResult identifierResult;
|
||||||
|
|
||||||
|
private final List<Fetch> fetches;
|
||||||
|
|
||||||
|
public EagerCollectionFetch(
|
||||||
|
NavigablePath fetchedPath,
|
||||||
|
PluralAttributeMapping fetchedAttribute,
|
||||||
|
DomainResult fkResult,
|
||||||
|
boolean nullable,
|
||||||
|
FetchParent fetchParent,
|
||||||
|
DomainResultCreationState creationState) {
|
||||||
|
super( fetchedPath, fetchedAttribute, nullable, fetchParent );
|
||||||
|
this.fkResult = fkResult;
|
||||||
|
|
||||||
|
final CollectionIdentifierDescriptor identifierDescriptor = fetchedAttribute.getIdentifierDescriptor();
|
||||||
|
if ( identifierDescriptor == null ) {
|
||||||
|
this.identifierResult = null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final TableGroup collectionTableGroup = creationState.getSqlAstCreationState().getFromClauseAccess().getTableGroup( fetchedPath );
|
||||||
|
this.identifierResult = identifierDescriptor.createDomainResult( fetchedPath, collectionTableGroup, creationState );
|
||||||
|
}
|
||||||
|
|
||||||
|
fetches = creationState.visitFetches( this );
|
||||||
|
if ( fetchedAttribute.getIndexDescriptor() != null ) {
|
||||||
|
assert fetches.size() == 2;
|
||||||
|
indexFetch = fetches.get( 0 );
|
||||||
|
elementFetch = fetches.get( 1 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert fetches.size() == 1;
|
||||||
|
indexFetch = null;
|
||||||
|
elementFetch = fetches.get( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DomainResultAssembler createAssembler(
|
||||||
|
FetchParentAccess parentAccess,
|
||||||
|
Consumer<Initializer> collector,
|
||||||
|
AssemblerCreationState creationState) {
|
||||||
|
return new EagerCollectionAssembler(
|
||||||
|
getNavigablePath(),
|
||||||
|
getFetchedMapping(),
|
||||||
|
fkResult,
|
||||||
|
elementFetch,
|
||||||
|
indexFetch,
|
||||||
|
identifierResult,
|
||||||
|
parentAccess,
|
||||||
|
collector,
|
||||||
|
creationState
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FetchableContainer getReferencedMappingContainer() {
|
||||||
|
return getFetchedMapping();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PluralAttributeMapping getReferencedMappingType() {
|
||||||
|
return getFetchedMapping();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Fetch> getFetches() {
|
||||||
|
return fetches;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetch findFetch(String fetchableName) {
|
||||||
|
if ( CollectionPart.Nature.ELEMENT.getName().equals( fetchableName ) ) {
|
||||||
|
return elementFetch;
|
||||||
|
}
|
||||||
|
else if ( CollectionPart.Nature.INDEX.getName().equals( fetchableName ) ) {
|
||||||
|
return indexFetch;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unknown fetchable [" + getFetchedMapping().getCollectionDescriptor().getRole() +
|
||||||
|
" -> " + fetchableName + "]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JavaTypeDescriptor getResultJavaTypeDescriptor() {
|
||||||
|
return getFetchedMapping().getJavaTypeDescriptor();
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||||
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.sql.results.internal.domain.AbstractFetchParent;
|
import org.hibernate.sql.results.internal.domain.AbstractFetchParent;
|
||||||
import org.hibernate.sql.results.spi.AssemblerCreationState;
|
import org.hibernate.sql.results.spi.AssemblerCreationState;
|
||||||
|
@ -29,17 +29,20 @@ import org.hibernate.sql.results.spi.Initializer;
|
||||||
public class CompositeFetch extends AbstractFetchParent implements CompositeResultMappingNode, Fetch {
|
public class CompositeFetch extends AbstractFetchParent implements CompositeResultMappingNode, Fetch {
|
||||||
private final FetchParent fetchParent;
|
private final FetchParent fetchParent;
|
||||||
private final FetchTiming fetchTiming;
|
private final FetchTiming fetchTiming;
|
||||||
|
private final boolean nullable;
|
||||||
|
|
||||||
public CompositeFetch(
|
public CompositeFetch(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
EmbeddedAttributeMapping embeddedAttribute,
|
EmbeddableValuedModelPart embeddedPartDescriptor,
|
||||||
FetchParent fetchParent,
|
FetchParent fetchParent,
|
||||||
FetchTiming fetchTiming,
|
FetchTiming fetchTiming,
|
||||||
|
boolean nullable,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
super( embeddedAttribute, navigablePath );
|
super( embeddedPartDescriptor, navigablePath );
|
||||||
|
|
||||||
this.fetchParent = fetchParent;
|
this.fetchParent = fetchParent;
|
||||||
this.fetchTiming = fetchTiming;
|
this.fetchTiming = fetchTiming;
|
||||||
|
this.nullable = nullable;
|
||||||
|
|
||||||
creationState.getSqlAstCreationState().getFromClauseAccess().registerTableGroup(
|
creationState.getSqlAstCreationState().getFromClauseAccess().registerTableGroup(
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
@ -49,38 +52,34 @@ public class CompositeFetch extends AbstractFetchParent implements CompositeResu
|
||||||
afterInitialize( creationState );
|
afterInitialize( creationState );
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmbeddedAttributeMapping getEmbeddedAttributeMapping() {
|
|
||||||
return (EmbeddedAttributeMapping) super.getFetchContainer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FetchParent getFetchParent() {
|
public FetchParent getFetchParent() {
|
||||||
return fetchParent;
|
return fetchParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EmbeddedAttributeMapping getFetchContainer() {
|
public EmbeddableValuedModelPart getFetchContainer() {
|
||||||
return getEmbeddedAttributeMapping();
|
return (EmbeddableValuedModelPart) super.getFetchContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EmbeddedAttributeMapping getReferencedMappingContainer() {
|
public EmbeddableValuedModelPart getReferencedMappingContainer() {
|
||||||
return getEmbeddedAttributeMapping();
|
return getFetchContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Fetchable getFetchedMapping() {
|
public Fetchable getFetchedMapping() {
|
||||||
return getEmbeddedAttributeMapping();
|
return getFetchContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EmbeddableMappingType getReferencedMappingType() {
|
public EmbeddableMappingType getReferencedMappingType() {
|
||||||
return getEmbeddedAttributeMapping().getEmbeddableTypeDescriptor();
|
return getFetchContainer().getEmbeddableTypeDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNullable() {
|
public boolean isNullable() {
|
||||||
return getEmbeddedAttributeMapping().getAttributeMetadataAccess().resolveAttributeMetadata( null ).isNullable();
|
return nullable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -27,4 +27,9 @@ public class CompositeFetchInitializer
|
||||||
AssemblerCreationState creationState) {
|
AssemblerCreationState creationState) {
|
||||||
super( resultDescriptor, fetchParentAccess, initializerConsumer, creationState );
|
super( resultDescriptor, fetchParentAccess, initializerConsumer, creationState );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getParentKey() {
|
||||||
|
return getFetchParentAccess().getParentKey();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,4 +22,9 @@ public class CompositeRootInitializer extends AbstractCompositeInitializer {
|
||||||
AssemblerCreationState creationState) {
|
AssemblerCreationState creationState) {
|
||||||
super( resultDescriptor, null, initializerConsumer, creationState );
|
super( resultDescriptor, null, initializerConsumer, creationState );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getParentKey() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,6 @@ import org.hibernate.event.spi.PreLoadEvent;
|
||||||
import org.hibernate.event.spi.PreLoadEventListener;
|
import org.hibernate.event.spi.PreLoadEventListener;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.StateArrayContributorMapping;
|
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.entity.Loadable;
|
import org.hibernate.persister.entity.Loadable;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
|
@ -197,6 +196,11 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
return entityKey.getIdentifier();
|
return entityKey.getIdentifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getParentKey() {
|
||||||
|
return getKeyValue();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getFetchParentInstance() {
|
public Object getFetchParentInstance() {
|
||||||
if ( entityInstance == null ) {
|
if ( entityInstance == null ) {
|
||||||
|
|
|
@ -25,8 +25,6 @@ import org.hibernate.sql.results.spi.EntityResult;
|
||||||
public class EntityResultImpl extends AbstractEntityResultNode implements EntityResult {
|
public class EntityResultImpl extends AbstractEntityResultNode implements EntityResult {
|
||||||
private final String resultVariable;
|
private final String resultVariable;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public EntityResultImpl(
|
public EntityResultImpl(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
EntityValuedModelPart entityValuedModelPart,
|
EntityValuedModelPart entityValuedModelPart,
|
||||||
|
|
|
@ -8,7 +8,7 @@ package org.hibernate.sql.results.spi;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
import org.hibernate.metamodel.mapping.MappingType;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,7 +22,7 @@ public interface FetchParent extends ResultSetMappingNode {
|
||||||
/**
|
/**
|
||||||
* This parent's type
|
* This parent's type
|
||||||
*/
|
*/
|
||||||
ManagedMappingType getReferencedMappingType();
|
FetchableContainer getReferencedMappingType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the property path to this parent
|
* Get the property path to this parent
|
||||||
|
|
|
@ -19,6 +19,8 @@ import org.hibernate.query.NavigablePath;
|
||||||
public interface FetchParentAccess {
|
public interface FetchParentAccess {
|
||||||
FetchParentAccess findFirstEntityDescriptorAccess();
|
FetchParentAccess findFirstEntityDescriptorAccess();
|
||||||
|
|
||||||
|
Object getParentKey();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access to the fetch's parent instance.
|
* Access to the fetch's parent instance.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -15,6 +15,8 @@ import org.hibernate.metamodel.mapping.ModelPartContainer;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface FetchableContainer extends ModelPartContainer {
|
public interface FetchableContainer extends ModelPartContainer {
|
||||||
|
int getNumberOfFetchables();
|
||||||
|
|
||||||
default void visitKeyFetchables(
|
default void visitKeyFetchables(
|
||||||
Consumer<Fetchable> fetchableConsumer,
|
Consumer<Fetchable> fetchableConsumer,
|
||||||
EntityMappingType treatTargetType) {
|
EntityMappingType treatTargetType) {
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.sql.results.spi;
|
package org.hibernate.sql.results.spi;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
|
|
||||||
import org.hibernate.engine.spi.CollectionKey;
|
import org.hibernate.engine.spi.CollectionKey;
|
||||||
import org.hibernate.engine.spi.EntityKey;
|
import org.hibernate.engine.spi.EntityKey;
|
||||||
import org.hibernate.engine.spi.PersistenceContext;
|
import org.hibernate.engine.spi.PersistenceContext;
|
||||||
|
@ -18,7 +16,7 @@ import org.hibernate.internal.util.collections.StandardStack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maintains a Stack of processing state related to performing load operations.
|
* Maintains a Stack of processing state related to performing load operations.
|
||||||
* The sCollectionLoadContexttate is defined by {@link JdbcValuesSourceProcessingState} which
|
* The state is defined by {@link JdbcValuesSourceProcessingState} which
|
||||||
* encapsulates the data to be processed by the load whether the data comes from
|
* encapsulates the data to be processed by the load whether the data comes from
|
||||||
* a ResultSet or second-level cache hit.
|
* a ResultSet or second-level cache hit.
|
||||||
*
|
*
|
||||||
|
|
|
@ -9,9 +9,6 @@ package org.hibernate.sql.results.spi;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import org.hibernate.collection.spi.PersistentCollection;
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
import org.hibernate.engine.spi.CollectionEntry;
|
|
||||||
import org.hibernate.engine.spi.PersistenceContext;
|
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||||
|
|
||||||
|
@ -20,76 +17,14 @@ import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class LoadingCollectionEntry {
|
public interface LoadingCollectionEntry {
|
||||||
private final CollectionPersister collectionDescriptor;
|
CollectionPersister getCollectionDescriptor();
|
||||||
private final CollectionInitializer initializer;
|
|
||||||
// todo (6.0) : change from Serializable to Object
|
|
||||||
private final Serializable key;
|
|
||||||
private final PersistentCollection collectionInstance;
|
|
||||||
|
|
||||||
public LoadingCollectionEntry(
|
CollectionInitializer getInitializer();
|
||||||
CollectionPersister collectionDescriptor,
|
|
||||||
CollectionInitializer initializer,
|
|
||||||
Serializable key,
|
|
||||||
PersistentCollection collectionInstance) {
|
|
||||||
this.collectionDescriptor = collectionDescriptor;
|
|
||||||
this.initializer = initializer;
|
|
||||||
this.key = key;
|
|
||||||
this.collectionInstance = collectionInstance;
|
|
||||||
|
|
||||||
collectionInstance.beforeInitialize( getCollectionDescriptor(), -1 );
|
Serializable getKey();
|
||||||
collectionInstance.beginRead();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CollectionPersister getCollectionDescriptor() {
|
PersistentCollection getCollectionInstance();
|
||||||
return collectionDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
void finishLoading(ExecutionContext executionContext);
|
||||||
* Access to the initializer that is responsible for initializing this collection
|
|
||||||
*/
|
|
||||||
public CollectionInitializer getInitializer() {
|
|
||||||
return initializer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Serializable getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PersistentCollection getCollectionInstance() {
|
|
||||||
return collectionInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return getClass().getSimpleName() + "(" + getCollectionDescriptor().getNavigableRole().getFullPath() + "#" + getKey() + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void finishLoading(ExecutionContext executionContext) {
|
|
||||||
collectionInstance.endRead();
|
|
||||||
|
|
||||||
final SharedSessionContractImplementor session = executionContext.getSession();
|
|
||||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
|
||||||
final CollectionPersister collectionDescriptor = getCollectionDescriptor();
|
|
||||||
|
|
||||||
CollectionEntry collectionEntry = persistenceContext.getCollectionEntry( collectionInstance );
|
|
||||||
if ( collectionEntry == null ) {
|
|
||||||
collectionEntry = persistenceContext.addInitializedCollection(
|
|
||||||
collectionDescriptor,
|
|
||||||
getCollectionInstance(),
|
|
||||||
getKey()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
collectionEntry.postInitialize( collectionInstance );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( collectionDescriptor.getCollectionType().hasHolder() ) {
|
|
||||||
persistenceContext.addCollectionHolder( collectionInstance );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// todo (6.0) : there is other logic still needing to be implemented here. caching, etc
|
|
||||||
// see org.hibernate.engine.loading.internal.CollectionLoadContext#endLoadingCollection in 5.x
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.type.descriptor.java;
|
package org.hibernate.type.descriptor.java;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.spi.Primitive;
|
||||||
|
|
||||||
import static java.lang.Boolean.FALSE;
|
import static java.lang.Boolean.FALSE;
|
||||||
import static java.lang.Boolean.TRUE;
|
import static java.lang.Boolean.TRUE;
|
||||||
|
@ -16,7 +17,7 @@ import static java.lang.Boolean.TRUE;
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class BooleanTypeDescriptor extends AbstractTypeDescriptor<Boolean> {
|
public class BooleanTypeDescriptor extends AbstractTypeDescriptor<Boolean> implements Primitive<Boolean> {
|
||||||
public static final BooleanTypeDescriptor INSTANCE = new BooleanTypeDescriptor();
|
public static final BooleanTypeDescriptor INSTANCE = new BooleanTypeDescriptor();
|
||||||
|
|
||||||
private final char characterValueTrue;
|
private final char characterValueTrue;
|
||||||
|
@ -130,4 +131,14 @@ public class BooleanTypeDescriptor extends AbstractTypeDescriptor<Boolean> {
|
||||||
public Long toLong(Boolean value) {
|
public Long toLong(Boolean value) {
|
||||||
return (long) toInt( value );
|
return (long) toInt( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getPrimitiveClass() {
|
||||||
|
return boolean.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean getDefaultValue() {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type.descriptor.java;
|
package org.hibernate.type.descriptor.java;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.spi.Primitive;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Descriptor for {@link Byte} handling.
|
* Descriptor for {@link Byte} handling.
|
||||||
|
@ -13,7 +14,7 @@ import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
*/
|
*/
|
||||||
public class ByteTypeDescriptor extends AbstractTypeDescriptor<Byte> {
|
public class ByteTypeDescriptor extends AbstractTypeDescriptor<Byte> implements Primitive<Byte> {
|
||||||
public static final ByteTypeDescriptor INSTANCE = new ByteTypeDescriptor();
|
public static final ByteTypeDescriptor INSTANCE = new ByteTypeDescriptor();
|
||||||
|
|
||||||
public ByteTypeDescriptor() {
|
public ByteTypeDescriptor() {
|
||||||
|
@ -58,6 +59,7 @@ public class ByteTypeDescriptor extends AbstractTypeDescriptor<Byte> {
|
||||||
}
|
}
|
||||||
throw unknownUnwrap( type );
|
throw unknownUnwrap( type );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> Byte wrap(X value, WrapperOptions options) {
|
public <X> Byte wrap(X value, WrapperOptions options) {
|
||||||
if ( value == null ) {
|
if ( value == null ) {
|
||||||
|
@ -74,4 +76,14 @@ public class ByteTypeDescriptor extends AbstractTypeDescriptor<Byte> {
|
||||||
}
|
}
|
||||||
throw unknownWrap( value.getClass() );
|
throw unknownWrap( value.getClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getPrimitiveClass() {
|
||||||
|
return byte.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Byte getDefaultValue() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,14 @@
|
||||||
package org.hibernate.type.descriptor.java;
|
package org.hibernate.type.descriptor.java;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.spi.Primitive;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Descriptor for {@link Character} handling.
|
* Descriptor for {@link Character} handling.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class CharacterTypeDescriptor extends AbstractTypeDescriptor<Character> {
|
public class CharacterTypeDescriptor extends AbstractTypeDescriptor<Character> implements Primitive<Character> {
|
||||||
public static final CharacterTypeDescriptor INSTANCE = new CharacterTypeDescriptor();
|
public static final CharacterTypeDescriptor INSTANCE = new CharacterTypeDescriptor();
|
||||||
|
|
||||||
public CharacterTypeDescriptor() {
|
public CharacterTypeDescriptor() {
|
||||||
|
@ -66,4 +67,14 @@ public class CharacterTypeDescriptor extends AbstractTypeDescriptor<Character> {
|
||||||
}
|
}
|
||||||
throw unknownWrap( value.getClass() );
|
throw unknownWrap( value.getClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getPrimitiveClass() {
|
||||||
|
return char.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Character getDefaultValue() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,14 @@ import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.spi.Primitive;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Descriptor for {@link Double} handling.
|
* Descriptor for {@link Double} handling.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class DoubleTypeDescriptor extends AbstractTypeDescriptor<Double> {
|
public class DoubleTypeDescriptor extends AbstractTypeDescriptor<Double> implements Primitive<Double> {
|
||||||
public static final DoubleTypeDescriptor INSTANCE = new DoubleTypeDescriptor();
|
public static final DoubleTypeDescriptor INSTANCE = new DoubleTypeDescriptor();
|
||||||
|
|
||||||
public DoubleTypeDescriptor() {
|
public DoubleTypeDescriptor() {
|
||||||
|
@ -71,15 +72,25 @@ public class DoubleTypeDescriptor extends AbstractTypeDescriptor<Double> {
|
||||||
if ( value == null ) {
|
if ( value == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if ( Double.class.isInstance( value ) ) {
|
if ( value instanceof Double ) {
|
||||||
return (Double) value;
|
return (Double) value;
|
||||||
}
|
}
|
||||||
if ( Number.class.isInstance( value ) ) {
|
if ( value instanceof Number ) {
|
||||||
return ( (Number) value ).doubleValue();
|
return ( (Number) value ).doubleValue();
|
||||||
}
|
}
|
||||||
else if ( String.class.isInstance( value ) ) {
|
else if ( value instanceof String ) {
|
||||||
return Double.valueOf( ( (String) value ) );
|
return Double.valueOf( ( (String) value ) );
|
||||||
}
|
}
|
||||||
throw unknownWrap( value.getClass() );
|
throw unknownWrap( value.getClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getPrimitiveClass() {
|
||||||
|
return double.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double getDefaultValue() {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,14 @@ import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.spi.Primitive;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Descriptor for {@link Float} handling.
|
* Descriptor for {@link Float} handling.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class FloatTypeDescriptor extends AbstractTypeDescriptor<Float> {
|
public class FloatTypeDescriptor extends AbstractTypeDescriptor<Float> implements Primitive<Float> {
|
||||||
public static final FloatTypeDescriptor INSTANCE = new FloatTypeDescriptor();
|
public static final FloatTypeDescriptor INSTANCE = new FloatTypeDescriptor();
|
||||||
|
|
||||||
public FloatTypeDescriptor() {
|
public FloatTypeDescriptor() {
|
||||||
|
@ -82,4 +83,14 @@ public class FloatTypeDescriptor extends AbstractTypeDescriptor<Float> {
|
||||||
}
|
}
|
||||||
throw unknownWrap( value.getClass() );
|
throw unknownWrap( value.getClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getPrimitiveClass() {
|
||||||
|
return float.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Float getDefaultValue() {
|
||||||
|
return 0F;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,14 @@ import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.spi.Primitive;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Descriptor for {@link Integer} handling.
|
* Descriptor for {@link Integer} handling.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class IntegerTypeDescriptor extends AbstractTypeDescriptor<Integer> {
|
public class IntegerTypeDescriptor extends AbstractTypeDescriptor<Integer> implements Primitive<Integer> {
|
||||||
public static final IntegerTypeDescriptor INSTANCE = new IntegerTypeDescriptor();
|
public static final IntegerTypeDescriptor INSTANCE = new IntegerTypeDescriptor();
|
||||||
|
|
||||||
public IntegerTypeDescriptor() {
|
public IntegerTypeDescriptor() {
|
||||||
|
@ -82,4 +83,14 @@ public class IntegerTypeDescriptor extends AbstractTypeDescriptor<Integer> {
|
||||||
}
|
}
|
||||||
throw unknownWrap( value.getClass() );
|
throw unknownWrap( value.getClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getPrimitiveClass() {
|
||||||
|
return int.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getDefaultValue() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,14 @@ import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.spi.Primitive;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Descriptor for {@link Long} handling.
|
* Descriptor for {@link Long} handling.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class LongTypeDescriptor extends AbstractTypeDescriptor<Long> {
|
public class LongTypeDescriptor extends AbstractTypeDescriptor<Long>implements Primitive<Long> {
|
||||||
public static final LongTypeDescriptor INSTANCE = new LongTypeDescriptor();
|
public static final LongTypeDescriptor INSTANCE = new LongTypeDescriptor();
|
||||||
|
|
||||||
public LongTypeDescriptor() {
|
public LongTypeDescriptor() {
|
||||||
|
@ -82,4 +83,14 @@ public class LongTypeDescriptor extends AbstractTypeDescriptor<Long> {
|
||||||
}
|
}
|
||||||
throw unknownWrap( value.getClass() );
|
throw unknownWrap( value.getClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getPrimitiveClass() {
|
||||||
|
return long.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getDefaultValue() {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,14 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type.descriptor.java;
|
package org.hibernate.type.descriptor.java;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.spi.Primitive;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Descriptor for {@link Short} handling.
|
* Descriptor for {@link Short} handling.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class ShortTypeDescriptor extends AbstractTypeDescriptor<Short> {
|
public class ShortTypeDescriptor extends AbstractTypeDescriptor<Short> implements Primitive<Short> {
|
||||||
public static final ShortTypeDescriptor INSTANCE = new ShortTypeDescriptor();
|
public static final ShortTypeDescriptor INSTANCE = new ShortTypeDescriptor();
|
||||||
|
|
||||||
public ShortTypeDescriptor() {
|
public ShortTypeDescriptor() {
|
||||||
|
@ -72,4 +73,14 @@ public class ShortTypeDescriptor extends AbstractTypeDescriptor<Short> {
|
||||||
}
|
}
|
||||||
throw unknownWrap( value.getClass() );
|
throw unknownWrap( value.getClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getPrimitiveClass() {
|
||||||
|
return short.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Short getDefaultValue() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ public class JavaTypeDescriptorRegistry implements JavaTypeDescriptorBaseline.Ba
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public JavaTypeDescriptorRegistry(TypeConfiguration typeConfiguration) {
|
public JavaTypeDescriptorRegistry(TypeConfiguration typeConfiguration) {
|
||||||
this.typeConfiguration = typeConfiguration;
|
this.typeConfiguration = typeConfiguration;
|
||||||
|
JavaTypeDescriptorBaseline.prime( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.hibernate.HibernateException;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||||
import org.hibernate.cache.spi.access.EntityDataAccess;
|
import org.hibernate.cache.spi.access.EntityDataAccess;
|
||||||
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
|
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
|
||||||
|
@ -58,6 +59,11 @@ import org.hibernate.persister.spi.PersisterClassResolver;
|
||||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
|
import org.hibernate.sql.ast.JoinType;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableReferenceCollector;
|
||||||
import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl;
|
import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl;
|
||||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||||
|
@ -717,6 +723,16 @@ public class PersisterClassProviderTest {
|
||||||
public JavaTypeDescriptor getMappedJavaTypeDescriptor() {
|
public JavaTypeDescriptor getMappedJavaTypeDescriptor() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyTableReferences(
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
JoinType baseJoinType,
|
||||||
|
TableReferenceCollector collector,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
throw new NotYetImplementedFor6Exception( getClass() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GoofyException extends RuntimeException {
|
public static class GoofyException extends RuntimeException {
|
||||||
|
|
|
@ -6,13 +6,16 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.metamodel.mapping;
|
package org.hibernate.orm.test.metamodel.mapping;
|
||||||
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import javax.persistence.AttributeConverter;
|
import javax.persistence.AttributeConverter;
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Convert;
|
||||||
import javax.persistence.ElementCollection;
|
import javax.persistence.ElementCollection;
|
||||||
import javax.persistence.Embeddable;
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Embedded;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
import javax.persistence.Enumerated;
|
import javax.persistence.Enumerated;
|
||||||
|
@ -21,14 +24,20 @@ import javax.persistence.OneToMany;
|
||||||
import javax.persistence.OrderColumn;
|
import javax.persistence.OrderColumn;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
|
import org.hibernate.metamodel.spi.DomainMetamodel;
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@ -36,6 +45,7 @@ import org.junit.jupiter.api.Test;
|
||||||
annotatedClasses = {
|
annotatedClasses = {
|
||||||
PluralAttributeTests.SimpleEntity.class,
|
PluralAttributeTests.SimpleEntity.class,
|
||||||
PluralAttributeTests.EntityContainingLists.class,
|
PluralAttributeTests.EntityContainingLists.class,
|
||||||
|
PluralAttributeTests.EntityContainingSets.class,
|
||||||
PluralAttributeTests.Component.class
|
PluralAttributeTests.Component.class
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -46,51 +56,50 @@ public class PluralAttributeTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLists(SessionFactoryScope scope) {
|
public void testLists(SessionFactoryScope scope) {
|
||||||
System.out.println( "test" );
|
final DomainMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityMappingType containerEntityDescriptor = domainModel.getEntityDescriptor( EntityContainingLists.class );
|
||||||
|
|
||||||
|
assertThat( containerEntityDescriptor.getNumberOfAttributeMappings(), is( 6 ) );
|
||||||
|
|
||||||
|
final AttributeMapping listOfBasics = containerEntityDescriptor.findAttributeMapping( "listOfBasics" );
|
||||||
|
assertThat( listOfBasics, notNullValue() );
|
||||||
|
|
||||||
|
final AttributeMapping listOfConvertedBasics = containerEntityDescriptor.findAttributeMapping( "listOfConvertedBasics" );
|
||||||
|
assertThat( listOfConvertedBasics, notNullValue() );
|
||||||
|
|
||||||
|
|
||||||
|
final AttributeMapping listOfEnums = containerEntityDescriptor.findAttributeMapping( "listOfEnums" );
|
||||||
|
assertThat( listOfEnums, notNullValue() );
|
||||||
|
|
||||||
|
final AttributeMapping listOfComponents = containerEntityDescriptor.findAttributeMapping( "listOfComponents" );
|
||||||
|
assertThat( listOfComponents, notNullValue() );
|
||||||
|
|
||||||
|
final AttributeMapping listOfEntities = containerEntityDescriptor.findAttributeMapping( "listOfEntities" );
|
||||||
|
assertThat( listOfEntities, notNullValue() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeAll
|
@Test
|
||||||
public void createTestData(SessionFactoryScope scope) {
|
public void testSets(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
final DomainMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
session -> {
|
final EntityMappingType containerEntityDescriptor = domainModel.getEntityDescriptor( EntityContainingSets.class );
|
||||||
final EntityContainingLists entityContainingLists = new EntityContainingLists( 1, "first" );
|
|
||||||
|
|
||||||
entityContainingLists.addBasic( "abc" );
|
assertThat( containerEntityDescriptor.getNumberOfAttributeMappings(), is( 6 ) );
|
||||||
entityContainingLists.addBasic( "def" );
|
|
||||||
entityContainingLists.addBasic( "ghi" );
|
|
||||||
|
|
||||||
entityContainingLists.addConvertedBasic( EnumValue.TWO );
|
final AttributeMapping setOfBasics = containerEntityDescriptor.findAttributeMapping( "setOfBasics" );
|
||||||
|
assertThat( setOfBasics, notNullValue() );
|
||||||
|
|
||||||
entityContainingLists.addEnum( EnumValue.ONE );
|
final AttributeMapping setOfConvertedBasics = containerEntityDescriptor.findAttributeMapping( "setOfConvertedBasics" );
|
||||||
entityContainingLists.addEnum( EnumValue.THREE );
|
assertThat( setOfConvertedBasics, notNullValue() );
|
||||||
|
|
||||||
entityContainingLists.addComponent( new Component( "first-a1", "first-another-a1" ) );
|
|
||||||
entityContainingLists.addComponent( new Component( "first-a2", "first-another-a2" ) );
|
|
||||||
|
|
||||||
entityContainingLists.addSimpleEntity( new SimpleEntity( 1, "simple-1" ) );
|
final AttributeMapping setOfEnums = containerEntityDescriptor.findAttributeMapping( "setOfEnums" );
|
||||||
entityContainingLists.addSimpleEntity( new SimpleEntity( 2, "simple-2" ) );
|
assertThat( setOfEnums, notNullValue() );
|
||||||
|
|
||||||
session.save( entityContainingLists );
|
final AttributeMapping setOfComponents = containerEntityDescriptor.findAttributeMapping( "setOfComponents" );
|
||||||
}
|
assertThat( setOfComponents, notNullValue() );
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterAll
|
final AttributeMapping setOfEntities = containerEntityDescriptor.findAttributeMapping( "setOfEntities" );
|
||||||
public void deleteTestData(SessionFactoryScope scope) {
|
assertThat( setOfEntities, notNullValue() );
|
||||||
scope.inTransaction(
|
|
||||||
session -> session.doWork(
|
|
||||||
conn -> {
|
|
||||||
try ( Statement stmnt = conn.createStatement() ) {
|
|
||||||
stmnt.execute( "delete from EntityContainingLists_listOfEnums" );
|
|
||||||
stmnt.execute( "delete from EntityContainingLists_listOfConvertedBasics" );
|
|
||||||
stmnt.execute( "delete from EntityContainingLists_listOfComponents" );
|
|
||||||
stmnt.execute( "delete from EntityContainingLists_listOfBasics" );
|
|
||||||
stmnt.execute( "delete from entity_containing_lists_simple_entity" );
|
|
||||||
stmnt.execute( "delete from entity_containing_lists" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum EnumValue {
|
public enum EnumValue {
|
||||||
|
@ -198,6 +207,7 @@ public class PluralAttributeTests {
|
||||||
|
|
||||||
@ElementCollection
|
@ElementCollection
|
||||||
@OrderColumn
|
@OrderColumn
|
||||||
|
@Convert( converter = Converter.class )
|
||||||
public List<EnumValue> getListOfConvertedBasics() {
|
public List<EnumValue> getListOfConvertedBasics() {
|
||||||
return listOfConvertedBasics;
|
return listOfConvertedBasics;
|
||||||
}
|
}
|
||||||
|
@ -266,6 +276,127 @@ public class PluralAttributeTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityContainingSets" )
|
||||||
|
@Table( name = "entity_containing_sets" )
|
||||||
|
public static class EntityContainingSets {
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private Set<String> setOfBasics;
|
||||||
|
private Set<EnumValue> setOfConvertedBasics;
|
||||||
|
private Set<EnumValue> setOfEnums;
|
||||||
|
private Set<Component> setOfComponents;
|
||||||
|
private Set<SimpleEntity> setOfEntities;
|
||||||
|
|
||||||
|
public EntityContainingSets() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityContainingSets(Integer id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Id
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
public Set<String> getSetOfBasics() {
|
||||||
|
return setOfBasics;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSetOfBasics(Set<String> setOfBasics) {
|
||||||
|
this.setOfBasics = setOfBasics;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBasic(String value) {
|
||||||
|
if ( setOfBasics == null ) {
|
||||||
|
setOfBasics = new HashSet<>();
|
||||||
|
}
|
||||||
|
setOfBasics.add( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
@Convert( converter = Converter.class )
|
||||||
|
public Set<EnumValue> getSetOfConvertedBasics() {
|
||||||
|
return setOfConvertedBasics;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSetOfConvertedBasics(Set<EnumValue> setOfConvertedBasics) {
|
||||||
|
this.setOfConvertedBasics = setOfConvertedBasics;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addConvertedBasic(EnumValue value) {
|
||||||
|
if ( setOfConvertedBasics == null ) {
|
||||||
|
setOfConvertedBasics = new HashSet<>();
|
||||||
|
}
|
||||||
|
setOfConvertedBasics.add( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
@Enumerated( EnumType.STRING )
|
||||||
|
public Set<EnumValue> getSetOfEnums() {
|
||||||
|
return setOfEnums;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSetOfEnums(Set<EnumValue> setOfEnums) {
|
||||||
|
this.setOfEnums = setOfEnums;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEnum(EnumValue value) {
|
||||||
|
if ( setOfEnums == null ) {
|
||||||
|
setOfEnums = new HashSet<>();
|
||||||
|
}
|
||||||
|
setOfEnums.add( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
@Embedded
|
||||||
|
public Set<Component> getSetOfComponents() {
|
||||||
|
return setOfComponents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSetOfComponents(Set<Component> setOfComponents) {
|
||||||
|
this.setOfComponents = setOfComponents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addComponent(Component value) {
|
||||||
|
if ( setOfComponents == null ) {
|
||||||
|
setOfComponents = new HashSet<>();
|
||||||
|
}
|
||||||
|
setOfComponents.add( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
@OneToMany( cascade = CascadeType.ALL )
|
||||||
|
public Set<SimpleEntity> getSetOfEntities() {
|
||||||
|
return setOfEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSetOfEntities(Set<SimpleEntity> setOfEntities) {
|
||||||
|
this.setOfEntities = setOfEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSimpleEntity(SimpleEntity value) {
|
||||||
|
if ( setOfEntities == null ) {
|
||||||
|
setOfEntities = new HashSet<>();
|
||||||
|
}
|
||||||
|
setOfEntities.add( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Entity( name = "SimpleEntity" )
|
@Entity( name = "SimpleEntity" )
|
||||||
@Table( name = "simple_entity" )
|
@Table( name = "simple_entity" )
|
||||||
public static class SimpleEntity {
|
public static class SimpleEntity {
|
||||||
|
|
|
@ -24,7 +24,10 @@ import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.internal.SingularAssociationAttributeMapping;
|
import org.hibernate.metamodel.mapping.internal.SingularAssociationAttributeMapping;
|
||||||
import org.hibernate.metamodel.model.convert.internal.NamedEnumValueConverter;
|
import org.hibernate.metamodel.model.convert.internal.NamedEnumValueConverter;
|
||||||
import org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter;
|
import org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter;
|
||||||
|
import org.hibernate.metamodel.model.convert.spi.EnumValueConverter;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.type.CustomType;
|
||||||
|
import org.hibernate.usertype.UserType;
|
||||||
|
|
||||||
import org.hibernate.testing.hamcrest.CollectionMatchers;
|
import org.hibernate.testing.hamcrest.CollectionMatchers;
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
@ -72,8 +75,12 @@ public class SmokeTests {
|
||||||
final BasicValuedSingularAttributeMapping genderAttrMapping = (BasicValuedSingularAttributeMapping) genderPart;
|
final BasicValuedSingularAttributeMapping genderAttrMapping = (BasicValuedSingularAttributeMapping) genderPart;
|
||||||
assert "mapping_simple_entity".equals( genderAttrMapping.getContainingTableExpression() );
|
assert "mapping_simple_entity".equals( genderAttrMapping.getContainingTableExpression() );
|
||||||
assert "gender".equals( genderAttrMapping.getMappedColumnExpression() );
|
assert "gender".equals( genderAttrMapping.getMappedColumnExpression() );
|
||||||
assert genderAttrMapping.getConverter() != null;
|
assert genderAttrMapping.getMappedTypeDescriptor() instanceof CustomType;
|
||||||
assert genderAttrMapping.getConverter() instanceof OrdinalEnumValueConverter;
|
final UserType userType = ( (CustomType) genderAttrMapping.getMappedTypeDescriptor() ).getUserType();
|
||||||
|
assert userType instanceof org.hibernate.type.EnumType;
|
||||||
|
final EnumValueConverter converter = ( (org.hibernate.type.EnumType) userType ).getEnumValueConverter();
|
||||||
|
assert converter != null;
|
||||||
|
assert converter instanceof OrdinalEnumValueConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -82,8 +89,13 @@ public class SmokeTests {
|
||||||
final BasicValuedSingularAttributeMapping attrMapping = (BasicValuedSingularAttributeMapping) part;
|
final BasicValuedSingularAttributeMapping attrMapping = (BasicValuedSingularAttributeMapping) part;
|
||||||
assert "mapping_simple_entity".equals( attrMapping.getContainingTableExpression() );
|
assert "mapping_simple_entity".equals( attrMapping.getContainingTableExpression() );
|
||||||
assert "gender2".equals( attrMapping.getMappedColumnExpression() );
|
assert "gender2".equals( attrMapping.getMappedColumnExpression() );
|
||||||
assert attrMapping.getConverter() != null;
|
|
||||||
assert attrMapping.getConverter() instanceof NamedEnumValueConverter;
|
assert attrMapping.getMappedTypeDescriptor() instanceof CustomType;
|
||||||
|
final UserType userType = ( (CustomType) attrMapping.getMappedTypeDescriptor() ).getUserType();
|
||||||
|
assert userType instanceof org.hibernate.type.EnumType;
|
||||||
|
final EnumValueConverter converter = ( (org.hibernate.type.EnumType) userType ).getEnumValueConverter();
|
||||||
|
assert converter != null;
|
||||||
|
assert converter instanceof NamedEnumValueConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,7 +35,10 @@ import org.hibernate.sql.results.internal.domain.basic.BasicResult;
|
||||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||||
import org.hibernate.sql.results.spi.DomainResult;
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.type.CustomType;
|
||||||
|
import org.hibernate.type.EnumType;
|
||||||
import org.hibernate.type.internal.StandardBasicTypeImpl;
|
import org.hibernate.type.internal.StandardBasicTypeImpl;
|
||||||
|
import org.hibernate.usertype.UserType;
|
||||||
|
|
||||||
import org.hibernate.testing.hamcrest.AssignableMatcher;
|
import org.hibernate.testing.hamcrest.AssignableMatcher;
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
@ -49,6 +52,7 @@ import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
|
import static org.hamcrest.CoreMatchers.nullValue;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -174,10 +178,15 @@ public class SmokeTests {
|
||||||
assertThat( columnReference.renderSqlFragment( scope.getSessionFactory() ), is( "s1_0.gender" ) );
|
assertThat( columnReference.renderSqlFragment( scope.getSessionFactory() ), is( "s1_0.gender" ) );
|
||||||
|
|
||||||
final MappingModelExpressable selectedExpressable = selectedExpression.getExpressionType();
|
final MappingModelExpressable selectedExpressable = selectedExpression.getExpressionType();
|
||||||
assertThat( selectedExpressable, instanceOf( StandardBasicTypeImpl.class ) );
|
//assertThat( selectedExpressable, instanceOf( StandardBasicTypeImpl.class ) );
|
||||||
final StandardBasicTypeImpl basicType = (StandardBasicTypeImpl) selectedExpressable;
|
// assertThat( basicType.getJavaTypeDescriptor().getJavaType(), AssignableMatcher.assignableTo( Integer.class ) );
|
||||||
assertThat( basicType.getJavaTypeDescriptor().getJavaType(), AssignableMatcher.assignableTo( Integer.class ) );
|
// assertThat( basicType.getSqlTypeDescriptor().getSqlType(), is( Types.INTEGER ) );
|
||||||
assertThat( basicType.getSqlTypeDescriptor().getSqlType(), is( Types.INTEGER ) );
|
assertThat( selectedExpressable, instanceOf( CustomType.class ) );
|
||||||
|
final CustomType basicType = (CustomType) selectedExpressable;
|
||||||
|
final EnumType enumType = (EnumType) basicType.getUserType();
|
||||||
|
assertThat( enumType.getEnumValueConverter().getRelationalJavaDescriptor().getJavaType(), AssignableMatcher.assignableTo( Integer.class ) );
|
||||||
|
assertThat( enumType.sqlTypes()[0], is( Types.INTEGER ) );
|
||||||
|
|
||||||
|
|
||||||
assertThat( sqlAst.getDomainResultDescriptors().size(), is( 1 ) );
|
assertThat( sqlAst.getDomainResultDescriptors().size(), is( 1 ) );
|
||||||
final DomainResult domainResult = sqlAst.getDomainResultDescriptors().get( 0 );
|
final DomainResult domainResult = sqlAst.getDomainResultDescriptors().get( 0 );
|
||||||
|
@ -185,8 +194,10 @@ public class SmokeTests {
|
||||||
final BasicResult scalarDomainResult = (BasicResult) domainResult;
|
final BasicResult scalarDomainResult = (BasicResult) domainResult;
|
||||||
assertThat( scalarDomainResult.getAssembler(), instanceOf( BasicResultAssembler.class ) );
|
assertThat( scalarDomainResult.getAssembler(), instanceOf( BasicResultAssembler.class ) );
|
||||||
final BasicResultAssembler<?> assembler = (BasicResultAssembler) scalarDomainResult.getAssembler();
|
final BasicResultAssembler<?> assembler = (BasicResultAssembler) scalarDomainResult.getAssembler();
|
||||||
assertThat( assembler.getValueConverter(), notNullValue() );
|
// assertThat( assembler.getValueConverter(), notNullValue() );
|
||||||
assertThat( assembler.getValueConverter(), instanceOf( OrdinalEnumValueConverter.class ) );
|
// assertThat( assembler.getValueConverter(), instanceOf( OrdinalEnumValueConverter.class ) );
|
||||||
|
assertThat( assembler.getValueConverter(), nullValue() );
|
||||||
|
|
||||||
final NavigablePath expectedSelectedPath = new NavigablePath(
|
final NavigablePath expectedSelectedPath = new NavigablePath(
|
||||||
org.hibernate.orm.test.metamodel.mapping.SmokeTests.SimpleEntity.class.getName(),
|
org.hibernate.orm.test.metamodel.mapping.SmokeTests.SimpleEntity.class.getName(),
|
||||||
"e"
|
"e"
|
||||||
|
@ -202,9 +213,10 @@ public class SmokeTests {
|
||||||
);
|
);
|
||||||
|
|
||||||
assertThat( resultAssembler, instanceOf( BasicResultAssembler.class ) );
|
assertThat( resultAssembler, instanceOf( BasicResultAssembler.class ) );
|
||||||
final BasicValueConverter valueConverter = ( (BasicResultAssembler) resultAssembler ).getValueConverter();
|
// final BasicValueConverter valueConverter = ( (BasicResultAssembler) resultAssembler ).getValueConverter();
|
||||||
assertThat( valueConverter, notNullValue() );
|
// assertThat( valueConverter, notNullValue() );
|
||||||
assertThat( valueConverter, instanceOf( OrdinalEnumValueConverter.class ) );
|
// assertThat( valueConverter, instanceOf( OrdinalEnumValueConverter.class ) );
|
||||||
|
assertThat( ( (BasicResultAssembler) resultAssembler ).getValueConverter(), nullValue() );
|
||||||
|
|
||||||
final JdbcSelect jdbcSelectOperation = new StandardSqlAstSelectTranslator( session.getSessionFactory() )
|
final JdbcSelect jdbcSelectOperation = new StandardSqlAstSelectTranslator( session.getSessionFactory() )
|
||||||
.interpret( sqlAst );
|
.interpret( sqlAst );
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
/*
|
||||||
|
* 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.orm.test.sql.exec;
|
||||||
|
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
|
import org.hibernate.orm.test.metamodel.mapping.PluralAttributeTests.Component;
|
||||||
|
import org.hibernate.orm.test.metamodel.mapping.PluralAttributeTests.EntityContainingLists;
|
||||||
|
import org.hibernate.orm.test.metamodel.mapping.PluralAttributeTests.EntityContainingSets;
|
||||||
|
import org.hibernate.orm.test.metamodel.mapping.PluralAttributeTests.EnumValue;
|
||||||
|
import org.hibernate.orm.test.metamodel.mapping.PluralAttributeTests.SimpleEntity;
|
||||||
|
import org.hibernate.query.spi.QueryImplementor;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.hamcrest.CoreMatchers;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel(
|
||||||
|
annotatedClasses = {
|
||||||
|
SimpleEntity.class,
|
||||||
|
EntityContainingLists.class,
|
||||||
|
EntityContainingSets.class,
|
||||||
|
Component.class
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ServiceRegistry
|
||||||
|
@SessionFactory
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public class PluralAttributeSmokeTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listBaselineTest(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
final QueryImplementor<EntityContainingLists> query = session.createQuery(
|
||||||
|
"select e from EntityContainingLists e",
|
||||||
|
EntityContainingLists.class
|
||||||
|
);
|
||||||
|
final EntityContainingLists result = query.uniqueResult();
|
||||||
|
|
||||||
|
assertThat( result, notNullValue() );
|
||||||
|
assertThat( result.getListOfBasics(), notNullValue() );
|
||||||
|
assertThat( Hibernate.isInitialized( result.getListOfBasics() ), is( false ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listEagerBasicTest(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
final QueryImplementor<EntityContainingLists> query = session.createQuery(
|
||||||
|
"select e from EntityContainingLists e join fetch e.listOfBasics",
|
||||||
|
EntityContainingLists.class
|
||||||
|
);
|
||||||
|
final EntityContainingLists result = query.uniqueResult();
|
||||||
|
|
||||||
|
assertThat( result, notNullValue() );
|
||||||
|
|
||||||
|
assertThat( result.getListOfBasics(), notNullValue() );
|
||||||
|
assertThat( Hibernate.isInitialized( result.getListOfBasics() ), is( true ) );
|
||||||
|
assertTrue( session.getPersistenceContext().containsCollection( (PersistentCollection) result.getListOfBasics() ) );
|
||||||
|
assertThat( result.getListOfBasics().size(), is( 3 ) );
|
||||||
|
|
||||||
|
assertThat( result.getListOfConvertedBasics(), notNullValue() );
|
||||||
|
assertThat( Hibernate.isInitialized( result.getListOfConvertedBasics() ), is( false ) );
|
||||||
|
assertTrue( session.getPersistenceContext().containsCollection( (PersistentCollection) result.getListOfConvertedBasics() ) );
|
||||||
|
|
||||||
|
assertThat( result.getListOfEnums(), notNullValue() );
|
||||||
|
assertThat( Hibernate.isInitialized( result.getListOfEnums() ), is( false ) );
|
||||||
|
assertTrue( session.getPersistenceContext().containsCollection( (PersistentCollection) result.getListOfEnums() ) );
|
||||||
|
|
||||||
|
assertThat( result.getListOfComponents(), notNullValue() );
|
||||||
|
assertThat( Hibernate.isInitialized( result.getListOfComponents() ), is( false ) );
|
||||||
|
assertTrue( session.getPersistenceContext().containsCollection( (PersistentCollection) result.getListOfComponents() ) );
|
||||||
|
|
||||||
|
assertThat( result.getListOfEntities(), notNullValue() );
|
||||||
|
assertThat( Hibernate.isInitialized( result.getListOfEntities() ), is( false ) );
|
||||||
|
assertTrue( session.getPersistenceContext().containsCollection( (PersistentCollection) result.getListOfEntities() ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setBaselineTest(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
final QueryImplementor<EntityContainingSets> query = session.createQuery(
|
||||||
|
"select e from EntityContainingSets e",
|
||||||
|
EntityContainingSets.class
|
||||||
|
);
|
||||||
|
|
||||||
|
final EntityContainingSets result = query.uniqueResult();
|
||||||
|
|
||||||
|
assertThat( result, notNullValue() );
|
||||||
|
assertThat( result.getSetOfBasics(), notNullValue() );
|
||||||
|
assertThat( Hibernate.isInitialized( result.getSetOfBasics() ), is( false ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public void createTestData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
final SimpleEntity simpleEntity1 = new SimpleEntity( 1, "simple-1" );
|
||||||
|
final SimpleEntity simpleEntity2 = new SimpleEntity( 2, "simple-2" );
|
||||||
|
|
||||||
|
session.save( simpleEntity1 );
|
||||||
|
session.save( simpleEntity2 );
|
||||||
|
|
||||||
|
{
|
||||||
|
final EntityContainingLists entityContainingLists = new EntityContainingLists( 1, "first" );
|
||||||
|
|
||||||
|
entityContainingLists.addBasic( "abc" );
|
||||||
|
entityContainingLists.addBasic( "def" );
|
||||||
|
entityContainingLists.addBasic( "ghi" );
|
||||||
|
|
||||||
|
entityContainingLists.addConvertedBasic( EnumValue.TWO );
|
||||||
|
|
||||||
|
entityContainingLists.addEnum( EnumValue.ONE );
|
||||||
|
entityContainingLists.addEnum( EnumValue.THREE );
|
||||||
|
|
||||||
|
entityContainingLists.addComponent( new Component( "first-a1", "first-another-a1" ) );
|
||||||
|
entityContainingLists.addComponent( new Component( "first-a2", "first-another-a2" ) );
|
||||||
|
|
||||||
|
entityContainingLists.addSimpleEntity( simpleEntity1 );
|
||||||
|
entityContainingLists.addSimpleEntity( simpleEntity2 );
|
||||||
|
|
||||||
|
session.save( entityContainingLists );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final EntityContainingSets entity = new EntityContainingSets( 1, "first" );
|
||||||
|
|
||||||
|
entity.addBasic( "abc" );
|
||||||
|
entity.addBasic( "def" );
|
||||||
|
entity.addBasic( "ghi" );
|
||||||
|
|
||||||
|
entity.addConvertedBasic( EnumValue.TWO );
|
||||||
|
|
||||||
|
entity.addEnum( EnumValue.ONE );
|
||||||
|
entity.addEnum( EnumValue.THREE );
|
||||||
|
|
||||||
|
entity.addComponent( new Component( "first-a1", "first-another-a1" ) );
|
||||||
|
entity.addComponent( new Component( "first-a2", "first-another-a2" ) );
|
||||||
|
|
||||||
|
entity.addSimpleEntity( simpleEntity1 );
|
||||||
|
entity.addSimpleEntity( simpleEntity2 );
|
||||||
|
|
||||||
|
session.save( entity );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
public void deleteTestData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> session.doWork(
|
||||||
|
conn -> {
|
||||||
|
try ( Statement stmnt = conn.createStatement() ) {
|
||||||
|
stmnt.execute( "delete from EntityContainingLists_listOfEnums" );
|
||||||
|
stmnt.execute( "delete from EntityContainingLists_listOfConvertedBasics" );
|
||||||
|
stmnt.execute( "delete from EntityContainingLists_listOfComponents" );
|
||||||
|
stmnt.execute( "delete from EntityContainingLists_listOfBasics" );
|
||||||
|
stmnt.execute( "delete from entity_containing_lists_simple_entity" );
|
||||||
|
stmnt.execute( "delete from entity_containing_lists" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,6 @@ import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.HibernateException;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||||
import org.hibernate.cache.spi.access.CollectionDataAccess;
|
import org.hibernate.cache.spi.access.CollectionDataAccess;
|
||||||
import org.hibernate.cache.spi.access.EntityDataAccess;
|
import org.hibernate.cache.spi.access.EntityDataAccess;
|
||||||
|
@ -58,6 +59,11 @@ import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
|
import org.hibernate.sql.ast.JoinType;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableReferenceCollector;
|
||||||
import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl;
|
import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl;
|
||||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||||
|
@ -703,6 +709,16 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
|
||||||
public JavaTypeDescriptor getMappedJavaTypeDescriptor() {
|
public JavaTypeDescriptor getMappedJavaTypeDescriptor() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyTableReferences(
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
JoinType baseJoinType,
|
||||||
|
TableReferenceCollector collector,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
throw new NotYetImplementedFor6Exception( getClass() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class NoopCollectionPersister implements CollectionPersister {
|
public static class NoopCollectionPersister implements CollectionPersister {
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.hibernate.HibernateException;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||||
import org.hibernate.cache.spi.access.EntityDataAccess;
|
import org.hibernate.cache.spi.access.EntityDataAccess;
|
||||||
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
|
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
|
||||||
|
@ -59,6 +60,11 @@ import org.hibernate.persister.entity.MultiLoadOptions;
|
||||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
|
import org.hibernate.sql.ast.JoinType;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableReferenceCollector;
|
||||||
import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl;
|
import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl;
|
||||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||||
|
@ -815,4 +821,14 @@ public class CustomPersister implements EntityPersister {
|
||||||
public JavaTypeDescriptor getMappedJavaTypeDescriptor() {
|
public JavaTypeDescriptor getMappedJavaTypeDescriptor() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyTableReferences(
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
JoinType baseJoinType,
|
||||||
|
TableReferenceCollector collector,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
throw new NotYetImplementedFor6Exception( getClass() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue