📄 mapbinder.java
字号:
//$Id: MapBinder.java 14425 2008-03-14 15:50:34Z epbernard $package org.hibernate.cfg.annotations;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Random;import javax.persistence.AttributeOverride;import javax.persistence.AttributeOverrides;import org.hibernate.AnnotationException;import org.hibernate.AssertionFailure;import org.hibernate.FetchMode;import org.hibernate.MappingException;import org.hibernate.annotations.MapKeyManyToMany;import org.hibernate.annotations.MapKey;import org.hibernate.annotations.common.reflection.XClass;import org.hibernate.annotations.common.reflection.XProperty;import org.hibernate.cfg.AnnotatedClassType;import org.hibernate.cfg.AnnotationBinder;import org.hibernate.cfg.BinderHelper;import org.hibernate.cfg.CollectionSecondPass;import org.hibernate.cfg.Ejb3Column;import org.hibernate.cfg.Ejb3JoinColumn;import org.hibernate.cfg.ExtendedMappings;import org.hibernate.cfg.PropertyData;import org.hibernate.cfg.PropertyHolder;import org.hibernate.cfg.PropertyHolderBuilder;import org.hibernate.cfg.PropertyPreloadedData;import org.hibernate.cfg.SecondPass;import org.hibernate.dialect.HSQLDialect;import org.hibernate.mapping.Collection;import org.hibernate.mapping.Column;import org.hibernate.mapping.Component;import org.hibernate.mapping.DependantValue;import org.hibernate.mapping.Formula;import org.hibernate.mapping.Join;import org.hibernate.mapping.ManyToOne;import org.hibernate.mapping.OneToMany;import org.hibernate.mapping.PersistentClass;import org.hibernate.mapping.Property;import org.hibernate.mapping.SimpleValue;import org.hibernate.mapping.ToOne;import org.hibernate.mapping.Value;import org.hibernate.sql.Template;import org.hibernate.util.StringHelper;/** * Implementation to bind a Map * * @author Emmanuel Bernard */public class MapBinder extends CollectionBinder { public MapBinder(boolean sorted) { super( sorted ); } public MapBinder() { super(); } protected Collection createCollection(PersistentClass persistentClass) { return new org.hibernate.mapping.Map( persistentClass ); } @Override public SecondPass getSecondPass( final Ejb3JoinColumn[] fkJoinColumns, final Ejb3JoinColumn[] keyColumns, final Ejb3JoinColumn[] inverseColumns, final Ejb3Column[] elementColumns, final Ejb3Column[] mapKeyColumns, final Ejb3JoinColumn[] mapKeyManyToManyColumns, final boolean isEmbedded, final XProperty property, final XClass collType, final boolean ignoreNotFound, final boolean unique, final TableBinder assocTableBinder, final ExtendedMappings mappings ) { return new CollectionSecondPass( mappings, MapBinder.this.collection ) { public void secondPass(Map persistentClasses, Map inheritedMetas) throws MappingException { bindStarToManySecondPass( persistentClasses, collType, fkJoinColumns, keyColumns, inverseColumns, elementColumns, isEmbedded, property, unique, assocTableBinder, ignoreNotFound, mappings ); bindKeyFromAssociationTable( collType, persistentClasses, mapKeyPropertyName, property, isEmbedded, mappings, mapKeyColumns, mapKeyManyToManyColumns, inverseColumns != null ? inverseColumns[0].getPropertyName() : null ); } }; } private void bindKeyFromAssociationTable( XClass collType, Map persistentClasses, String mapKeyPropertyName, XProperty property, boolean isEmbedded, ExtendedMappings mappings, Ejb3Column[] mapKeyColumns, Ejb3JoinColumn[] mapKeyManyToManyColumns, String targetPropertyName ) { if ( mapKeyPropertyName != null ) { //this is an EJB3 @MapKey PersistentClass associatedClass = (PersistentClass) persistentClasses.get( collType.getName() ); if ( associatedClass == null ) throw new AnnotationException( "Associated class not found: " + collType ); Property mapProperty = BinderHelper.findPropertyByName( associatedClass, mapKeyPropertyName ); if ( mapProperty == null ) { throw new AnnotationException( "Map key property not found: " + collType + "." + mapKeyPropertyName ); } org.hibernate.mapping.Map map = (org.hibernate.mapping.Map) this.collection; Value indexValue = createFormulatedValue( mapProperty.getValue(), map, targetPropertyName, associatedClass ); map.setIndex( indexValue ); } else { //this is a true Map mapping //TODO ugly copy/pastle from CollectionBinder.bindManyToManySecondPass String mapKeyType; Class target = void.class; /* * target has priority over reflection for the map key type */ if ( property.isAnnotationPresent( org.hibernate.annotations.MapKey.class ) ) { target = property.getAnnotation( org.hibernate.annotations.MapKey.class ).targetElement(); } else if ( property.isAnnotationPresent( MapKeyManyToMany.class ) ) { target = property.getAnnotation( MapKeyManyToMany.class ).targetEntity(); } if ( !void.class.equals( target ) ) { mapKeyType = target.getName(); } else { mapKeyType = property.getMapKey().getName(); } PersistentClass collectionEntity = (PersistentClass) persistentClasses.get( mapKeyType ); boolean isIndexOfEntities = collectionEntity != null; ManyToOne element = null; org.hibernate.mapping.Map mapValue = (org.hibernate.mapping.Map) this.collection; if ( isIndexOfEntities ) { element = new ManyToOne( mapValue.getCollectionTable() ); mapValue.setIndex( element ); element.setReferencedEntityName( mapKeyType ); //element.setFetchMode( fetchMode ); //element.setLazy( fetchMode != FetchMode.JOIN ); //make the second join non lazy element.setFetchMode( FetchMode.JOIN ); element.setLazy( false ); //does not make sense for a map key element.setIgnoreNotFound( ignoreNotFound ); } else { XClass elementClass; AnnotatedClassType classType; // Map<String, javax.persistence.Column[]> columnOverrides = PropertyHolderBuilder.buildColumnOverride( // property, StringHelper.qualify( collValue.getRole(), "element" ) // ); //FIXME the "element" is lost PropertyHolder holder = null; if ( BinderHelper.PRIMITIVE_NAMES.contains( mapKeyType ) ) { classType = AnnotatedClassType.NONE; elementClass = null; } else { try { elementClass = mappings.getReflectionManager().classForName( mapKeyType, MapBinder.class ); } catch (ClassNotFoundException e) { throw new AnnotationException( "Unable to find class: " + mapKeyType, e ); } classType = mappings.getClassType( elementClass ); holder = PropertyHolderBuilder.buildPropertyHolder( mapValue, StringHelper.qualify( mapValue.getRole(), "mapkey" ), elementClass, property, propertyHolder, mappings ); //force in case of attribute override boolean attributeOverride = property.isAnnotationPresent( AttributeOverride.class ) || property.isAnnotationPresent( AttributeOverrides.class ); if ( isEmbedded || attributeOverride ) { classType = AnnotatedClassType.EMBEDDABLE; } } if ( AnnotatedClassType.EMBEDDABLE.equals( classType ) ) { EntityBinder entityBinder = new EntityBinder(); PersistentClass owner = mapValue.getOwner(); boolean isPropertyAnnotated; //FIXME support @Access for collection of elements //String accessType = access != null ? access.value() : null; if ( owner.getIdentifierProperty() != null ) { isPropertyAnnotated = owner.getIdentifierProperty() .getPropertyAccessorName() .equals( "property" ); } else if ( owner.getIdentifierMapper() != null && owner.getIdentifierMapper().getPropertySpan() > 0 ) { Property prop = (Property) owner.getIdentifierMapper().getPropertyIterator().next(); isPropertyAnnotated = prop.getPropertyAccessorName().equals( "property" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -