private static void bindPojoRepresentation(Element node, PersistentClass entity, Mappings mappings, java.util.Map metaTags) { String className = getClassName( node.attribute( "name" ), mappings ); String proxyName = getClassName( node.attribute( "proxy" ), mappings ); entity.setClassName( className ); if ( proxyName != null ) { entity.setProxyInterfaceName( proxyName ); entity.setLazy( true ); } else if ( entity.isLazy() ) { entity.setProxyInterfaceName( className ); } Element tuplizer = locateTuplizerDefinition( node, EntityMode.POJO ); if ( tuplizer != null ) { entity.addTuplizer( EntityMode.POJO, tuplizer.attributeValue( "class" ) ); } }
public ComponentMetamodel(Component component) { // this.sessionFactory = sessionFactory; this.role = component.getRoleName(); this.isKey = component.isKey(); propertySpan = component.getPropertySpan(); properties = new StandardProperty[propertySpan]; Iterator itr = component.getPropertyIterator(); int i = 0; while ( itr.hasNext() ) { Property property = ( Property ) itr.next(); properties[i] = PropertyFactory.buildStandardProperty( property, false ); propertyIndexes.put( property.getName(), i ); i++; } entityMode = component.hasPojoRepresentation() ? EntityMode.POJO : EntityMode.MAP; // todo : move this to SF per HHH-3517; also see HHH-1907 and ComponentMetamodel final ComponentTuplizerFactory componentTuplizerFactory = new ComponentTuplizerFactory(); final String tuplizerClassName = component.getTuplizerImplClassName( entityMode ); this.componentTuplizer = tuplizerClassName == null ? componentTuplizerFactory.constructDefaultTuplizer( entityMode, component ) : componentTuplizerFactory.constructTuplizer( tuplizerClassName, component ); }
/** * @deprecated the tenantId and entityMode parameters where removed: this constructor accepts but ignores them. * Use the other constructor! */ @Deprecated public EntityEntry( final Status status, final Object[] loadedState, final Object rowId, final Serializable id, final Object version, final LockMode lockMode, final boolean existsInDatabase, final EntityPersister persister, final EntityMode entityMode, final String tenantId, final boolean disableVersionIncrement, final boolean lazyPropertiesAreUnfetched, final PersistenceContext persistenceContext) { this( status, loadedState, rowId, id, version, lockMode, existsInDatabase, persister,disableVersionIncrement, lazyPropertiesAreUnfetched, persistenceContext ); }
@Override Object processComponent(Object component, CompositeType componentType) throws HibernateException { if ( component != null ) { Object[] values = componentType.getPropertyValues( component, getSession() ); Type[] types = componentType.getSubtypes(); boolean substituteComponent = false; for ( int i = 0; i < types.length; i++ ) { Object result = processValue( values[i], types[i] ); if ( result != null ) { values[i] = result; substituteComponent = true; } } if ( substituteComponent ) { componentType.setPropertyValues( component, values, EntityMode.POJO ); } } return null; }
/** * Binds the specified persistant class to the runtime model based on the * properties defined in the domain class * * @param domainClass The Grails domain class * @param persistentClass The persistant class * @param mappings Existing mappings */ protected void bindClass(PersistentEntity domainClass, PersistentClass persistentClass, InFlightMetadataCollector mappings) { // set lazy loading for now persistentClass.setLazy(true); final String entityName = domainClass.getName(); persistentClass.setEntityName(entityName); persistentClass.setJpaEntityName(unqualify(entityName)); persistentClass.setProxyInterfaceName(entityName); persistentClass.setClassName(entityName); persistentClass.addTuplizer(EntityMode.POJO, GroovyAwarePojoEntityTuplizer.class.getName()); // set dynamic insert to false persistentClass.setDynamicInsert(false); // set dynamic update to false persistentClass.setDynamicUpdate(false); // set select before update to false persistentClass.setSelectBeforeUpdate(false); // add import to mappings String en = persistentClass.getEntityName(); if (mappings.getMetadataBuildingOptions().getMappingDefaults().isAutoImportEnabled() && en.indexOf('.') > 0) { String unqualified = unqualify(en); mappings.addImport(unqualified, en); } }
@Override public void write(ObjectDataOutput out, CacheKey object) throws IOException { try { Object key = UNSAFE.getObject(object, KEY_OFFSET); Type type = (Type) UNSAFE.getObject(object, TYPE_OFFSET); String entityOrRoleName = (String) UNSAFE.getObject(object, ENTITY_OR_ROLE_NAME_OFFSET); EntityMode entityMode = (EntityMode) UNSAFE.getObject(object, ENTITY_MODE_OFFSET); int hashCode = UNSAFE.getInt(object, HASH_CODE_OFFSET); out.writeObject(key); out.writeObject(type); out.writeUTF(entityOrRoleName); out.writeUTF(entityMode.toString()); out.writeInt(hashCode); } catch (Exception e) { if (e instanceof IOException) { throw (IOException) e; } throw new IOException(e); } }
@Override public CacheKey read(ObjectDataInput in) throws IOException { try { Object key = in.readObject(); Type type = in.readObject(); String entityOrRoleName = in.readUTF(); EntityMode entityMode = EntityMode.parse(in.readUTF()); int hashCode = in.readInt(); CacheKey cacheKey = (CacheKey) UNSAFE.allocateInstance(CacheKey.class); UNSAFE.putObjectVolatile(cacheKey, KEY_OFFSET, key); UNSAFE.putObjectVolatile(cacheKey, TYPE_OFFSET, type); UNSAFE.putObjectVolatile(cacheKey, ENTITY_OR_ROLE_NAME_OFFSET, entityOrRoleName); UNSAFE.putObjectVolatile(cacheKey, ENTITY_MODE_OFFSET, entityMode); UNSAFE.putIntVolatile(cacheKey, HASH_CODE_OFFSET, hashCode); return cacheKey; } catch (Exception e) { if (e instanceof IOException) { throw (IOException) e; } throw new IOException(e); } }
public static Set createFilterKeys(Map enabledFilters, EntityMode entityMode) { if ( enabledFilters.size()==0 ) return null; Set result = new HashSet(); Iterator iter = enabledFilters.values().iterator(); while ( iter.hasNext() ) { FilterImpl filter = (FilterImpl) iter.next(); FilterKey key = new FilterKey( filter.getName(), filter.getParameters(), filter.getFilterDefinition().getParameterTypes(), entityMode ); result.add(key); } return result; }
protected static boolean isCached( PersistenceContext context, Serializable collectionKey, CollectionPersister persister, EntityMode entityMode) { if ( persister.hasCache() ) { CacheKey cacheKey = new CacheKey( collectionKey, persister.getKeyType(), persister.getRole(), entityMode, context.getSession().getFactory() ); return persister.getCacheAccessStrategy().get( cacheKey, context.getSession().getTimestamp() ) != null; } return false; }
public void update(String entityName, Object entity) { errorIfClosed(); EntityPersister persister = getEntityPersister(entityName, entity); Serializable id = persister.getIdentifier(entity, EntityMode.POJO); Object[] state = persister.getPropertyValues(entity, EntityMode.POJO); Object oldVersion; if ( persister.isVersioned() ) { oldVersion = persister.getVersion(entity, EntityMode.POJO); Object newVersion = Versioning.increment( oldVersion, persister.getVersionType(), this ); Versioning.setVersion(state, newVersion, persister); persister.setPropertyValues(entity, state, EntityMode.POJO); } else { oldVersion = null; } persister.update(id, state, null, false, null, oldVersion, entity, null, this); }
public Serializable getSnapshot(CollectionPersister persister) throws HibernateException { EntityMode entityMode = getSession().getEntityMode(); HashMap map = new HashMap( values.size() ); Iterator iter = values.iterator(); int i=0; while ( iter.hasNext() ) { Object value = iter.next(); map.put( identifiers.get( new Integer(i++) ), persister.getElementType().deepCopy(value, entityMode, persister.getFactory()) ); } return map; }
public Object deepCopy(Object component, EntityMode entityMode, SessionFactoryImplementor factory) throws HibernateException { if ( component == null ) { return null; } Object[] values = getPropertyValues( component, entityMode ); for ( int i = 0; i < propertySpan; i++ ) { values[i] = propertyTypes[i].deepCopy( values[i], entityMode, factory ); } Object result = instantiate( entityMode ); setPropertyValues( result, values, entityMode ); //not absolutely necessary, but helps for some //equals()/hashCode() implementations ComponentTuplizer ct = ( ComponentTuplizer ) tuplizerMapping.getTuplizer( entityMode ); if ( ct.hasParentProperty() ) { ct.setParent( result, ct.getParent( component ), factory ); } return result; }
private boolean isCached( EntityKey entityKey, EntityPersister persister, EntityMode entityMode) { if ( persister.hasCache() ) { CacheKey key = new CacheKey( entityKey.getIdentifier(), persister.getIdentifierType(), entityKey.getEntityName(), entityMode, context.getSession().getFactory() ); return persister.getCache().getCache().get( key ) != null; } return false; }
/** * Custom deserialization routine used during deserialization of a * Session/PersistenceContext for increased performance. * * @param ois The stream from which to read the entry. * @param session The session being deserialized. * @return The deserialized EntityEntry * @throws IOException * @throws ClassNotFoundException */ static EntityEntry deserialize( ObjectInputStream ois, SessionImplementor session) throws IOException, ClassNotFoundException { return new EntityEntry( session.getFactory(), ( String ) ois.readObject(), ( Serializable ) ois.readObject(), EntityMode.parse( ( String ) ois.readObject() ), Status.parse( ( String ) ois.readObject() ), ( Object[] ) ois.readObject(), ( Object[] ) ois.readObject(), ( Object ) ois.readObject(), LockMode.parse( ( String ) ois.readObject() ), ois.readBoolean(), ois.readBoolean(), ois.readBoolean() ); }
private static void bindMapRepresentation(Element node, PersistentClass entity, Mappings mappings, java.util.Map inheritedMetas) { Element tuplizer = locateTuplizerDefinition( node, EntityMode.MAP ); if ( tuplizer != null ) { entity.addTuplizer( EntityMode.MAP, tuplizer.attributeValue( "class" ) ); } }
/** * Locate any explicit tuplizer definition in the metadata, for the given entity-mode. * * @param container The containing element (representing the entity/component) * @param entityMode The entity-mode for which to locate the tuplizer element * @return The tuplizer element, or null. */ private static Element locateTuplizerDefinition(Element container, EntityMode entityMode) { Iterator itr = container.elements( "tuplizer" ).iterator(); while( itr.hasNext() ) { final Element tuplizerElem = ( Element ) itr.next(); if ( entityMode.toString().equals( tuplizerElem.attributeValue( "entity-mode") ) ) { return tuplizerElem; } } return null; }
public String getTuplizerImplClassName(EntityMode mode) { // todo : remove this once ComponentMetamodel is complete and merged if ( tuplizerImpls == null ) { return null; } return tuplizerImpls.get( mode ); }
public String getTuplizerImplClassName(EntityMode mode) { String impl = super.getTuplizerImplClassName( mode ); if ( impl == null ) { impl = getSuperclass().getTuplizerImplClassName( mode ); } return impl; }
@Override public String getCustomTuplizerClassName() { if ( entityElement.getTuplizer() == null ) { return null; } final EntityMode entityMode = determineEntityMode(); for ( JaxbTuplizerElement tuplizerElement : entityElement.getTuplizer() ) { if ( entityMode == EntityMode.parse( tuplizerElement.getEntityMode() ) ) { return tuplizerElement.getClazz(); } } return null; }
@Override public String getExplicitTuplizerClassName() { if ( componentElement.getTuplizer() == null ) { return null; } final EntityMode entityMode = StringHelper.isEmpty( componentElement.getClazz() ) ? EntityMode.MAP : EntityMode.POJO; for ( JaxbTuplizerElement tuplizerElement : componentElement.getTuplizer() ) { if ( entityMode == EntityMode.parse( tuplizerElement.getEntityMode() ) ) { return tuplizerElement.getClazz(); } } return null; }
@Override public String getExplicitTuplizerClassName() { if ( compositeElement.getTuplizer() == null ) { return null; } final EntityMode entityMode = StringHelper.isEmpty( compositeElement.getClazz() ) ? EntityMode.MAP : EntityMode.POJO; for ( JaxbTuplizerElement tuplizerElement : compositeElement.getTuplizer() ) { if ( entityMode == EntityMode.parse( tuplizerElement.getEntityMode() ) ) { return tuplizerElement.getClazz(); } } return null; }
private String determineCustomTuplizer() { final AnnotationInstance tuplizersAnnotation = JandexHelper.getSingleAnnotation( classInfo, HibernateDotNames.TUPLIZERS ); if ( tuplizersAnnotation == null ) { return null; } AnnotationInstance[] annotations = JandexHelper.getValue( tuplizersAnnotation, "value", AnnotationInstance[].class ); AnnotationInstance pojoTuplizerAnnotation = null; for ( AnnotationInstance tuplizerAnnotation : annotations ) { if ( EntityMode.valueOf( tuplizerAnnotation.value( "entityModeType" ).asEnum() ) == EntityMode.POJO ) { pojoTuplizerAnnotation = tuplizerAnnotation; break; } } String customTuplizer = null; if ( pojoTuplizerAnnotation != null ) { customTuplizer = pojoTuplizerAnnotation.value( "impl" ).asString(); } return customTuplizer; }
private EntityMode getEntityMode(Criteria criteria, CriteriaQuery criteriaQuery) { final EntityPersister meta = criteriaQuery.getFactory().getEntityPersister( criteriaQuery.getEntityName( criteria ) ); final EntityMode result = meta.getEntityMode(); if ( ! meta.getEntityMetamodel().getTuplizer().isInstance( exampleEntity ) ) { throw new ClassCastException( exampleEntity.getClass().getName() ); } return result; }
/** * Retrieves a PropertyAccessor instance based on the given property definition and * entity mode. * * @param property The property for which to retrieve an accessor. * @param mode The mode for the resulting entity. * @return An appropriate accessor. * @throws MappingException */ public static PropertyAccessor getPropertyAccessor(Property property, EntityMode mode) throws MappingException { //TODO: this is temporary in that the end result will probably not take a Property reference per-se. if ( null == mode || EntityMode.POJO.equals( mode ) ) { return getPojoPropertyAccessor( property.getPropertyAccessorName() ); } else if ( EntityMode.MAP.equals( mode ) ) { return getDynamicMapPropertyAccessor(); } else { throw new MappingException( "Unknown entity mode [" + mode + "]" ); } }
/** * Retrieves a PropertyAccessor instance based on the given property definition and * entity mode. * * @param property The property for which to retrieve an accessor. * @param mode The mode for the resulting entity. * @return An appropriate accessor. * @throws MappingException */ public static PropertyAccessor getPropertyAccessor(AttributeBinding property, EntityMode mode) throws MappingException { //TODO: this is temporary in that the end result will probably not take a Property reference per-se. if ( null == mode || EntityMode.POJO.equals( mode ) ) { return getPojoPropertyAccessor( property.getPropertyAccessorName() ); } else if ( EntityMode.MAP.equals( mode ) ) { return getDynamicMapPropertyAccessor(); } else { throw new MappingException( "Unknown entity mode [" + mode + "]" ); } }
public Object nullSafeGet( ResultSet rs, String name, SessionImplementor session, Object owner) throws HibernateException, SQLException { final Object discriminatorValue = underlyingType.nullSafeGet( rs, name, session, owner ); final String entityName = persister.getSubclassForDiscriminatorValue( discriminatorValue ); if ( entityName == null ) { throw new HibernateException( "Unable to resolve discriminator value [" + discriminatorValue + "] to entity name" ); } final EntityPersister entityPersister = session.getEntityPersister( entityName, null ); return ( EntityMode.POJO == entityPersister.getEntityMode() ) ? entityPersister.getMappedClass() : entityName; }
/** * Method allowing registration of the tuplizer class to use as default for a particular entity-mode. * * @param entityMode The entity-mode for which to register the tuplizer class * @param tuplizerClass The class to use as the default tuplizer for the given entity-mode. */ public void registerDefaultTuplizerClass(EntityMode entityMode, Class<? extends EntityTuplizer> tuplizerClass) { assert isEntityTuplizerImplementor( tuplizerClass ) : "Specified tuplizer class [" + tuplizerClass.getName() + "] does not implement " + EntityTuplizer.class.getName(); // TODO: for now we need constructors for both PersistentClass and EntityBinding assert hasProperConstructor( tuplizerClass, ENTITY_TUP_CTOR_SIG ) : "Specified tuplizer class [" + tuplizerClass.getName() + "] is not properly instantiatable"; assert hasProperConstructor( tuplizerClass, ENTITY_TUP_CTOR_SIG_NEW ) : "Specified tuplizer class [" + tuplizerClass.getName() + "] is not properly instantiatable"; defaultImplClassByMode.put( entityMode, tuplizerClass ); }
@Override public Object getIdentifier(Object entity, EntityMode entityMode, SessionImplementor session) { Object id = mappedIdentifierType.instantiate( entityMode ); final Object[] propertyValues = virtualIdComponent.getPropertyValues( entity, entityMode ); mappedIdentifierType.setPropertyValues( id, propertyValues, entityMode ); return id; }
@Override public void setIdentifier(Object entity, Serializable id, EntityMode entityMode, SessionImplementor session) { virtualIdComponent.setPropertyValues( entity, mappedIdentifierType.getPropertyValues( id, session ), entityMode ); }
@Override public void setIdentifier(Object entity, Serializable id, EntityMode entityMode, SessionImplementor session) { final Object[] extractedValues = mappedIdentifierType.getPropertyValues( id, entityMode ); final Object[] injectionValues = new Object[ extractedValues.length ]; final PersistenceContext persistenceContext = session.getPersistenceContext(); for ( int i = 0; i < virtualIdComponent.getSubtypes().length; i++ ) { final Type virtualPropertyType = virtualIdComponent.getSubtypes()[i]; final Type idClassPropertyType = mappedIdentifierType.getSubtypes()[i]; if ( virtualPropertyType.isEntityType() && ! idClassPropertyType.isEntityType() ) { if ( session == null ) { throw new AssertionError( "Deprecated version of getIdentifier (no session) was used but session was required" ); } final String associatedEntityName = ( (EntityType) virtualPropertyType ).getAssociatedEntityName(); final EntityKey entityKey = session.generateEntityKey( (Serializable) extractedValues[i], session.getFactory().getEntityPersister( associatedEntityName ) ); // it is conceivable there is a proxy, so check that first Object association = persistenceContext.getProxy( entityKey ); if ( association == null ) { // otherwise look for an initialized version association = persistenceContext.getEntity( entityKey ); } injectionValues[i] = association; } else { injectionValues[i] = extractedValues[i]; } } virtualIdComponent.setPropertyValues( entity, injectionValues, entityMode ); }
/** * Method allowing registration of the tuplizer class to use as default for a particular entity-mode. * * @param entityMode The entity-mode for which to register the tuplizer class * @param tuplizerClass The class to use as the default tuplizer for the given entity-mode. */ @SuppressWarnings({ "UnusedDeclaration" }) public void registerDefaultTuplizerClass(EntityMode entityMode, Class<? extends ComponentTuplizer> tuplizerClass) { assert isComponentTuplizerImplementor( tuplizerClass ) : "Specified tuplizer class [" + tuplizerClass.getName() + "] does not implement " + ComponentTuplizer.class.getName(); assert hasProperConstructor( tuplizerClass ) : "Specified tuplizer class [" + tuplizerClass.getName() + "] is not properly instantiatable"; defaultImplClassByMode.put( entityMode, tuplizerClass ); }
private static Getter getGetter(Property mappingProperty) { if ( mappingProperty == null || !mappingProperty.getPersistentClass().hasPojoRepresentation() ) { return null; } PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( mappingProperty, EntityMode.POJO ); return pa.getGetter( mappingProperty.getPersistentClass().getMappedClass(), mappingProperty.getName() ); }
private static Getter getGetter(AttributeBinding mappingProperty) { if ( mappingProperty == null || mappingProperty.getContainer().getClassReference() == null ) { return null; } PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( mappingProperty, EntityMode.POJO ); return pa.getGetter( mappingProperty.getContainer().getClassReference(), mappingProperty.getAttribute().getName() ); }
private CollectionKey( String role, Serializable key, Type keyType, EntityMode entityMode, SessionFactoryImplementor factory) { this.role = role; this.key = key; this.keyType = keyType; this.entityMode = entityMode; this.factory = factory; //cache the hash-code this.hashCode = generateHashCode(); }
/** * Get a batch of unloaded identifiers for this class, using a slightly * complex algorithm that tries to grab keys registered immediately after * the given key. * * @param persister The persister for the entities being loaded. * @param id The identifier of the entity currently demanding load. * @param batchSize The maximum number of keys to return * @return an array of identifiers, of length batchSize (possibly padded with nulls) */ public Serializable[] getEntityBatch( final EntityPersister persister, final Serializable id, final int batchSize, final EntityMode entityMode) { Serializable[] ids = new Serializable[batchSize]; ids[0] = id; //first element of array is reserved for the actual instance we are loading! int i = 1; int end = -1; boolean checkForEnd = false; // TODO: this needn't exclude subclasses... LinkedHashSet<EntityKey> set = batchLoadableEntityKeys.get( persister.getEntityName() ); if ( set != null ) { for ( EntityKey key : set ) { if ( checkForEnd && i == end ) { //the first id found after the given id return ids; } if ( persister.getIdentifierType().isEqual( id, key.getIdentifier() ) ) { end = i; } else { if ( !isCached( key, persister ) ) { ids[i++] = key.getIdentifier(); } } if ( i == batchSize ) { i = 1; // end of array, start filling again from start if ( end != -1 ) { checkForEnd = true; } } } } return ids; //we ran out of ids to try }
public EntityUniqueKey( final String entityName, final String uniqueKeyName, final Object semiResolvedKey, final Type keyType, final EntityMode entityMode, final SessionFactoryImplementor factory) { this.uniqueKeyName = uniqueKeyName; this.entityName = entityName; this.key = semiResolvedKey; this.keyType = keyType.getSemiResolvedType( factory ); this.entityMode = entityMode; this.hashCode = generateHashCode( factory ); }
/** * Custom deserialization routine used during deserialization of a * Session/PersistenceContext for increased performance. * * @param ois The stream from which to read the entry. * @param session The session being deserialized. * * @return The deserialized EntityEntry * * @throws IOException * @throws ClassNotFoundException */ public static EntityUniqueKey deserialize( ObjectInputStream ois, SessionImplementor session) throws IOException, ClassNotFoundException { return new EntityUniqueKey( (String) ois.readObject(), (String) ois.readObject(), ois.readObject(), (Type) ois.readObject(), (EntityMode) ois.readObject(), session.getFactory() ); }
/** * Return null if the argument is an "unsaved" entity (ie. one with no existing database row), or the * input argument otherwise. This is how Hibernate avoids foreign key constraint violations. * * @param value An entity attribute value * @param type An entity attribute type * * @return {@code null} if the argument is an unsaved entity; otherwise return the argument. */ private Object nullifyTransientReferences(final Object value, final Type type) { if ( value == null ) { return null; } else if ( type.isEntityType() ) { final EntityType entityType = (EntityType) type; if ( entityType.isOneToOne() ) { return value; } else { final String entityName = entityType.getAssociatedEntityName(); return isNullifiable( entityName, value ) ? null : value; } } else if ( type.isAnyType() ) { return isNullifiable( null, value ) ? null : value; } else if ( type.isComponentType() ) { final CompositeType actype = (CompositeType) type; final Object[] subvalues = actype.getPropertyValues( value, session ); final Type[] subtypes = actype.getSubtypes(); boolean substitute = false; for ( int i = 0; i < subvalues.length; i++ ) { final Object replacement = nullifyTransientReferences( subvalues[i], subtypes[i] ); if ( replacement != subvalues[i] ) { substitute = true; subvalues[i] = replacement; } } if ( substitute ) { // todo : need to account for entity mode on the CompositeType interface :( actype.setPropertyValues( value, subvalues, EntityMode.POJO ); } return value; } else { return value; } }
@SuppressWarnings({"unchecked", "UnusedParameters"}) protected Serializable snapshot(BasicCollectionPersister persister, EntityMode entityMode) throws HibernateException { final TreeMap clonedSet = new TreeMap( comparator ); for ( Object setElement : set ) { final Object copy = persister.getElementType().deepCopy( setElement, persister.getFactory() ); clonedSet.put( copy, copy ); } return clonedSet; }
@SuppressWarnings({"unchecked", "UnusedParameters"}) protected Serializable snapshot(BasicCollectionPersister persister, EntityMode entityMode) throws HibernateException { final TreeMap clonedMap = new TreeMap( comparator ); for ( Object o : map.entrySet() ) { final Entry e = (Entry) o; clonedMap.put( e.getKey(), persister.getElementType().deepCopy( e.getValue(), persister.getFactory() ) ); } return clonedMap; }