mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-17 00:24:57 +00:00
HHH-7888 - Bind @OrderBy with empty value
This commit is contained in:
parent
288823d2dd
commit
2d43576045
@ -1065,7 +1065,7 @@ protected void bindManyToManySecondPass(
|
|||||||
TableBinder associationTableBinder,
|
TableBinder associationTableBinder,
|
||||||
XProperty property,
|
XProperty property,
|
||||||
PropertyHolder parentPropertyHolder,
|
PropertyHolder parentPropertyHolder,
|
||||||
String hqlOrderBy,
|
final String hqlOrderBy,
|
||||||
Mappings mappings) throws MappingException {
|
Mappings mappings) throws MappingException {
|
||||||
|
|
||||||
PersistentClass collectionEntity = (PersistentClass) persistentClasses.get( collType.getName() );
|
PersistentClass collectionEntity = (PersistentClass) persistentClasses.get( collType.getName() );
|
||||||
@ -1286,7 +1286,6 @@ else if ( owner.getIdentifierMapper() != null && owner.getIdentifierMapper().get
|
|||||||
collValue.setElement( component );
|
collValue.setElement( component );
|
||||||
|
|
||||||
if ( StringHelper.isNotEmpty( hqlOrderBy ) ) {
|
if ( StringHelper.isNotEmpty( hqlOrderBy ) ) {
|
||||||
String path = collValue.getOwnerEntityName() + "." + joinColumns[0].getPropertyName();
|
|
||||||
String orderBy = adjustUserSuppliedValueCollectionOrderingFragment( hqlOrderBy );
|
String orderBy = adjustUserSuppliedValueCollectionOrderingFragment( hqlOrderBy );
|
||||||
if ( orderBy != null ) {
|
if ( orderBy != null ) {
|
||||||
collValue.setOrderBy( orderBy );
|
collValue.setOrderBy( orderBy );
|
||||||
|
@ -156,4 +156,20 @@ public static boolean isNotEmpty(Object[] objs){
|
|||||||
public static <T> List<T> createEmptyList(Class<T> elementClass) {
|
public static <T> List<T> createEmptyList(Class<T> elementClass) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isCollectionOrArray(Class clazz) {
|
||||||
|
if ( clazz == null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( Collection.class.isAssignableFrom( clazz ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( Map.class.isAssignableFrom( clazz ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// if ( clazz.isArray() ) {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1980,23 +1980,7 @@ private void bindSortingAndOrdering(
|
|||||||
if ( Orderable.class.isInstance( attributeSource ) ) {
|
if ( Orderable.class.isInstance( attributeSource ) ) {
|
||||||
final Orderable orderable = (Orderable) attributeSource;
|
final Orderable orderable = (Orderable) attributeSource;
|
||||||
if ( orderable.isOrdered() ) {
|
if ( orderable.isOrdered() ) {
|
||||||
String orderBy = orderable.getOrder();
|
attributeBinding.setOrderBy( orderable.getOrder() );
|
||||||
if ( orderBy.equals( "" ) ) {
|
|
||||||
PrimaryKey pk = attributeBinding.getPluralAttributeKeyBinding()
|
|
||||||
.getReferencedAttributeBinding()
|
|
||||||
.getContainer()
|
|
||||||
.seekEntityBinding()
|
|
||||||
.getPrimaryTable()
|
|
||||||
.getPrimaryKey();
|
|
||||||
List<Column> pkColumns = pk.getColumns();
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
for ( final Column column : pkColumns ) {
|
|
||||||
sb.append( column.getColumnName().getText() );
|
|
||||||
sb.append( " asc ," );
|
|
||||||
}
|
|
||||||
orderBy = sb.substring( 0, sb.length() - 2 );
|
|
||||||
}
|
|
||||||
attributeBinding.setOrderBy( orderBy );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2250,47 +2234,52 @@ private void bindCollectionTableForeignKey(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO : It is really confusing that we have so many different <tt>natures</tt>
|
||||||
|
*/
|
||||||
private void bindCollectionTablePrimaryKey(
|
private void bindCollectionTablePrimaryKey(
|
||||||
final AbstractPluralAttributeBinding attributeBinding,
|
final AbstractPluralAttributeBinding attributeBinding,
|
||||||
final PluralAttributeSource attributeSource) {
|
final PluralAttributeSource attributeSource) {
|
||||||
PluralAttributeSource.Nature pluralAttributeNature = attributeSource.getNature();
|
final PluralAttributeSource.Nature pluralAttributeSourceNature = attributeSource.getNature();
|
||||||
if ( attributeSource.getElementSource().getNature() == PluralAttributeElementSource.Nature.ONE_TO_MANY
|
final PluralAttributeElementSource.Nature pluralElementSourceNature = attributeSource.getElementSource().getNature();
|
||||||
|| pluralAttributeNature == PluralAttributeSource.Nature.BAG ) {
|
final PluralAttributeElementBinding.Nature pluralElementBindingNature = attributeBinding.getPluralAttributeElementBinding().getNature();
|
||||||
|
|
||||||
|
//TODO what is this case? it would be really good to add a comment
|
||||||
|
if ( pluralElementSourceNature == PluralAttributeElementSource.Nature.ONE_TO_MANY
|
||||||
|
|| pluralAttributeSourceNature == PluralAttributeSource.Nature.BAG ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( attributeBinding.getPluralAttributeElementBinding()
|
if ( pluralElementBindingNature == PluralAttributeElementBinding.Nature.BASIC ) {
|
||||||
.getNature() == PluralAttributeElementBinding.Nature.BASIC ) {
|
switch ( pluralAttributeSourceNature ) {
|
||||||
if ( pluralAttributeNature == PluralAttributeSource.Nature.SET ) {
|
case SET:
|
||||||
bindBasicSetCollectionTablePrimaryKey( (SetBinding) attributeBinding );
|
bindBasicSetCollectionTablePrimaryKey( (SetBinding) attributeBinding );
|
||||||
}
|
break;
|
||||||
else if (
|
case LIST:
|
||||||
pluralAttributeNature == PluralAttributeSource.Nature.LIST
|
case MAP:
|
||||||
|| pluralAttributeNature == PluralAttributeSource.Nature.MAP
|
case ARRAY:
|
||||||
|| pluralAttributeNature == PluralAttributeSource.Nature.ARRAY ) {
|
bindIndexedCollectionTablePrimaryKey( (IndexedPluralAttributeBinding) attributeBinding );
|
||||||
bindIndexedCollectionTablePrimaryKey( (IndexedPluralAttributeBinding) attributeBinding );
|
break;
|
||||||
}
|
default:
|
||||||
else {
|
throw new NotYetImplementedException(
|
||||||
throw new NotYetImplementedException(
|
String.format( "%s of basic elements is not supported yet.", pluralAttributeSourceNature )
|
||||||
String.format( "%s of basic elements is not supported yet.", pluralAttributeNature )
|
);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( attributeBinding.getPluralAttributeElementBinding()
|
else if ( pluralElementBindingNature == PluralAttributeElementBinding.Nature.MANY_TO_MANY ) {
|
||||||
.getNature() == PluralAttributeElementBinding.Nature.MANY_TO_MANY ) {
|
|
||||||
if ( !attributeBinding.getPluralAttributeKeyBinding().isInverse() ) {
|
if ( !attributeBinding.getPluralAttributeKeyBinding().isInverse() ) {
|
||||||
if ( pluralAttributeNature == PluralAttributeSource.Nature.SET ) {
|
switch ( pluralAttributeSourceNature ) {
|
||||||
bindSetCollectionTablePrimaryKey( (SetBinding) attributeBinding );
|
case SET:
|
||||||
}
|
bindSetCollectionTablePrimaryKey( (SetBinding) attributeBinding );
|
||||||
else if (
|
break;
|
||||||
pluralAttributeNature == PluralAttributeSource.Nature.LIST
|
case LIST:
|
||||||
|| pluralAttributeNature == PluralAttributeSource.Nature.MAP
|
case MAP:
|
||||||
|| pluralAttributeNature == PluralAttributeSource.Nature.ARRAY ) {
|
case ARRAY:
|
||||||
bindIndexedCollectionTablePrimaryKey( (IndexedPluralAttributeBinding) attributeBinding );
|
bindIndexedCollectionTablePrimaryKey( (IndexedPluralAttributeBinding) attributeBinding );
|
||||||
}
|
break;
|
||||||
else {
|
default:
|
||||||
throw new NotYetImplementedException(
|
throw new NotYetImplementedException(
|
||||||
String.format( "Many-to-many %s is not supported yet.", pluralAttributeNature )
|
String.format( "Many-to-many %s is not supported yet.", pluralAttributeSourceNature )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,8 +144,8 @@ public List<AttributeSource> initialize() {
|
|||||||
}
|
}
|
||||||
for ( AssociationAttribute associationAttribute : embeddableClass.getAssociationAttributes() ) {
|
for ( AssociationAttribute associationAttribute : embeddableClass.getAssociationAttributes() ) {
|
||||||
associationAttribute.setNaturalIdMutability( embeddableClass.getNaturalIdMutability() );
|
associationAttribute.setNaturalIdMutability( embeddableClass.getNaturalIdMutability() );
|
||||||
attributeList.add( new ToOneAttributeSourceImpl( associationAttribute ) );
|
|
||||||
}
|
}
|
||||||
|
SourceHelper.resolveAssociationAttributes( embeddableClass, attributeList );
|
||||||
return Collections.unmodifiableList( attributeList );
|
return Collections.unmodifiableList( attributeList );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
import org.hibernate.metamodel.internal.source.annotations.attribute.AssociationAttribute;
|
import org.hibernate.metamodel.internal.source.annotations.attribute.AssociationAttribute;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.attribute.AttributeOverride;
|
import org.hibernate.metamodel.internal.source.annotations.attribute.AttributeOverride;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.attribute.BasicAttribute;
|
import org.hibernate.metamodel.internal.source.annotations.attribute.BasicAttribute;
|
||||||
|
import org.hibernate.metamodel.internal.source.annotations.entity.ConfiguredClass;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.entity.EmbeddableClass;
|
import org.hibernate.metamodel.internal.source.annotations.entity.EmbeddableClass;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.entity.EntityClass;
|
|
||||||
import org.hibernate.metamodel.spi.binding.CascadeType;
|
import org.hibernate.metamodel.spi.binding.CascadeType;
|
||||||
import org.hibernate.metamodel.spi.source.AttributeSource;
|
import org.hibernate.metamodel.spi.source.AttributeSource;
|
||||||
import org.hibernate.metamodel.spi.source.CompositePluralAttributeElementSource;
|
import org.hibernate.metamodel.spi.source.CompositePluralAttributeElementSource;
|
||||||
@ -47,7 +47,7 @@ public class CompositePluralAttributeElementSourceImpl implements CompositePlura
|
|||||||
private static final String PATH_SEPARATOR = ".";
|
private static final String PATH_SEPARATOR = ".";
|
||||||
|
|
||||||
private final AssociationAttribute associationAttribute;
|
private final AssociationAttribute associationAttribute;
|
||||||
private final EntityClass entityClass;
|
private final ConfiguredClass entityClass;
|
||||||
|
|
||||||
private List<AttributeSource> attributeSources
|
private List<AttributeSource> attributeSources
|
||||||
= new ArrayList<AttributeSource>();
|
= new ArrayList<AttributeSource>();
|
||||||
@ -56,7 +56,7 @@ public class CompositePluralAttributeElementSourceImpl implements CompositePlura
|
|||||||
|
|
||||||
public CompositePluralAttributeElementSourceImpl(
|
public CompositePluralAttributeElementSourceImpl(
|
||||||
AssociationAttribute associationAttribute,
|
AssociationAttribute associationAttribute,
|
||||||
EntityClass rootEntityClass ) {
|
ConfiguredClass rootEntityClass ) {
|
||||||
this.associationAttribute = associationAttribute;
|
this.associationAttribute = associationAttribute;
|
||||||
this.entityClass = rootEntityClass;
|
this.entityClass = rootEntityClass;
|
||||||
|
|
||||||
@ -152,8 +152,8 @@ private void buildAttributeSources() {
|
|||||||
}
|
}
|
||||||
for ( AssociationAttribute associationAttribute : embeddableClass.getAssociationAttributes() ) {
|
for ( AssociationAttribute associationAttribute : embeddableClass.getAssociationAttributes() ) {
|
||||||
associationAttribute.setNaturalIdMutability( embeddableClass.getNaturalIdMutability() );
|
associationAttribute.setNaturalIdMutability( embeddableClass.getNaturalIdMutability() );
|
||||||
attributeSources.add( new ToOneAttributeSourceImpl( associationAttribute ) );
|
|
||||||
}
|
}
|
||||||
|
SourceHelper.resolveAssociationAttributes( embeddableClass, attributeSources );
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, AttributeOverride> createAggregatedOverrideMap(
|
private Map<String, AttributeOverride> createAggregatedOverrideMap(
|
||||||
|
@ -32,16 +32,12 @@
|
|||||||
|
|
||||||
import org.hibernate.AnnotationException;
|
import org.hibernate.AnnotationException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.cfg.NotYetImplementedException;
|
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.jaxb.spi.Origin;
|
import org.hibernate.jaxb.spi.Origin;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.attribute.AssociationAttribute;
|
|
||||||
import org.hibernate.metamodel.internal.source.annotations.attribute.AttributeOverride;
|
import org.hibernate.metamodel.internal.source.annotations.attribute.AttributeOverride;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.attribute.BasicAttribute;
|
import org.hibernate.metamodel.internal.source.annotations.attribute.BasicAttribute;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute;
|
|
||||||
import org.hibernate.metamodel.internal.source.annotations.entity.EmbeddableClass;
|
import org.hibernate.metamodel.internal.source.annotations.entity.EmbeddableClass;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.entity.EntityClass;
|
import org.hibernate.metamodel.internal.source.annotations.entity.EntityClass;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.entity.RootEntityClass;
|
|
||||||
import org.hibernate.metamodel.internal.source.annotations.util.HibernateDotNames;
|
import org.hibernate.metamodel.internal.source.annotations.util.HibernateDotNames;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
|
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
|
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
|
||||||
@ -53,7 +49,6 @@
|
|||||||
import org.hibernate.metamodel.spi.source.JpaCallbackSource;
|
import org.hibernate.metamodel.spi.source.JpaCallbackSource;
|
||||||
import org.hibernate.metamodel.spi.source.LocalBindingContext;
|
import org.hibernate.metamodel.spi.source.LocalBindingContext;
|
||||||
import org.hibernate.metamodel.spi.source.MetaAttributeSource;
|
import org.hibernate.metamodel.spi.source.MetaAttributeSource;
|
||||||
import org.hibernate.metamodel.spi.source.PluralAttributeSource;
|
|
||||||
import org.hibernate.metamodel.spi.source.PrimaryKeyJoinColumnSource;
|
import org.hibernate.metamodel.spi.source.PrimaryKeyJoinColumnSource;
|
||||||
import org.hibernate.metamodel.spi.source.SecondaryTableSource;
|
import org.hibernate.metamodel.spi.source.SecondaryTableSource;
|
||||||
import org.hibernate.metamodel.spi.source.SubclassEntitySource;
|
import org.hibernate.metamodel.spi.source.SubclassEntitySource;
|
||||||
@ -229,32 +224,7 @@ public List<AttributeSource> attributeSources() {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
SourceHelper.resolveAssociationAttributes( entityClass, attributeList );
|
||||||
for ( AssociationAttribute associationAttribute : entityClass.getAssociationAttributes() ) {
|
|
||||||
switch ( associationAttribute.getNature() ) {
|
|
||||||
case ONE_TO_ONE:
|
|
||||||
case MANY_TO_ONE: {
|
|
||||||
attributeList.add( new ToOneAttributeSourceImpl( associationAttribute ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MANY_TO_MANY:
|
|
||||||
case ONE_TO_MANY:
|
|
||||||
case ELEMENT_COLLECTION_BASIC:
|
|
||||||
case ELEMENT_COLLECTION_EMBEDDABLE: {
|
|
||||||
PluralAssociationAttribute pluralAssociationAttribute = (PluralAssociationAttribute) associationAttribute;
|
|
||||||
PluralAttributeSource.Nature pluralAttributeNature = pluralAssociationAttribute.getPluralAttributeNature();
|
|
||||||
|
|
||||||
AttributeSource source = pluralAssociationAttribute.isIndexed() ?
|
|
||||||
new IndexedPluralAttributeSourceImpl( pluralAssociationAttribute, entityClass )
|
|
||||||
: new PluralAttributeSourceImpl( pluralAssociationAttribute, entityClass );
|
|
||||||
attributeList.add( source );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
throw new NotYetImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return attributeList;
|
return attributeList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import org.hibernate.metamodel.internal.source.annotations.attribute.MappedAttribute;
|
import org.hibernate.metamodel.internal.source.annotations.attribute.MappedAttribute;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute;
|
import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute;
|
||||||
|
import org.hibernate.metamodel.internal.source.annotations.entity.ConfiguredClass;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.entity.EntityClass;
|
import org.hibernate.metamodel.internal.source.annotations.entity.EntityClass;
|
||||||
import org.hibernate.metamodel.spi.source.IndexedPluralAttributeSource;
|
import org.hibernate.metamodel.spi.source.IndexedPluralAttributeSource;
|
||||||
import org.hibernate.metamodel.spi.source.MappingException;
|
import org.hibernate.metamodel.spi.source.MappingException;
|
||||||
@ -15,16 +16,16 @@
|
|||||||
public class IndexedPluralAttributeSourceImpl extends PluralAttributeSourceImpl
|
public class IndexedPluralAttributeSourceImpl extends PluralAttributeSourceImpl
|
||||||
implements IndexedPluralAttributeSource {
|
implements IndexedPluralAttributeSource {
|
||||||
private final PluralAttributeIndexSource indexSource;
|
private final PluralAttributeIndexSource indexSource;
|
||||||
private final static EnumSet<MappedAttribute.Nature> validNatures = EnumSet.of(
|
private final static EnumSet<MappedAttribute.Nature> VALID_NATURES = EnumSet.of(
|
||||||
MappedAttribute.Nature.MANY_TO_MANY,
|
MappedAttribute.Nature.MANY_TO_MANY,
|
||||||
MappedAttribute.Nature.ONE_TO_MANY,
|
MappedAttribute.Nature.ONE_TO_MANY,
|
||||||
MappedAttribute.Nature.ELEMENT_COLLECTION_BASIC,
|
MappedAttribute.Nature.ELEMENT_COLLECTION_BASIC,
|
||||||
MappedAttribute.Nature.ELEMENT_COLLECTION_EMBEDDABLE);
|
MappedAttribute.Nature.ELEMENT_COLLECTION_EMBEDDABLE);
|
||||||
|
|
||||||
public IndexedPluralAttributeSourceImpl(PluralAssociationAttribute attribute,
|
public IndexedPluralAttributeSourceImpl(PluralAssociationAttribute attribute,
|
||||||
EntityClass entityClass ) {
|
ConfiguredClass entityClass ) {
|
||||||
super( attribute, entityClass );
|
super( attribute, entityClass );
|
||||||
if ( !validNatures.contains( attribute.getNature() ) ) {
|
if ( !VALID_NATURES.contains( attribute.getNature() ) ) {
|
||||||
throw new MappingException(
|
throw new MappingException(
|
||||||
"Indexed column could be only mapped on the MANY side",
|
"Indexed column could be only mapped on the MANY side",
|
||||||
attribute.getContext().getOrigin()
|
attribute.getContext().getOrigin()
|
||||||
|
@ -24,9 +24,6 @@
|
|||||||
package org.hibernate.metamodel.internal.source.annotations;
|
package org.hibernate.metamodel.internal.source.annotations;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.jboss.jandex.AnnotationInstance;
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
|
|
||||||
@ -35,8 +32,8 @@
|
|||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.ValueHolder;
|
import org.hibernate.internal.util.ValueHolder;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute;
|
import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute;
|
||||||
|
import org.hibernate.metamodel.internal.source.annotations.entity.ConfiguredClass;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.entity.EntityClass;
|
import org.hibernate.metamodel.internal.source.annotations.entity.EntityClass;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.entity.RootEntityClass;
|
|
||||||
import org.hibernate.metamodel.spi.binding.Caching;
|
import org.hibernate.metamodel.spi.binding.Caching;
|
||||||
import org.hibernate.metamodel.spi.binding.CustomSQL;
|
import org.hibernate.metamodel.spi.binding.CustomSQL;
|
||||||
import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource;
|
import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource;
|
||||||
@ -61,7 +58,7 @@ public class PluralAttributeSourceImpl implements PluralAttributeSource, Orderab
|
|||||||
|
|
||||||
public PluralAttributeSourceImpl(
|
public PluralAttributeSourceImpl(
|
||||||
final PluralAssociationAttribute associationAttribute,
|
final PluralAssociationAttribute associationAttribute,
|
||||||
final EntityClass entityClass ) {
|
final ConfiguredClass entityClass ) {
|
||||||
this.associationAttribute = associationAttribute;
|
this.associationAttribute = associationAttribute;
|
||||||
this.keySource = new PluralAttributeKeySourceImpl( associationAttribute );
|
this.keySource = new PluralAttributeKeySourceImpl( associationAttribute );
|
||||||
this.typeSource = new ExplicitHibernateTypeSourceImpl( associationAttribute );
|
this.typeSource = new ExplicitHibernateTypeSourceImpl( associationAttribute );
|
||||||
@ -91,7 +88,7 @@ public ValueHolder<Class<?>> getElementClassReference() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PluralAttributeElementSource determineElementSource(PluralAssociationAttribute associationAttribute, EntityClass entityClass) {
|
private static PluralAttributeElementSource determineElementSource(PluralAssociationAttribute associationAttribute, ConfiguredClass entityClass) {
|
||||||
switch ( associationAttribute.getNature() ) {
|
switch ( associationAttribute.getNature() ) {
|
||||||
case MANY_TO_MANY:
|
case MANY_TO_MANY:
|
||||||
return new ManyToManyPluralAttributeElementSourceImpl( associationAttribute );
|
return new ManyToManyPluralAttributeElementSourceImpl( associationAttribute );
|
||||||
@ -222,7 +219,7 @@ public String getOrder() {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOrdered() {
|
public boolean isOrdered() {
|
||||||
return getOrder() != null;
|
return StringHelper.isNotEmpty( getOrder() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.internal.source.annotations;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.NotYetImplementedException;
|
||||||
|
import org.hibernate.metamodel.internal.source.annotations.attribute.AssociationAttribute;
|
||||||
|
import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute;
|
||||||
|
import org.hibernate.metamodel.internal.source.annotations.entity.ConfiguredClass;
|
||||||
|
import org.hibernate.metamodel.spi.source.AttributeSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Strong Liu <stliu@hibernate.org>
|
||||||
|
*/
|
||||||
|
public class SourceHelper {
|
||||||
|
/**
|
||||||
|
* Bind association attributes within {@param configuredClass} to the proper source impl based on its nature.
|
||||||
|
*
|
||||||
|
* @param configuredClass The holder of association attributes.
|
||||||
|
* @param attributeList Attribute source container, can't be <code>null</code>.
|
||||||
|
*/
|
||||||
|
public static void resolveAssociationAttributes(ConfiguredClass configuredClass, List<AttributeSource> attributeList) {
|
||||||
|
for ( AssociationAttribute associationAttribute : configuredClass.getAssociationAttributes() ) {
|
||||||
|
switch ( associationAttribute.getNature() ) {
|
||||||
|
case ONE_TO_ONE:
|
||||||
|
case MANY_TO_ONE: {
|
||||||
|
attributeList.add( new ToOneAttributeSourceImpl( associationAttribute ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MANY_TO_MANY:
|
||||||
|
case ONE_TO_MANY:
|
||||||
|
case ELEMENT_COLLECTION_BASIC:
|
||||||
|
case ELEMENT_COLLECTION_EMBEDDABLE: {
|
||||||
|
PluralAssociationAttribute pluralAssociationAttribute = (PluralAssociationAttribute) associationAttribute;
|
||||||
|
AttributeSource source = pluralAssociationAttribute.isIndexed() ?
|
||||||
|
new IndexedPluralAttributeSourceImpl( pluralAssociationAttribute, configuredClass )
|
||||||
|
: new PluralAttributeSourceImpl( pluralAssociationAttribute, configuredClass );
|
||||||
|
attributeList.add( source );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new NotYetImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -57,6 +57,7 @@ public class ToOneAttributeSourceImpl extends SingularAttributeSourceImpl implem
|
|||||||
private final Set<CascadeStyle> cascadeStyles;
|
private final Set<CascadeStyle> cascadeStyles;
|
||||||
|
|
||||||
public ToOneAttributeSourceImpl(AssociationAttribute associationAttribute) {
|
public ToOneAttributeSourceImpl(AssociationAttribute associationAttribute) {
|
||||||
|
|
||||||
super( associationAttribute );
|
super( associationAttribute );
|
||||||
this.associationAttribute = associationAttribute;
|
this.associationAttribute = associationAttribute;
|
||||||
this.cascadeStyles = EnumConversionHelper.cascadeTypeToCascadeStyleSet(
|
this.cascadeStyles = EnumConversionHelper.cascadeTypeToCascadeStyleSet(
|
||||||
@ -75,9 +76,8 @@ else if ( MappedAttribute.Nature.ONE_TO_ONE.equals( associationAttribute.getNatu
|
|||||||
throw new NotYetImplementedException( "One-to-one using annotations is not supported yet." );
|
throw new NotYetImplementedException( "One-to-one using annotations is not supported yet." );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new AssertionError(
|
throw new AssertionError(String.format( "Wrong attribute nature[%s] for toOne attribute: %s",
|
||||||
"Wrong attribute nature for toOne attribute: " + associationAttribute.getNature()
|
associationAttribute.getNature(), associationAttribute.getRole() ));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,12 +49,16 @@
|
|||||||
import org.hibernate.metamodel.internal.source.annotations.util.HibernateDotNames;
|
import org.hibernate.metamodel.internal.source.annotations.util.HibernateDotNames;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
|
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
|
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
|
||||||
|
import org.hibernate.metamodel.internal.source.annotations.xml.mocker.MockHelper;
|
||||||
import org.hibernate.metamodel.spi.source.MappingException;
|
import org.hibernate.metamodel.spi.source.MappingException;
|
||||||
import org.jboss.jandex.AnnotationInstance;
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
|
import org.jboss.jandex.AnnotationTarget;
|
||||||
import org.jboss.jandex.AnnotationValue;
|
import org.jboss.jandex.AnnotationValue;
|
||||||
import org.jboss.jandex.ClassInfo;
|
import org.jboss.jandex.ClassInfo;
|
||||||
import org.jboss.jandex.DotName;
|
import org.jboss.jandex.DotName;
|
||||||
|
import org.jboss.jandex.FieldInfo;
|
||||||
import org.jboss.jandex.Index;
|
import org.jboss.jandex.Index;
|
||||||
|
import org.jboss.jandex.Type;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,6 +91,7 @@ public class AssociationAttribute extends MappedAttribute {
|
|||||||
private AttributeTypeResolver resolver;
|
private AttributeTypeResolver resolver;
|
||||||
|
|
||||||
public static AssociationAttribute createAssociationAttribute(
|
public static AssociationAttribute createAssociationAttribute(
|
||||||
|
ClassInfo classInfo,
|
||||||
String name,
|
String name,
|
||||||
Class<?> attributeType,
|
Class<?> attributeType,
|
||||||
Nature attributeNature,
|
Nature attributeNature,
|
||||||
@ -94,6 +99,7 @@ public static AssociationAttribute createAssociationAttribute(
|
|||||||
Map<DotName, List<AnnotationInstance>> annotations,
|
Map<DotName, List<AnnotationInstance>> annotations,
|
||||||
EntityBindingContext context) {
|
EntityBindingContext context) {
|
||||||
return new AssociationAttribute(
|
return new AssociationAttribute(
|
||||||
|
classInfo,
|
||||||
name,
|
name,
|
||||||
attributeType,
|
attributeType,
|
||||||
attributeType,
|
attributeType,
|
||||||
@ -105,6 +111,7 @@ public static AssociationAttribute createAssociationAttribute(
|
|||||||
}
|
}
|
||||||
|
|
||||||
AssociationAttribute(
|
AssociationAttribute(
|
||||||
|
ClassInfo classInfo,
|
||||||
String name,
|
String name,
|
||||||
Class<?> attributeType,
|
Class<?> attributeType,
|
||||||
Class<?> referencedAttributeType,
|
Class<?> referencedAttributeType,
|
||||||
@ -119,6 +126,23 @@ public static AssociationAttribute createAssociationAttribute(
|
|||||||
annotations,
|
annotations,
|
||||||
attributeNature.getAnnotationDotName()
|
attributeNature.getAnnotationDotName()
|
||||||
);
|
);
|
||||||
|
if ( associationAnnotation == null &&
|
||||||
|
( attributeNature == Nature.ELEMENT_COLLECTION_BASIC || attributeNature == Nature.ELEMENT_COLLECTION_EMBEDDABLE ) ) {
|
||||||
|
|
||||||
|
AnnotationTarget target = MockHelper.getTarget(
|
||||||
|
context.getServiceRegistry(),
|
||||||
|
classInfo,
|
||||||
|
name,
|
||||||
|
MockHelper.TargetType.valueOf( accessType.toUpperCase() )
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
associationAnnotation = AnnotationInstance.create(
|
||||||
|
attributeNature.getAnnotationDotName(),
|
||||||
|
target,
|
||||||
|
MockHelper.EMPTY_ANNOTATION_VALUE_ARRAY
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// using jandex we don't really care which exact type of annotation we are dealing with
|
// using jandex we don't really care which exact type of annotation we are dealing with
|
||||||
this.referencedEntityType = determineReferencedEntityType( associationAnnotation, referencedAttributeType );
|
this.referencedEntityType = determineReferencedEntityType( associationAnnotation, referencedAttributeType );
|
||||||
|
@ -23,9 +23,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.internal.source.annotations.attribute;
|
package org.hibernate.metamodel.internal.source.annotations.attribute;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.SortedMap;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
|
|
||||||
@ -77,17 +81,22 @@ public class PluralAssociationAttribute extends AssociationAttribute {
|
|||||||
private final String explicitForeignKeyName;
|
private final String explicitForeignKeyName;
|
||||||
|
|
||||||
private final PluralAttributeSource.Nature pluralAttributeNature;
|
private final PluralAttributeSource.Nature pluralAttributeNature;
|
||||||
|
private static final EnumSet<PluralAttributeSource.Nature> SHOULD_NOT_HAS_COLLECTION_ID = EnumSet.of( PluralAttributeSource.Nature.SET,
|
||||||
|
PluralAttributeSource.Nature.MAP, PluralAttributeSource.Nature.LIST, PluralAttributeSource.Nature.ARRAY );
|
||||||
|
|
||||||
private LazyCollectionOption lazyOption;
|
private LazyCollectionOption lazyOption;
|
||||||
|
private final boolean isCollectionIdPresent;
|
||||||
|
|
||||||
public static PluralAssociationAttribute createPluralAssociationAttribute(ClassInfo entityClassInfo,
|
|
||||||
String name,
|
public static PluralAssociationAttribute createPluralAssociationAttribute(
|
||||||
Class<?> attributeType,
|
ClassInfo entityClassInfo,
|
||||||
Class<?> referencedAttributeType,
|
String name,
|
||||||
Nature attributeNature,
|
Class<?> attributeType,
|
||||||
String accessType,
|
Class<?> referencedAttributeType,
|
||||||
Map<DotName, List<AnnotationInstance>> annotations,
|
Nature attributeNature,
|
||||||
EntityBindingContext context) {
|
String accessType,
|
||||||
|
Map<DotName, List<AnnotationInstance>> annotations,
|
||||||
|
EntityBindingContext context) {
|
||||||
return new PluralAssociationAttribute(
|
return new PluralAssociationAttribute(
|
||||||
entityClassInfo,
|
entityClassInfo,
|
||||||
name,
|
name,
|
||||||
@ -171,15 +180,16 @@ public boolean isIndexed() {
|
|||||||
return isIndexed;
|
return isIndexed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PluralAssociationAttribute(ClassInfo entityClassInfo,
|
private PluralAssociationAttribute(
|
||||||
String name,
|
final ClassInfo entityClassInfo,
|
||||||
Class<?> attributeType,
|
final String name,
|
||||||
Class<?> referencedAttributeType,
|
final Class<?> attributeType,
|
||||||
Nature associationType,
|
final Class<?> referencedAttributeType,
|
||||||
String accessType,
|
final Nature associationType,
|
||||||
Map<DotName, List<AnnotationInstance>> annotations,
|
final String accessType,
|
||||||
EntityBindingContext context) {
|
final Map<DotName, List<AnnotationInstance>> annotations,
|
||||||
super( name, attributeType, referencedAttributeType, associationType, accessType, annotations, context );
|
final EntityBindingContext context) {
|
||||||
|
super( entityClassInfo, name, attributeType, referencedAttributeType, associationType, accessType, annotations, context );
|
||||||
this.entityClassInfo = entityClassInfo;
|
this.entityClassInfo = entityClassInfo;
|
||||||
this.whereClause = determineWereClause();
|
this.whereClause = determineWereClause();
|
||||||
this.orderBy = determineOrderBy();
|
this.orderBy = determineOrderBy();
|
||||||
@ -215,7 +225,10 @@ HibernateDotNames.SQL_DELETE, annotations()
|
|||||||
HibernateDotNames.SQL_DELETE_ALL, annotations()
|
HibernateDotNames.SQL_DELETE_ALL, annotations()
|
||||||
);
|
);
|
||||||
this.onDeleteAction = determineOnDeleteAction();
|
this.onDeleteAction = determineOnDeleteAction();
|
||||||
|
this.isCollectionIdPresent = JandexHelper.getSingleAnnotation(
|
||||||
|
annotations,
|
||||||
|
HibernateDotNames.COLLECTION_ID
|
||||||
|
) != null;
|
||||||
final AnnotationInstance sortAnnotation = JandexHelper.getSingleAnnotation( annotations, HibernateDotNames.SORT );
|
final AnnotationInstance sortAnnotation = JandexHelper.getSingleAnnotation( annotations, HibernateDotNames.SORT );
|
||||||
if ( sortAnnotation == null ) {
|
if ( sortAnnotation == null ) {
|
||||||
this.sorted = false;
|
this.sorted = false;
|
||||||
@ -249,15 +262,58 @@ HibernateDotNames.SQL_DELETE_ALL, annotations()
|
|||||||
}
|
}
|
||||||
this.isIndexed = orderColumnAnnotation != null || indexColumnAnnotation != null;
|
this.isIndexed = orderColumnAnnotation != null || indexColumnAnnotation != null;
|
||||||
this.pluralAttributeNature = resolvePluralAttributeNature();
|
this.pluralAttributeNature = resolvePluralAttributeNature();
|
||||||
|
|
||||||
|
validateMapping();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateMapping() {
|
||||||
|
checkSortedTypeIsSortable();
|
||||||
|
checkIfCollectionIdIsWronglyPlaced();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkIfCollectionIdIsWronglyPlaced() {
|
||||||
|
if ( isCollectionIdPresent && SHOULD_NOT_HAS_COLLECTION_ID.contains( pluralAttributeNature ) ) {
|
||||||
|
throw new MappingException(
|
||||||
|
"The Collection type doesn't support @CollectionId annotation: " + getRole(),
|
||||||
|
getContext().getOrigin()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkSortedTypeIsSortable() {
|
||||||
|
//shortcut, a little performance improvement of avoiding the class type check
|
||||||
|
if ( pluralAttributeNature == PluralAttributeSource.Nature.MAP
|
||||||
|
|| pluralAttributeNature == PluralAttributeSource.Nature.SET ) {
|
||||||
|
if ( SortedMap.class.isAssignableFrom( getAttributeType() )
|
||||||
|
|| SortedSet.class.isAssignableFrom( getAttributeType() ) ) {
|
||||||
|
if ( !isSorted() ) {
|
||||||
|
throw new MappingException(
|
||||||
|
"A sorted collection has to define @Sort: " + getRole(),
|
||||||
|
getContext().getOrigin()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO org.hibernate.cfg.annotations.CollectionBinder#hasToBeSorted
|
||||||
private PluralAttributeSource.Nature resolvePluralAttributeNature() {
|
private PluralAttributeSource.Nature resolvePluralAttributeNature() {
|
||||||
|
|
||||||
if ( Map.class.isAssignableFrom( getAttributeType() ) ) {
|
if ( Map.class.isAssignableFrom( getAttributeType() ) ) {
|
||||||
return PluralAttributeSource.Nature.MAP;
|
return PluralAttributeSource.Nature.MAP;
|
||||||
}
|
}
|
||||||
else if ( List.class.isAssignableFrom( getAttributeType() ) ) {
|
else if ( List.class.isAssignableFrom( getAttributeType() ) ) {
|
||||||
return isIndexed() ? PluralAttributeSource.Nature.LIST : PluralAttributeSource.Nature.BAG;
|
if ( isIndexed() ) {
|
||||||
|
return PluralAttributeSource.Nature.LIST;
|
||||||
|
}
|
||||||
|
else if ( isCollectionIdPresent ) {
|
||||||
|
return PluralAttributeSource.Nature.ID_BAG;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return PluralAttributeSource.Nature.BAG;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ( Set.class.isAssignableFrom( getAttributeType() ) ) {
|
else if ( Set.class.isAssignableFrom( getAttributeType() ) ) {
|
||||||
return PluralAttributeSource.Nature.SET;
|
return PluralAttributeSource.Nature.SET;
|
||||||
@ -265,22 +321,24 @@ else if ( Set.class.isAssignableFrom( getAttributeType() ) ) {
|
|||||||
else if ( getAttributeType().isArray() ) {
|
else if ( getAttributeType().isArray() ) {
|
||||||
return PluralAttributeSource.Nature.ARRAY;
|
return PluralAttributeSource.Nature.ARRAY;
|
||||||
}
|
}
|
||||||
|
else if ( Collection.class.isAssignableFrom( getAttributeType() ) ) {
|
||||||
|
return isCollectionIdPresent ? PluralAttributeSource.Nature.ID_BAG : PluralAttributeSource.Nature.BAG;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
return PluralAttributeSource.Nature.BAG;
|
return PluralAttributeSource.Nature.BAG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private OnDeleteAction determineOnDeleteAction() {
|
|
||||||
|
|
||||||
OnDeleteAction action = null;
|
private OnDeleteAction determineOnDeleteAction() {
|
||||||
final AnnotationInstance onDeleteAnnotation = JandexHelper.getSingleAnnotation(
|
final AnnotationInstance onDeleteAnnotation = JandexHelper.getSingleAnnotation(
|
||||||
annotations(),
|
annotations(),
|
||||||
HibernateDotNames.ON_DELETE
|
HibernateDotNames.ON_DELETE
|
||||||
);
|
);
|
||||||
if ( onDeleteAnnotation != null ) {
|
if ( onDeleteAnnotation != null ) {
|
||||||
action = JandexHelper.getEnumValue( onDeleteAnnotation, "action", OnDeleteAction.class );
|
return JandexHelper.getEnumValue( onDeleteAnnotation, "action", OnDeleteAction.class );
|
||||||
}
|
}
|
||||||
return action;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -369,9 +427,10 @@ private String determineOrderBy() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ( jpaWhereAnnotation != null && hibernateWhereAnnotation != null ) {
|
if ( jpaWhereAnnotation != null && hibernateWhereAnnotation != null ) {
|
||||||
throw new AnnotationException(
|
throw new MappingException(
|
||||||
"Cannot use sql order by clause (@org.hibernate.annotations.OrderBy) " +
|
"Cannot use sql order by clause (@org.hibernate.annotations.OrderBy) " +
|
||||||
"in conjunction with JPA order by clause (@java.persistence.OrderBy) on " + getRole()
|
"in conjunction with JPA order by clause (@java.persistence.OrderBy) on " + getRole(),
|
||||||
|
getContext().getOrigin()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,12 +444,21 @@ private String determineOrderBy() {
|
|||||||
// associated entity is assumed
|
// associated entity is assumed
|
||||||
// The binder will need to take this into account and generate the right property names
|
// The binder will need to take this into account and generate the right property names
|
||||||
orderBy = JandexHelper.getValue( jpaWhereAnnotation, "value", String.class );
|
orderBy = JandexHelper.getValue( jpaWhereAnnotation, "value", String.class );
|
||||||
orderBy = orderBy == null ? "" : orderBy;
|
if ( orderBy == null ) {
|
||||||
|
orderBy = isBasicCollection() ? "$element$ asc" :"id asc" ;
|
||||||
|
}
|
||||||
|
if ( orderBy.equalsIgnoreCase( "desc" ) ) {
|
||||||
|
orderBy = isBasicCollection() ? "$element$ desc" :"id desc";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return orderBy;
|
return orderBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isBasicCollection(){
|
||||||
|
return getNature() == Nature.ELEMENT_COLLECTION_BASIC || getNature() == Nature.ELEMENT_COLLECTION_EMBEDDABLE;
|
||||||
|
}
|
||||||
|
|
||||||
private Caching determineCachingSettings() {
|
private Caching determineCachingSettings() {
|
||||||
Caching caching = null;
|
Caching caching = null;
|
||||||
final AnnotationInstance hibernateCacheAnnotation = JandexHelper.getSingleAnnotation(
|
final AnnotationInstance hibernateCacheAnnotation = JandexHelper.getSingleAnnotation(
|
||||||
@ -418,6 +486,8 @@ private Caching determineCachingSettings() {
|
|||||||
}
|
}
|
||||||
return caching;
|
return caching;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -46,6 +47,7 @@
|
|||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.AnnotationBindingContext;
|
import org.hibernate.metamodel.internal.source.annotations.AnnotationBindingContext;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.attribute.AssociationAttribute;
|
import org.hibernate.metamodel.internal.source.annotations.attribute.AssociationAttribute;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.attribute.AttributeOverride;
|
import org.hibernate.metamodel.internal.source.annotations.attribute.AttributeOverride;
|
||||||
@ -513,6 +515,7 @@ else if ( attribute.isVersioned() ) {
|
|||||||
case ONE_TO_ONE:
|
case ONE_TO_ONE:
|
||||||
case MANY_TO_ONE: {
|
case MANY_TO_ONE: {
|
||||||
final AssociationAttribute attribute = AssociationAttribute.createAssociationAttribute(
|
final AssociationAttribute attribute = AssociationAttribute.createAssociationAttribute(
|
||||||
|
classInfo,
|
||||||
attributeName,
|
attributeName,
|
||||||
resolvedMember.getType().getErasedType(),
|
resolvedMember.getType().getErasedType(),
|
||||||
attributeNature,
|
attributeNature,
|
||||||
@ -599,39 +602,36 @@ private MappedAttribute.Nature determineAttributeNature( Map<DotName,
|
|||||||
List<AnnotationInstance>> annotations,
|
List<AnnotationInstance>> annotations,
|
||||||
Class<?> attributeType,
|
Class<?> attributeType,
|
||||||
Class<?> referencedCollectionType ) {
|
Class<?> referencedCollectionType ) {
|
||||||
EnumMap<MappedAttribute.Nature, AnnotationInstance> discoveredAttributeTypes =
|
EnumSet<MappedAttribute.Nature> discoveredAttributeTypes = EnumSet.noneOf( MappedAttribute.Nature.class );
|
||||||
new EnumMap<MappedAttribute.Nature, AnnotationInstance>( MappedAttribute.Nature.class );
|
|
||||||
|
|
||||||
AnnotationInstance oneToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_ONE );
|
AnnotationInstance oneToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_ONE );
|
||||||
if ( oneToOne != null ) {
|
if ( oneToOne != null ) {
|
||||||
discoveredAttributeTypes.put( MappedAttribute.Nature.ONE_TO_ONE, oneToOne );
|
discoveredAttributeTypes.add( MappedAttribute.Nature.ONE_TO_ONE );
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnotationInstance oneToMany = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_MANY );
|
AnnotationInstance oneToMany = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_MANY );
|
||||||
if ( oneToMany != null ) {
|
if ( oneToMany != null ) {
|
||||||
discoveredAttributeTypes.put( MappedAttribute.Nature.ONE_TO_MANY, oneToMany );
|
discoveredAttributeTypes.add( MappedAttribute.Nature.ONE_TO_MANY );
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnotationInstance manyToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_ONE );
|
AnnotationInstance manyToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_ONE );
|
||||||
if ( manyToOne != null ) {
|
if ( manyToOne != null ) {
|
||||||
discoveredAttributeTypes.put( MappedAttribute.Nature.MANY_TO_ONE, manyToOne );
|
discoveredAttributeTypes.add( MappedAttribute.Nature.MANY_TO_ONE );
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnotationInstance manyToMany = JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_MANY );
|
AnnotationInstance manyToMany = JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_MANY );
|
||||||
if ( manyToMany != null ) {
|
if ( manyToMany != null ) {
|
||||||
discoveredAttributeTypes.put( MappedAttribute.Nature.MANY_TO_MANY, manyToMany );
|
discoveredAttributeTypes.add( MappedAttribute.Nature.MANY_TO_MANY );
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnotationInstance embeddedId = JandexHelper.getSingleAnnotation( annotations, JPADotNames.EMBEDDED_ID );
|
AnnotationInstance embeddedId = JandexHelper.getSingleAnnotation( annotations, JPADotNames.EMBEDDED_ID );
|
||||||
if ( embeddedId != null ) {
|
if ( embeddedId != null ) {
|
||||||
discoveredAttributeTypes.put( MappedAttribute.Nature.EMBEDDED_ID, embeddedId );
|
discoveredAttributeTypes.add( MappedAttribute.Nature.EMBEDDED_ID );
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnotationInstance embedded = JandexHelper.getSingleAnnotation(
|
AnnotationInstance embedded = JandexHelper.getSingleAnnotation(
|
||||||
annotations, JPADotNames.EMBEDDED );
|
annotations, JPADotNames.EMBEDDED );
|
||||||
if ( embedded != null ) {
|
if ( embedded != null ) {
|
||||||
discoveredAttributeTypes.put( MappedAttribute.Nature.EMBEDDED,
|
discoveredAttributeTypes.add( MappedAttribute.Nature.EMBEDDED );
|
||||||
embedded );
|
|
||||||
} else if ( embeddedId == null ) {
|
} else if ( embeddedId == null ) {
|
||||||
// For backward compatibility, we're allowing attributes of an
|
// For backward compatibility, we're allowing attributes of an
|
||||||
// @Embeddable type to leave off @Embedded. Check the type's
|
// @Embeddable type to leave off @Embedded. Check the type's
|
||||||
@ -644,8 +644,7 @@ private MappedAttribute.Nature determineAttributeNature( Map<DotName,
|
|||||||
&& JandexHelper.getSingleAnnotation(
|
&& JandexHelper.getSingleAnnotation(
|
||||||
typeClassInfo.annotations(),
|
typeClassInfo.annotations(),
|
||||||
JPADotNames.EMBEDDABLE ) != null ) {
|
JPADotNames.EMBEDDABLE ) != null ) {
|
||||||
discoveredAttributeTypes.put( MappedAttribute.Nature.EMBEDDED,
|
discoveredAttributeTypes.add( MappedAttribute.Nature.EMBEDDED );
|
||||||
null );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,19 +652,9 @@ private MappedAttribute.Nature determineAttributeNature( Map<DotName,
|
|||||||
annotations,
|
annotations,
|
||||||
JPADotNames.ELEMENT_COLLECTION
|
JPADotNames.ELEMENT_COLLECTION
|
||||||
);
|
);
|
||||||
if ( elementCollection != null ) {
|
if ( elementCollection != null || ( discoveredAttributeTypes.isEmpty() && CollectionHelper.isCollectionOrArray( attributeType ) )) {
|
||||||
// class info can be null for types like string, etc where there are no annotations
|
boolean isEmbeddable = isEmbeddableType( referencedCollectionType );
|
||||||
ClassInfo classInfo = getLocalBindingContext().getIndex().getClassByName(
|
discoveredAttributeTypes.add( isEmbeddable? MappedAttribute.Nature.ELEMENT_COLLECTION_EMBEDDABLE : MappedAttribute.Nature.ELEMENT_COLLECTION_BASIC );
|
||||||
DotName.createSimple(
|
|
||||||
referencedCollectionType.getName()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
if ( classInfo != null && classInfo.annotations().get( JPADotNames.EMBEDDABLE ) != null ) {
|
|
||||||
discoveredAttributeTypes.put( MappedAttribute.Nature.ELEMENT_COLLECTION_EMBEDDABLE, elementCollection );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
discoveredAttributeTypes.put( MappedAttribute.Nature.ELEMENT_COLLECTION_BASIC, elementCollection );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int size = discoveredAttributeTypes.size();
|
int size = discoveredAttributeTypes.size();
|
||||||
@ -673,12 +662,22 @@ private MappedAttribute.Nature determineAttributeNature( Map<DotName,
|
|||||||
case 0:
|
case 0:
|
||||||
return MappedAttribute.Nature.BASIC;
|
return MappedAttribute.Nature.BASIC;
|
||||||
case 1:
|
case 1:
|
||||||
return discoveredAttributeTypes.keySet().iterator().next();
|
return discoveredAttributeTypes.iterator().next();
|
||||||
default:
|
default:
|
||||||
throw new AnnotationException( "More than one association type configured for property " + getName() + " of class " + getName() );
|
throw new AnnotationException( "More than one association type configured for property " + getName() + " of class " + getName() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isEmbeddableType(Class<?> referencedCollectionType) {
|
||||||
|
// class info can be null for types like string, etc where there are no annotations
|
||||||
|
ClassInfo classInfo = getLocalBindingContext().getIndex().getClassByName(
|
||||||
|
DotName.createSimple(
|
||||||
|
referencedCollectionType.getName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return classInfo != null && classInfo.annotations().get( JPADotNames.EMBEDDABLE ) != null;
|
||||||
|
}
|
||||||
|
|
||||||
private ResolvedMember findResolvedMember(String name, ResolvedMember[] resolvedMembers) {
|
private ResolvedMember findResolvedMember(String name, ResolvedMember[] resolvedMembers) {
|
||||||
for ( ResolvedMember resolvedMember : resolvedMembers ) {
|
for ( ResolvedMember resolvedMember : resolvedMembers ) {
|
||||||
if ( resolvedMember.getName().equals( name ) ) {
|
if ( resolvedMember.getName().equals( name ) ) {
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
*/
|
*/
|
||||||
public class MockHelper {
|
public class MockHelper {
|
||||||
|
|
||||||
static final AnnotationValue[] EMPTY_ANNOTATION_VALUE_ARRAY = new AnnotationValue[0];
|
public static final AnnotationValue[] EMPTY_ANNOTATION_VALUE_ARRAY = new AnnotationValue[0];
|
||||||
static final Type[] EMPTY_TYPE_ARRAY = new Type[0];
|
static final Type[] EMPTY_TYPE_ARRAY = new Type[0];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -305,9 +305,9 @@ private static MethodInfo getMethodInfo(ClassInfo classInfo, Method method) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TargetType {METHOD, FIELD, PROPERTY}
|
public enum TargetType {METHOD, FIELD, PROPERTY}
|
||||||
|
|
||||||
static AnnotationTarget getTarget(ServiceRegistry serviceRegistry, ClassInfo classInfo, String name, TargetType type) {
|
public static AnnotationTarget getTarget(ServiceRegistry serviceRegistry, ClassInfo classInfo, String name, TargetType type) {
|
||||||
Class clazz = serviceRegistry.getService( ClassLoaderService.class ).classForName( classInfo.toString() );
|
Class clazz = serviceRegistry.getService( ClassLoaderService.class ).classForName( classInfo.toString() );
|
||||||
switch ( type ) {
|
switch ( type ) {
|
||||||
case FIELD:
|
case FIELD:
|
||||||
@ -440,7 +440,7 @@ private static Type getType(Class clazz) {
|
|||||||
return Type.create( DotName.createSimple( clazz.getName() ), getTypeKind( clazz ) );
|
return Type.create( DotName.createSimple( clazz.getName() ), getTypeKind( clazz ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Type.Kind getTypeKind(Class clazz) {
|
public static Type.Kind getTypeKind(Class clazz) {
|
||||||
Type.Kind kind;
|
Type.Kind kind;
|
||||||
if ( clazz == Void.TYPE ) {
|
if ( clazz == Void.TYPE ) {
|
||||||
kind = Type.Kind.VOID;
|
kind = Type.Kind.VOID;
|
||||||
|
@ -51,7 +51,7 @@ public JaxbBagElement getPluralAttributeElement() {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOrdered() {
|
public boolean isOrdered() {
|
||||||
return getOrder() != null;
|
return StringHelper.isNotEmpty( getOrder() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -64,7 +64,7 @@ public String getComparatorName() {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOrdered() {
|
public boolean isOrdered() {
|
||||||
return getOrder() != null;
|
return StringHelper.isNotEmpty( getOrder() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@ -33,6 +34,7 @@
|
|||||||
/**
|
/**
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
|
@FailureExpectedWithNewMetamodel
|
||||||
public class IndexedCollectionOfElementsTest extends BaseCoreFunctionalTestCase {
|
public class IndexedCollectionOfElementsTest extends BaseCoreFunctionalTestCase {
|
||||||
@Test
|
@Test
|
||||||
public void testIndexedCollectionOfElements() throws Exception {
|
public void testIndexedCollectionOfElements() throws Exception {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user