From 73f9df1bb573b2d2ac3587eae8f9f1b4a2adc806 Mon Sep 17 00:00:00 2001 From: Strong Liu Date: Mon, 26 Nov 2012 16:44:49 +0800 Subject: [PATCH] HHH-7736 - simple improvement and test fixing --- .../main/java/org/hibernate/LockOptions.java | 12 +- .../annotations/entity/EntityClass.java | 2 +- .../entity/AbstractEntityPersister.java | 184 +++------------ .../entity/LazyPropertyInitializerImpl.java | 219 ++++++++++++++++++ .../persister/CollectionPersister.java | 6 + .../persister/EntityPersister.java | 13 +- .../annotations/persister/PersisterTest.java | 27 ++- 7 files changed, 297 insertions(+), 166 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/entity/LazyPropertyInitializerImpl.java diff --git a/hibernate-core/src/main/java/org/hibernate/LockOptions.java b/hibernate-core/src/main/java/org/hibernate/LockOptions.java index a86b8b4f91..99a4c919c7 100644 --- a/hibernate-core/src/main/java/org/hibernate/LockOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/LockOptions.java @@ -65,7 +65,7 @@ public class LockOptions implements Serializable { private LockMode lockMode = LockMode.NONE; private int timeout = WAIT_FOREVER; - private Map aliasSpecificLockModes = null; //initialize lazily as LockOptions is frequently created without needing this + private Map aliasSpecificLockModes = null; //initialize lazily as LockOptions is frequently created without needing this public LockOptions() { } @@ -114,7 +114,7 @@ public class LockOptions implements Serializable { */ public LockOptions setAliasSpecificLockMode(String alias, LockMode lockMode) { if ( aliasSpecificLockModes == null ) { - aliasSpecificLockModes = new HashMap(); + aliasSpecificLockModes = new HashMap(); } aliasSpecificLockModes.put( alias, lockMode ); return this; @@ -135,7 +135,7 @@ public class LockOptions implements Serializable { if ( aliasSpecificLockModes == null ) { return null; } - return (LockMode) aliasSpecificLockModes.get( alias ); + return aliasSpecificLockModes.get( alias ); } /** @@ -176,9 +176,9 @@ public class LockOptions implements Serializable { * * @return Iterator for accessing the Map.Entry's */ - public Iterator getAliasLockIterator() { + public Iterator> getAliasLockIterator() { if ( aliasSpecificLockModes == null ) { - return Collections.emptyList().iterator(); + return Collections.emptyMap().entrySet().iterator(); } return aliasSpecificLockModes.entrySet().iterator(); } @@ -256,7 +256,7 @@ public class LockOptions implements Serializable { dest.setScope(from.getScope()); dest.setTimeOut(from.getTimeOut()); if ( from.aliasSpecificLockModes != null ) { - dest.aliasSpecificLockModes = new HashMap( from.aliasSpecificLockModes ); + dest.aliasSpecificLockModes = new HashMap( from.aliasSpecificLockModes ); } return dest; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java index 64b0cf0021..e8142eccbf 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java @@ -388,7 +388,7 @@ public class EntityClass extends ConfiguredClass { // Custom persister String entityPersisterClass = null; final AnnotationInstance persisterAnnotation = JandexHelper.getSingleAnnotation( - getClassInfo(), HibernateDotNames.PERSISTER + getClassInfo(), HibernateDotNames.PERSISTER, ClassInfo.class ); if ( persisterAnnotation != null && persisterAnnotation.value( "impl" ) != null ) { entityPersisterClass = persisterAnnotation.value( "impl" ).asString(); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index a96f091e8f..0d5fb64895 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -87,6 +87,7 @@ import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.FilterConfiguration; import org.hibernate.internal.FilterHelper; import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.ValueHolder; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.jdbc.Expectation; import org.hibernate.jdbc.Expectations; @@ -199,6 +200,7 @@ public abstract class AbstractEntityPersister //information about lazy properties of this class private final String[] lazyPropertyNames; private final int[] lazyPropertyNumbers; + private final Type[] lazyPropertyTypes; private final String[][] lazyPropertyColumnAliases; @@ -266,7 +268,7 @@ public abstract class AbstractEntityPersister protected ExecuteUpdateResultCheckStyle[] deleteResultCheckStyles; private InsertGeneratedIdentifierDelegate identityDelegate; - + private LazyPropertyInitializer lazyPropertyInitializerDelegater = new LazyPropertyInitializerImpl( this ); private boolean[] tableHasColumns; private final String loaderName; @@ -1204,147 +1206,11 @@ public abstract class AbstractEntityPersister ArrayHelper.toIntArray( formulaNumbers ) ); } - + @Override public Object initializeLazyProperty(String fieldName, Object entity, SessionImplementor session) throws HibernateException { + return lazyPropertyInitializerDelegater.initializeLazyProperty( fieldName, entity, session ); - final Serializable id = session.getContextEntityIdentifier( entity ); - - final EntityEntry entry = session.getPersistenceContext().getEntry( entity ); - if ( entry == null ) { - throw new HibernateException( "entity is not associated with the session: " + id ); - } - - if ( LOG.isTraceEnabled() ) { - LOG.tracev( "Initializing lazy properties of: {0}, field access: {1}", MessageHelper.infoString( this, id, getFactory() ), fieldName ); - } - - if ( hasCache() ) { - CacheKey cacheKey = session.generateCacheKey( id, getIdentifierType(), getEntityName() ); - Object ce = getCacheAccessStrategy().get( cacheKey, session.getTimestamp() ); - if (ce!=null) { - CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory); - if ( !cacheEntry.areLazyPropertiesUnfetched() ) { - //note early exit here: - return initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry ); - } - } - } - - return initializeLazyPropertiesFromDatastore( fieldName, entity, session, id, entry ); - - } - - private Object initializeLazyPropertiesFromDatastore( - final String fieldName, - final Object entity, - final SessionImplementor session, - final Serializable id, - final EntityEntry entry) { - - if ( !hasLazyProperties() ) { - throw new AssertionFailure( "no lazy properties" ); - } - - LOG.trace( "Initializing lazy properties from datastore" ); - - try { - - Object result = null; - PreparedStatement ps = null; - try { - final String lazySelect = getSQLLazySelectString(); - ResultSet rs = null; - try { - if ( lazySelect != null ) { - // null sql means that the only lazy properties - // are shared PK one-to-one associations which are - // handled differently in the Type#nullSafeGet code... - ps = session.getTransactionCoordinator() - .getJdbcCoordinator() - .getStatementPreparer() - .prepareStatement( lazySelect ); - getIdentifierType().nullSafeSet( ps, id, 1, session ); - rs = ps.executeQuery(); - rs.next(); - } - final Object[] snapshot = entry.getLoadedState(); - for ( int j = 0; j < lazyPropertyNames.length; j++ ) { - Object propValue = lazyPropertyTypes[j].nullSafeGet( rs, lazyPropertyColumnAliases[j], session, entity ); - if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) { - result = propValue; - } - } - } - finally { - if ( rs != null ) { - rs.close(); - } - } - } - finally { - if ( ps != null ) { - ps.close(); - } - } - - LOG.trace( "Done initializing lazy properties" ); - - return result; - - } - catch ( SQLException sqle ) { - throw getFactory().getSQLExceptionHelper().convert( - sqle, - "could not initialize lazy properties: " + - MessageHelper.infoString( this, id, getFactory() ), - getSQLLazySelectString() - ); - } - } - - private Object initializeLazyPropertiesFromCache( - final String fieldName, - final Object entity, - final SessionImplementor session, - final EntityEntry entry, - final CacheEntry cacheEntry - ) { - - LOG.trace( "Initializing lazy properties from second-level cache" ); - - Object result = null; - Serializable[] disassembledValues = cacheEntry.getDisassembledState(); - final Object[] snapshot = entry.getLoadedState(); - for ( int j = 0; j < lazyPropertyNames.length; j++ ) { - final Object propValue = lazyPropertyTypes[j].assemble( - disassembledValues[ lazyPropertyNumbers[j] ], - session, - entity - ); - if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) { - result = propValue; - } - } - - LOG.trace( "Done initializing lazy properties" ); - - return result; - } - - private boolean initializeLazyProperty( - final String fieldName, - final Object entity, - final SessionImplementor session, - final Object[] snapshot, - final int j, - final Object propValue) { - setPropertyValue( entity, lazyPropertyNumbers[j], propValue ); - if ( snapshot != null ) { - // object have been loaded with setReadOnly(true); HHH-2236 - snapshot[ lazyPropertyNumbers[j] ] = lazyPropertyTypes[j].deepCopy( propValue, factory ); - } - return fieldName.equals( lazyPropertyNames[j] ); } public boolean isBatchable() { @@ -3014,15 +2880,23 @@ public abstract class AbstractEntityPersister return identityDelegate.performInsert( sql, session, binder ); } + private ValueHolder identitySelectStringValue = new ValueHolder( + new ValueHolder.DeferredInitializer() { + @Override + public String initialize() { + return getFactory().getDialect().getIdentitySelectString( + getTableName( 0 ), + getKeyColumns( 0 )[0], + getIdentifierType().sqlTypes( getFactory() )[0] + ); + } + } + ); + @Override public String getIdentitySelectString() { - //TODO: cache this in an instvar - return getFactory().getDialect().getIdentitySelectString( - getTableName(0), - getKeyColumns(0)[0], - getIdentifierType().sqlTypes( getFactory() )[0] - ); + return identitySelectStringValue.getValue(); } - + @Override public String getSelectByUniqueKeyString(String propertyName) { return new SimpleSelect( getFactory().getDialect() ) .setTableName( getTableName(0) ) @@ -5024,5 +4898,21 @@ public abstract class AbstractEntityPersister public int determineTableNumberForColumn(String columnName) { return 0; } - + + + Type[] getLazyPropertyTypes() { + return lazyPropertyTypes; + } + + int[] getLazyPropertyNumbers() { + return lazyPropertyNumbers; + } + + String[] getLazyPropertyNames() { + return lazyPropertyNames; + } + + String[][] getLazyPropertyColumnAliases() { + return lazyPropertyColumnAliases; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/LazyPropertyInitializerImpl.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/LazyPropertyInitializerImpl.java new file mode 100644 index 0000000000..b0c10b03f4 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/LazyPropertyInitializerImpl.java @@ -0,0 +1,219 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, 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.persister.entity; + +import java.io.Serializable; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.jboss.logging.Logger; + +import org.hibernate.AssertionFailure; +import org.hibernate.HibernateException; +import org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer; +import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.entry.CacheEntry; +import org.hibernate.engine.spi.EntityEntry; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.pretty.MessageHelper; + +/** + * @author Strong Liu + */ +class LazyPropertyInitializerImpl implements LazyPropertyInitializer { + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + AbstractEntityPersister.class.getName() + ); + private final AbstractEntityPersister entityPersister; + + LazyPropertyInitializerImpl(AbstractEntityPersister entityPersister) { + this.entityPersister = entityPersister; + } + + @Override + public Object initializeLazyProperty(String fieldName, Object entity, SessionImplementor session) + throws HibernateException { + + final Serializable id = session.getContextEntityIdentifier( entity ); + + final EntityEntry entry = session.getPersistenceContext().getEntry( entity ); + if ( entry == null ) { + throw new HibernateException( "entity is not associated with the session: " + id ); + } + + if ( LOG.isTraceEnabled() ) { + LOG.tracev( + "Initializing lazy properties of: {0}, field access: {1}", MessageHelper.infoString( + entityPersister, + id, + entityPersister.getFactory() + ), fieldName + ); + } + + if ( entityPersister.hasCache() ) { + CacheKey cacheKey = session.generateCacheKey( + id, + entityPersister.getIdentifierType(), + entityPersister.getEntityName() + ); + Object ce = entityPersister.getCacheAccessStrategy().get( cacheKey, session.getTimestamp() ); + if ( ce != null ) { + CacheEntry cacheEntry = (CacheEntry) entityPersister.getCacheEntryStructure() + .destructure( ce, entityPersister.getFactory() ); + if ( !cacheEntry.areLazyPropertiesUnfetched() ) { + //note early exit here: + return initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry ); + } + } + } + + return initializeLazyPropertiesFromDatastore( fieldName, entity, session, id, entry ); + + } + + private Object initializeLazyPropertiesFromDatastore( + final String fieldName, + final Object entity, + final SessionImplementor session, + final Serializable id, + final EntityEntry entry) { + + if ( !entityPersister.hasLazyProperties() ) { + throw new AssertionFailure( "no lazy properties" ); + } + + LOG.trace( "Initializing lazy properties from datastore" ); + + try { + + Object result = null; + PreparedStatement ps = null; + try { + final String lazySelect = entityPersister.getSQLLazySelectString(); + ResultSet rs = null; + try { + if ( lazySelect != null ) { + // null sql means that the only lazy properties + // are shared PK one-to-one associations which are + // handled differently in the Type#nullSafeGet code... + ps = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( lazySelect ); + entityPersister.getIdentifierType().nullSafeSet( ps, id, 1, session ); + rs = ps.executeQuery(); + rs.next(); + } + final Object[] snapshot = entry.getLoadedState(); + for ( int j = 0; j < entityPersister.getLazyPropertyNames().length; + j++ ) { + Object propValue = entityPersister.getLazyPropertyTypes()[j].nullSafeGet( + rs, + entityPersister.getLazyPropertyColumnAliases()[j], + session, + entity + ); + if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) { + result = propValue; + } + } + } + finally { + if ( rs != null ) { + rs.close(); + } + } + } + finally { + if ( ps != null ) { + ps.close(); + } + } + + LOG.trace( "Done initializing lazy properties" ); + + return result; + + } + catch ( SQLException sqle ) { + throw entityPersister.getFactory().getSQLExceptionHelper().convert( + sqle, + "could not initialize lazy properties: " + + MessageHelper.infoString( entityPersister, id, entityPersister.getFactory() ), + entityPersister.getSQLLazySelectString() + ); + } + } + + private Object initializeLazyPropertiesFromCache( + final String fieldName, + final Object entity, + final SessionImplementor session, + final EntityEntry entry, + final CacheEntry cacheEntry + ) { + + LOG.trace( "Initializing lazy properties from second-level cache" ); + + Object result = null; + Serializable[] disassembledValues = cacheEntry.getDisassembledState(); + final Object[] snapshot = entry.getLoadedState(); + for ( int j = 0; j < entityPersister.getLazyPropertyNames().length; j++ ) { + final Object propValue = entityPersister.getLazyPropertyTypes()[j].assemble( + disassembledValues[entityPersister.getLazyPropertyNumbers()[j]], + session, + entity + ); + if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) { + result = propValue; + } + } + + LOG.trace( "Done initializing lazy properties" ); + + return result; + } + + private boolean initializeLazyProperty( + final String fieldName, + final Object entity, + final SessionImplementor session, + final Object[] snapshot, + final int j, + final Object propValue) { + entityPersister.setPropertyValue( entity, entityPersister.getLazyPropertyNumbers()[j], propValue ); + if ( snapshot != null ) { + // object have been loaded with setReadOnly(true); HHH-2236 + snapshot[entityPersister.getLazyPropertyNumbers()[j]] = entityPersister.getLazyPropertyTypes()[j].deepCopy( + propValue, + entityPersister.getFactory() + ); + } + return fieldName.equals( entityPersister.getLazyPropertyNames()[j] ); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/persister/CollectionPersister.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/persister/CollectionPersister.java index 33c9ad34ec..a10cd25fcb 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/persister/CollectionPersister.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/persister/CollectionPersister.java @@ -5,6 +5,7 @@ import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cfg.Configuration; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.mapping.Collection; +import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding; import org.hibernate.persister.collection.OneToManyPersister; /** @@ -16,4 +17,9 @@ public class CollectionPersister extends OneToManyPersister { SessionFactoryImplementor factory) throws MappingException, CacheException { super( collection, cache, factory ); } + + public CollectionPersister(AbstractPluralAttributeBinding collection, CollectionRegionAccessStrategy cacheAccessStrategy, SessionFactoryImplementor factory) + throws MappingException, CacheException { + super( collection, cacheAccessStrategy, factory ); + } } \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/persister/EntityPersister.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/persister/EntityPersister.java index 2fdf9c0fbf..314ff61eff 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/persister/EntityPersister.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/persister/EntityPersister.java @@ -1,20 +1,27 @@ package org.hibernate.test.annotations.persister; + import org.hibernate.HibernateException; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.engine.spi.Mapping; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.mapping.PersistentClass; +import org.hibernate.metamodel.spi.binding.EntityBinding; import org.hibernate.persister.entity.SingleTableEntityPersister; /** * @author Shawn Clowater */ public class EntityPersister extends SingleTableEntityPersister { - @SuppressWarnings( {"UnusedDeclaration"}) + @SuppressWarnings({ "UnusedDeclaration" }) public EntityPersister(PersistentClass persistentClass, EntityRegionAccessStrategy cache, - NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy, - SessionFactoryImplementor factory, Mapping cfg) throws HibernateException { + NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy, + SessionFactoryImplementor factory, Mapping cfg) throws HibernateException { super( persistentClass, cache, naturalIdRegionAccessStrategy, factory, cfg ); } + + public EntityPersister(EntityBinding entityBinding, EntityRegionAccessStrategy cacheAccessStrategy, NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy, SessionFactoryImplementor factory, Mapping mapping) + throws HibernateException { + super( entityBinding, cacheAccessStrategy, naturalIdRegionAccessStrategy, factory, mapping ); + } } \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/persister/PersisterTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/persister/PersisterTest.java index 86424c1d00..876ba5f9f8 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/persister/PersisterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/persister/PersisterTest.java @@ -23,12 +23,13 @@ */ package org.hibernate.test.annotations.persister; +import java.util.Iterator; + import org.junit.Test; -import org.hibernate.mapping.Collection; +import org.hibernate.metamodel.spi.binding.PluralAttributeBinding; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.SingleTableEntityPersister; -import org.hibernate.testing.FailureExpectedWithNewMetamodel; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import static org.junit.Assert.assertEquals; @@ -36,14 +37,13 @@ import static org.junit.Assert.assertEquals; /** * @author Shawn Clowater */ -@FailureExpectedWithNewMetamodel public class PersisterTest extends BaseCoreFunctionalTestCase { @Test public void testEntityEntityPersisterAndPersisterSpecified() throws Exception { //checks to see that the persister specified with the @Persister annotation takes precedence if a @Entity.persister() is also specified Class clazz = getEntityBinding( Deck.class ).getCustomEntityPersisterClass(); assertEquals( "Incorrect Persister class for " + Deck.class.getName(), - EntityPersister.class, clazz ); + org.hibernate.test.annotations.persister.EntityPersister.class, clazz ); } @Test @@ -56,11 +56,20 @@ public class PersisterTest extends BaseCoreFunctionalTestCase { @Test public void testCollectionPersisterSpecified() throws Exception { - // TODO: use getCollectionBindings() - //tests the persister specified by the @Persister annotation on a collection - Collection collection = configuration().getCollectionMapping( Deck.class.getName() + ".cards" ); - assertEquals( "Incorrect Persister class for collection " + collection.getRole(), CollectionPersister.class, - collection.getCollectionPersisterClass() ); + String expectedRole = Deck.class.getName() + ".cards"; + Iterator collectionBindings = getCollectionBindings(); + while ( collectionBindings.hasNext() ) { + PluralAttributeBinding attributeBinding = collectionBindings.next(); + String role = attributeBinding.getAttribute().getRole(); + //tests the persister specified by the @Persister annotation on a collection + if ( expectedRole.equals( role ) ) { + assertEquals( + "Incorrect Persister class for collection " + role, CollectionPersister.class, + attributeBinding.getExplicitPersisterClass() + ); + break; + } + } } @Override