/* * 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.cfg.annotations; import java.util.Map; import org.hibernate.AnnotationException; import org.hibernate.MappingException; import org.hibernate.annotations.OrderBy; import org.hibernate.annotations.Sort; import org.hibernate.annotations.common.reflection.XClass; import org.hibernate.annotations.common.reflection.XProperty; import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.cfg.CollectionSecondPass; import org.hibernate.cfg.Ejb3Column; import org.hibernate.cfg.Ejb3JoinColumn; import org.hibernate.cfg.PropertyHolder; import org.hibernate.cfg.PropertyHolderBuilder; import org.hibernate.cfg.SecondPass; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.StringHelper; import org.hibernate.mapping.Collection; import org.hibernate.mapping.IndexBackref; import org.hibernate.mapping.List; import org.hibernate.mapping.OneToMany; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.SimpleValue; import org.jboss.logging.Logger; /** * Bind a list to the underlying Hibernate configuration * * @author Matthew Inger * @author Emmanuel Bernard */ @SuppressWarnings({"unchecked", "serial"}) public class ListBinder extends CollectionBinder { private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, ListBinder.class.getName() ); public ListBinder() { super( false ); } @Override protected Collection createCollection(PersistentClass persistentClass) { return new org.hibernate.mapping.List( getBuildingContext().getMetadataCollector(), persistentClass ); } @Override public void setSqlOrderBy(OrderBy orderByAnn) { if ( orderByAnn != null ) { LOG.orderByAnnotationIndexedCollection(); } } @Override public void setSort(Sort sortAnn) { if ( sortAnn != null ) { LOG.sortAnnotationIndexedCollection(); } } @Override public SecondPass getSecondPass( final Ejb3JoinColumn[] fkJoinColumns, final Ejb3JoinColumn[] keyColumns, final Ejb3JoinColumn[] inverseColumns, final Ejb3Column[] elementColumns, Ejb3Column[] mapKeyColumns, final Ejb3JoinColumn[] mapKeyManyToManyColumns, final boolean isEmbedded, final XProperty property, final XClass collType, final boolean ignoreNotFound, final boolean unique, final TableBinder assocTableBinder, final MetadataBuildingContext buildingContext) { return new CollectionSecondPass( getBuildingContext(), ListBinder.this.collection ) { @Override public void secondPass(Map persistentClasses, Map inheritedMetas) throws MappingException { bindStarToManySecondPass( persistentClasses, collType, fkJoinColumns, keyColumns, inverseColumns, elementColumns, isEmbedded, property, unique, assocTableBinder, ignoreNotFound, buildingContext ); bindIndex( buildingContext ); } }; } private void bindIndex(final MetadataBuildingContext buildingContext) { if ( !indexColumn.isImplicit() ) { PropertyHolder valueHolder = PropertyHolderBuilder.buildPropertyHolder( this.collection, StringHelper.qualify( this.collection.getRole(), "key" ), null, null, propertyHolder, getBuildingContext() ); List list = (List) this.collection; if ( !list.isOneToMany() ) indexColumn.forceNotNull(); indexColumn.setPropertyHolder( valueHolder ); SimpleValueBinder value = new SimpleValueBinder(); value.setColumns( new Ejb3Column[] { indexColumn } ); value.setExplicitType( "integer" ); value.setBuildingContext( getBuildingContext() ); SimpleValue indexValue = value.make(); indexColumn.linkWithValue( indexValue ); list.setIndex( indexValue ); list.setBaseIndex( indexColumn.getBase() ); if ( list.isOneToMany() && !list.getKey().isNullable() && !list.isInverse() ) { String entityName = ( (OneToMany) list.getElement() ).getReferencedEntityName(); PersistentClass referenced = buildingContext.getMetadataCollector().getEntityBinding( entityName ); IndexBackref ib = new IndexBackref(); ib.setName( '_' + propertyName + "IndexBackref" ); ib.setUpdateable( false ); ib.setSelectable( false ); ib.setCollectionRole( list.getRole() ); ib.setEntityName( list.getOwner().getEntityName() ); ib.setValue( list.getIndex() ); referenced.addProperty( ib ); } } else { Collection coll = this.collection; throw new AnnotationException( "List/array has to be annotated with an @OrderColumn (or @IndexColumn): " + coll.getRole() ); } } }