diff --git a/hibernate-core/src/main/java/org/hibernate/SessionFactory.java b/hibernate-core/src/main/java/org/hibernate/SessionFactory.java
index af932e6393..68e109e913 100644
--- a/hibernate-core/src/main/java/org/hibernate/SessionFactory.java
+++ b/hibernate-core/src/main/java/org/hibernate/SessionFactory.java
@@ -32,6 +32,7 @@ import java.util.Set;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
+import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.stat.Statistics;
/**
@@ -51,6 +52,14 @@ import org.hibernate.stat.Statistics;
* @author Steve Ebersole
*/
public interface SessionFactory extends Referenceable, Serializable {
+
+ public interface SessionFactoryOptions {
+ Interceptor getInterceptor();
+ EntityNotFoundDelegate getEntityNotFoundDelegate();
+ }
+
+ public SessionFactoryOptions getSessionFactoryOptions();
+
/**
* Obtain a {@link Session} builder.
*
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java
index 425dfac570..4e2bdd9f6a 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java
@@ -28,6 +28,8 @@ import java.util.Comparator;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
+import org.hibernate.metamodel.binding.EntityBinding;
+import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.type.VersionType;
/**
@@ -66,6 +68,14 @@ public class CacheDataDescriptionImpl implements CacheDataDescription {
);
}
+ public static CacheDataDescriptionImpl decode(EntityBinding model) {
+ return new CacheDataDescriptionImpl(
+ model.isMutable(),
+ model.isVersioned(),
+ getVersionComparator( model )
+ );
+ }
+
public static CacheDataDescriptionImpl decode(Collection model) {
return new CacheDataDescriptionImpl(
model.isMutable(),
@@ -73,4 +83,25 @@ public class CacheDataDescriptionImpl implements CacheDataDescription {
model.getOwner().isVersioned() ? ( ( VersionType ) model.getOwner().getVersion().getType() ).getComparator() : null
);
}
+
+ public static CacheDataDescriptionImpl decode(PluralAttributeBinding model) {
+ return new CacheDataDescriptionImpl(
+ model.isMutable(),
+ model.getEntityBinding().isVersioned(),
+ getVersionComparator( model.getEntityBinding() )
+ );
+ }
+
+ private static Comparator getVersionComparator(EntityBinding model ) {
+ Comparator versionComparator = null;
+ if ( model.isVersioned() ) {
+ versionComparator = (
+ ( VersionType ) model
+ .getVersioningValueBinding()
+ .getHibernateTypeDescriptor()
+ .getExplicitType()
+ ).getComparator();
+ }
+ return versionComparator;
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CollectionRegionAccessStrategy.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CollectionRegionAccessStrategy.java
index 6f88fd1c6a..7187fec426 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CollectionRegionAccessStrategy.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CollectionRegionAccessStrategy.java
@@ -23,7 +23,6 @@
*/
package org.hibernate.cache.spi.access;
-import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CollectionRegion;
/**
@@ -39,7 +38,7 @@ import org.hibernate.cache.spi.CollectionRegion;
* @author Gavin King
* @author Steve Ebersole
*/
-public interface CollectionRegionAccessStrategy {
+public interface CollectionRegionAccessStrategy extends RegionAccessStrategy {
/**
* Get the wrapped collection cache region
@@ -48,125 +47,4 @@ public interface CollectionRegionAccessStrategy {
*/
public CollectionRegion getRegion();
- /**
- * Attempt to retrieve an object from the cache. Mainly used in attempting
- * to resolve entities/collections from the second level cache.
- *
- * @param key The key of the item to be retrieved.
- * @param txTimestamp a timestamp prior to the transaction start time
- * @return the cached object or null
- * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public Object get(Object key, long txTimestamp) throws CacheException;
-
- /**
- * Attempt to cache an object, after loading from the database.
- *
- * @param key The item key
- * @param value The item
- * @param txTimestamp a timestamp prior to the transaction start time
- * @param version the item version number
- * @return true if the object was successfully cached
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public boolean putFromLoad(
- Object key,
- Object value,
- long txTimestamp,
- Object version) throws CacheException;
-
- /**
- * Attempt to cache an object, after loading from the database, explicitly
- * specifying the minimalPut behavior.
- *
- * @param key The item key
- * @param value The item
- * @param txTimestamp a timestamp prior to the transaction start time
- * @param version the item version number
- * @param minimalPutOverride Explicit minimalPut flag
- * @return true if the object was successfully cached
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public boolean putFromLoad(
- Object key,
- Object value,
- long txTimestamp,
- Object version,
- boolean minimalPutOverride) throws CacheException;
-
- /**
- * We are going to attempt to update/delete the keyed object. This
- * method is used by "asynchronous" concurrency strategies.
- *
- * The returned object must be passed back to release(), to release the
- * lock. Concurrency strategies which do not support client-visible
- * locks may silently return null.
- *
- * @param key The key of the item to lock
- * @param version The item's current version value
- * @return A representation of our lock on the item; or null.
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public SoftLock lockItem(Object key, Object version) throws CacheException;
-
- /**
- * Lock the entire region
- *
- * @return A representation of our lock on the item; or null.
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public SoftLock lockRegion() throws CacheException;
-
- /**
- * Called when we have finished the attempted update/delete (which may or
- * may not have been successful), after transaction completion. This method
- * is used by "asynchronous" concurrency strategies.
- *
- * @param key The item key
- * @param lock The lock previously obtained from {@link #lockItem}
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public void unlockItem(Object key, SoftLock lock) throws CacheException;
-
- /**
- * Called after we have finished the attempted invalidation of the entire
- * region
- *
- * @param lock The lock previously obtained from {@link #lockRegion}
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public void unlockRegion(SoftLock lock) throws CacheException;
-
- /**
- * Called after an item has become stale (before the transaction completes).
- * This method is used by "synchronous" concurrency strategies.
- *
- * @param key The key of the item to remove
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public void remove(Object key) throws CacheException;
-
- /**
- * Called to evict data from the entire region
- *
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public void removeAll() throws CacheException;
-
- /**
- * Forcibly evict an item from the cache immediately without regard for transaction
- * isolation.
- *
- * @param key The key of the item to remove
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public void evict(Object key) throws CacheException;
-
- /**
- * Forcibly evict all items from the cache immediately without regard for transaction
- * isolation.
- *
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public void evictAll() throws CacheException;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/EntityRegionAccessStrategy.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/EntityRegionAccessStrategy.java
index 7b110fe46c..faf27cc846 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/EntityRegionAccessStrategy.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/EntityRegionAccessStrategy.java
@@ -41,7 +41,7 @@ import org.hibernate.cache.spi.EntityRegion;
* @author Gavin King
* @author Steve Ebersole
*/
-public interface EntityRegionAccessStrategy {
+public interface EntityRegionAccessStrategy extends RegionAccessStrategy{
/**
* Get the wrapped entity cache region
@@ -50,95 +50,6 @@ public interface EntityRegionAccessStrategy {
*/
public EntityRegion getRegion();
- /**
- * Attempt to retrieve an object from the cache. Mainly used in attempting
- * to resolve entities/collections from the second level cache.
- *
- * @param key The key of the item to be retrieved.
- * @param txTimestamp a timestamp prior to the transaction start time
- * @return the cached object or null
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public Object get(Object key, long txTimestamp) throws CacheException;
-
- /**
- * Attempt to cache an object, after loading from the database.
- *
- * @param key The item key
- * @param value The item
- * @param txTimestamp a timestamp prior to the transaction start time
- * @param version the item version number
- * @return true if the object was successfully cached
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public boolean putFromLoad(
- Object key,
- Object value,
- long txTimestamp,
- Object version) throws CacheException;
-
- /**
- * Attempt to cache an object, after loading from the database, explicitly
- * specifying the minimalPut behavior.
- *
- * @param key The item key
- * @param value The item
- * @param txTimestamp a timestamp prior to the transaction start time
- * @param version the item version number
- * @param minimalPutOverride Explicit minimalPut flag
- * @return true if the object was successfully cached
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public boolean putFromLoad(
- Object key,
- Object value,
- long txTimestamp,
- Object version,
- boolean minimalPutOverride) throws CacheException;
-
- /**
- * We are going to attempt to update/delete the keyed object. This
- * method is used by "asynchronous" concurrency strategies.
- *
- * The returned object must be passed back to release(), to release the
- * lock. Concurrency strategies which do not support client-visible
- * locks may silently return null.
- *
- * @param key The key of the item to lock
- * @param version The item's current version value
- * @return A representation of our lock on the item; or null.
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public SoftLock lockItem(Object key, Object version) throws CacheException;
-
- /**
- * Lock the entire region
- *
- * @return A representation of our lock on the item; or null.
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public SoftLock lockRegion() throws CacheException;
-
- /**
- * Called when we have finished the attempted update/delete (which may or
- * may not have been successful), after transaction completion. This method
- * is used by "asynchronous" concurrency strategies.
- *
- * @param key The item key
- * @param lock The lock previously obtained from {@link #lockItem}
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public void unlockItem(Object key, SoftLock lock) throws CacheException;
-
- /**
- * Called after we have finished the attempted invalidation of the entire
- * region
- *
- * @param lock The lock previously obtained from {@link #lockRegion}
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
- */
- public void unlockRegion(SoftLock lock) throws CacheException;
-
/**
* Called after an item has been inserted (before the transaction completes),
* instead of calling evict().
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java
new file mode 100644
index 0000000000..c60c4f25e0
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java
@@ -0,0 +1,153 @@
+/*
+ * 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.cache.spi.access;
+
+import org.hibernate.cache.CacheException;
+
+/**
+ * @author Gail Badner
+ */
+public interface RegionAccessStrategy {
+ /**
+ * Attempt to retrieve an object from the cache. Mainly used in attempting
+ * to resolve entities/collections from the second level cache.
+ *
+ * @param key The key of the item to be retrieved.
+ * @param txTimestamp a timestamp prior to the transaction start time
+ * @return the cached object or null
+ * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ */
+ Object get(Object key, long txTimestamp) throws CacheException;
+
+ /**
+ * Attempt to cache an object, after loading from the database.
+ *
+ * @param key The item key
+ * @param value The item
+ * @param txTimestamp a timestamp prior to the transaction start time
+ * @param version the item version number
+ * @return true if the object was successfully cached
+ * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ */
+ boolean putFromLoad(
+ Object key,
+ Object value,
+ long txTimestamp,
+ Object version) throws CacheException;
+
+ /**
+ * Attempt to cache an object, after loading from the database, explicitly
+ * specifying the minimalPut behavior.
+ *
+ * @param key The item key
+ * @param value The item
+ * @param txTimestamp a timestamp prior to the transaction start time
+ * @param version the item version number
+ * @param minimalPutOverride Explicit minimalPut flag
+ * @return true if the object was successfully cached
+ * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ */
+ boolean putFromLoad(
+ Object key,
+ Object value,
+ long txTimestamp,
+ Object version,
+ boolean minimalPutOverride) throws CacheException;
+
+ /**
+ * We are going to attempt to update/delete the keyed object. This
+ * method is used by "asynchronous" concurrency strategies.
+ *
+ * The returned object must be passed back to release(), to release the
+ * lock. Concurrency strategies which do not support client-visible
+ * locks may silently return null.
+ *
+ * @param key The key of the item to lock
+ * @param version The item's current version value
+ * @return A representation of our lock on the item; or null.
+ * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ */
+ SoftLock lockItem(Object key, Object version) throws CacheException;
+
+ /**
+ * Lock the entire region
+ *
+ * @return A representation of our lock on the item; or null.
+ * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ */
+ SoftLock lockRegion() throws CacheException;
+
+ /**
+ * Called when we have finished the attempted update/delete (which may or
+ * may not have been successful), after transaction completion. This method
+ * is used by "asynchronous" concurrency strategies.
+ *
+ * @param key The item key
+ * @param lock The lock previously obtained from {@link #lockItem}
+ * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ */
+ void unlockItem(Object key, SoftLock lock) throws CacheException;
+
+ /**
+ * Called after we have finished the attempted invalidation of the entire
+ * region
+ *
+ * @param lock The lock previously obtained from {@link #lockRegion}
+ * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ */
+ void unlockRegion(SoftLock lock) throws CacheException;
+
+ /**
+ * Called after an item has become stale (before the transaction completes).
+ * This method is used by "synchronous" concurrency strategies.
+ *
+ * @param key The key of the item to remove
+ * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ */
+ void remove(Object key) throws CacheException;
+
+ /**
+ * Called to evict data from the entire region
+ *
+ * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ */
+ void removeAll() throws CacheException;
+
+ /**
+ * Forcibly evict an item from the cache immediately without regard for transaction
+ * isolation.
+ *
+ * @param key The key of the item to remove
+ * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ */
+ void evict(Object key) throws CacheException;
+
+ /**
+ * Forcibly evict all items from the cache immediately without regard for transaction
+ * isolation.
+ *
+ * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ */
+ void evictAll() throws CacheException;
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java
index 5a925154b8..b45043307a 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java
@@ -2661,6 +2661,7 @@ public final class HbmBinder {
String comment = cmAtt == null ? null : cmAtt.getValue();
NamedQueryDefinition namedQuery = new NamedQueryDefinition(
+ queryName,
query,
cacheable,
region,
@@ -2673,7 +2674,7 @@ public final class HbmBinder {
getParameterTypes(queryElem)
);
- mappings.addQuery( queryName, namedQuery );
+ mappings.addQuery( namedQuery.getName(), namedQuery );
}
public static CacheMode getCacheMode(String cacheMode) {
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/NamedSQLQuerySecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/NamedSQLQuerySecondPass.java
index 636b94df4a..478912e0f5 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/NamedSQLQuerySecondPass.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/NamedSQLQuerySecondPass.java
@@ -84,6 +84,7 @@ public class NamedSQLQuerySecondPass extends ResultSetMappingBinder implements Q
String resultSetRef = ref == null ? null : ref.getValue();
if ( StringHelper.isNotEmpty( resultSetRef ) ) {
namedQuery = new NamedSQLQueryDefinition(
+ queryName,
queryElem.getText(),
resultSetRef,
synchronizedTables,
@@ -103,6 +104,7 @@ public class NamedSQLQuerySecondPass extends ResultSetMappingBinder implements Q
else {
ResultSetMappingDefinition definition = buildResultSetMappingDefinition( queryElem, path, mappings );
namedQuery = new NamedSQLQueryDefinition(
+ queryName,
queryElem.getText(),
definition.getQueryReturns(),
synchronizedTables,
@@ -119,7 +121,7 @@ public class NamedSQLQuerySecondPass extends ResultSetMappingBinder implements Q
);
}
- LOG.debugf("Named SQL query: %s -> %s", queryName, namedQuery.getQueryString());
+ LOG.debugf("Named SQL query: %s -> %s", namedQuery.getName(), namedQuery.getQueryString());
mappings.addSQLQuery( queryName, namedQuery );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/SettingsFactory.java b/hibernate-core/src/main/java/org/hibernate/cfg/SettingsFactory.java
index 7b88455ecb..1286675c25 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/SettingsFactory.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/SettingsFactory.java
@@ -61,7 +61,7 @@ public class SettingsFactory implements Serializable {
public static final String DEF_CACHE_REG_FACTORY = NoCachingRegionFactory.class.getName();
- protected SettingsFactory() {
+ public SettingsFactory() {
}
public Settings buildSettings(Properties props, ServiceRegistry serviceRegistry) {
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java
index 03648535a0..cb1ad0e7d8 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java
@@ -64,6 +64,7 @@ public abstract class QueryBinder {
QueryHint[] hints = queryAnn.hints();
String queryName = queryAnn.query();
NamedQueryDefinition query = new NamedQueryDefinition(
+ queryAnn.name(),
queryName,
getBoolean( queryName, "org.hibernate.cacheable", hints ),
getString( queryName, "org.hibernate.cacheRegion", hints ),
@@ -76,12 +77,12 @@ public abstract class QueryBinder {
null
);
if ( isDefault ) {
- mappings.addDefaultQuery( queryAnn.name(), query );
+ mappings.addDefaultQuery( query.getName(), query );
}
else {
- mappings.addQuery( queryAnn.name(), query );
+ mappings.addQuery( query.getName(), query );
}
- LOG.debugf( "Binding named query: %s => %s", queryAnn.name(), queryAnn.query() );
+ LOG.debugf( "Binding named query: %s => %s", query.getName(), query.getQueryString() );
}
@@ -97,6 +98,7 @@ public abstract class QueryBinder {
if ( !BinderHelper.isEmptyAnnotationValue( resultSetMapping ) ) {
//sql result set usage
query = new NamedSQLQueryDefinition(
+ queryAnn.name(),
queryName,
resultSetMapping,
null,
@@ -118,6 +120,7 @@ public abstract class QueryBinder {
final NativeSQLQueryRootReturn entityQueryReturn =
new NativeSQLQueryRootReturn( "alias1", queryAnn.resultClass().getName(), new HashMap(), LockMode.READ );
query = new NamedSQLQueryDefinition(
+ queryAnn.name(),
queryName,
new NativeSQLQueryReturn[] { entityQueryReturn },
null,
@@ -137,10 +140,10 @@ public abstract class QueryBinder {
throw new NotYetImplementedException( "Pure native scalar queries are not yet supported" );
}
if ( isDefault ) {
- mappings.addDefaultSQLQuery( queryAnn.name(), query );
+ mappings.addDefaultSQLQuery( query.getName(), query );
}
else {
- mappings.addSQLQuery( queryAnn.name(), query );
+ mappings.addSQLQuery( query.getName(), query );
}
LOG.debugf( "Binding named native query: %s => %s", queryAnn.name(), queryAnn.query() );
}
@@ -155,6 +158,7 @@ public abstract class QueryBinder {
if ( !BinderHelper.isEmptyAnnotationValue( resultSetMapping ) ) {
//sql result set usage
query = new NamedSQLQueryDefinition(
+ queryAnn.name(),
queryAnn.query(),
resultSetMapping,
null,
@@ -176,6 +180,7 @@ public abstract class QueryBinder {
final NativeSQLQueryRootReturn entityQueryReturn =
new NativeSQLQueryRootReturn( "alias1", queryAnn.resultClass().getName(), new HashMap(), LockMode.READ );
query = new NamedSQLQueryDefinition(
+ queryAnn.name(),
queryAnn.query(),
new NativeSQLQueryReturn[] { entityQueryReturn },
null,
@@ -194,8 +199,8 @@ public abstract class QueryBinder {
else {
throw new NotYetImplementedException( "Pure native scalar queries are not yet supported" );
}
- mappings.addSQLQuery( queryAnn.name(), query );
- LOG.debugf( "Binding named native query: %s => %s", queryAnn.name(), queryAnn.query() );
+ mappings.addSQLQuery( query.getName(), query );
+ LOG.debugf( "Binding named native query: %s => %s", query.getName(), queryAnn.query() );
}
public static void bindQueries(NamedQueries queriesAnn, Mappings mappings, boolean isDefault) {
@@ -229,6 +234,7 @@ public abstract class QueryBinder {
flushMode = getFlushMode( queryAnn.flushMode() );
NamedQueryDefinition query = new NamedQueryDefinition(
+ queryAnn.name(),
queryAnn.query(),
queryAnn.cacheable(),
BinderHelper.isEmptyAnnotationValue( queryAnn.cacheRegion() ) ? null : queryAnn.cacheRegion(),
@@ -241,8 +247,8 @@ public abstract class QueryBinder {
null
);
- mappings.addQuery( queryAnn.name(), query );
- LOG.debugf( "Binding named query: %s => %s", queryAnn.name(), queryAnn.query() );
+ mappings.addQuery( query.getName(), query );
+ LOG.debugf( "Binding named query: %s => %s", query.getName(), query.getQueryString() );
}
private static FlushMode getFlushMode(FlushModeType flushModeType) {
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/NamedQueryDefinition.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/NamedQueryDefinition.java
index 47b97dfbfd..d021ef32a4 100755
--- a/hibernate-core/src/main/java/org/hibernate/engine/spi/NamedQueryDefinition.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/NamedQueryDefinition.java
@@ -35,6 +35,7 @@ import org.hibernate.FlushMode;
* @author Gavin King
*/
public class NamedQueryDefinition implements Serializable {
+ private final String name;
private final String query;
private final boolean cacheable;
private final String cacheRegion;
@@ -47,6 +48,7 @@ public class NamedQueryDefinition implements Serializable {
private String comment;
// kept for backward compatibility until after the 3.1beta5 release of HA
+ // TODO: is this still needed?
public NamedQueryDefinition(
String query,
boolean cacheable,
@@ -56,6 +58,7 @@ public class NamedQueryDefinition implements Serializable {
FlushMode flushMode,
Map parameterTypes) {
this(
+ null,
query,
cacheable,
cacheRegion,
@@ -70,6 +73,7 @@ public class NamedQueryDefinition implements Serializable {
}
public NamedQueryDefinition(
+ String name,
String query,
boolean cacheable,
String cacheRegion,
@@ -80,6 +84,7 @@ public class NamedQueryDefinition implements Serializable {
boolean readOnly,
String comment,
Map parameterTypes) {
+ this.name = name;
this.query = query;
this.cacheable = cacheable;
this.cacheRegion = cacheRegion;
@@ -92,6 +97,10 @@ public class NamedQueryDefinition implements Serializable {
this.comment = comment;
}
+ public String getName() {
+ return name;
+ }
+
public String getQueryString() {
return query;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/NamedSQLQueryDefinition.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/NamedSQLQueryDefinition.java
index 106140e47d..b3f675be17 100755
--- a/hibernate-core/src/main/java/org/hibernate/engine/spi/NamedSQLQueryDefinition.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/NamedSQLQueryDefinition.java
@@ -62,6 +62,7 @@ public class NamedSQLQueryDefinition extends NamedQueryDefinition {
* @param callable Does the query string represent a callable object (i.e., proc)
*/
public NamedSQLQueryDefinition(
+ String name,
String query,
NativeSQLQueryReturn[] queryReturns,
List querySpaces,
@@ -76,6 +77,7 @@ public class NamedSQLQueryDefinition extends NamedQueryDefinition {
Map parameterTypes,
boolean callable) {
super(
+ name,
query.trim(), /* trim done to workaround stupid oracle bug that cant handle whitespaces before a { in a sp */
cacheable,
cacheRegion,
@@ -111,6 +113,7 @@ public class NamedSQLQueryDefinition extends NamedQueryDefinition {
* @param callable Does the query string represent a callable object (i.e., proc)
*/
public NamedSQLQueryDefinition(
+ String name,
String query,
String resultSetRef,
List querySpaces,
@@ -125,6 +128,7 @@ public class NamedSQLQueryDefinition extends NamedQueryDefinition {
Map parameterTypes,
boolean callable) {
super(
+ name,
query.trim(), /* trim done to workaround stupid oracle bug that cant handle whitespaces before a { in a sp */
cacheable,
cacheRegion,
@@ -172,6 +176,7 @@ public class NamedSQLQueryDefinition extends NamedQueryDefinition {
Map parameterTypes,
boolean callable) {
this(
+ null,
query,
resultSetRef,
querySpaces,
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java
index 788a916eb0..57f16a315a 100644
--- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java
@@ -75,10 +75,11 @@ import org.hibernate.cache.spi.UpdateTimestampsCache;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
-import org.hibernate.cfg.AvailableSettings;
+import org.hibernate.cache.spi.access.RegionAccessStrategy;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.Settings;
+import org.hibernate.cfg.SettingsFactory;
import org.hibernate.context.internal.ThreadLocalSessionContext;
import org.hibernate.context.spi.CurrentSessionContext;
import org.hibernate.context.internal.JTASessionContext;
@@ -114,6 +115,7 @@ import org.hibernate.mapping.RootClass;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.metamodel.binding.EntityBinding;
+import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.source.spi.MetadataImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
@@ -180,13 +182,12 @@ public final class SessionFactoryImpl
private final transient Map collectionMetadata;
private final transient Map> collectionRolesByEntityParticipant;
private final transient Map identifierGenerators;
- private final transient Map namedQueries;
- private final transient Map namedSqlQueries;
- private final transient Map sqlResultSetMappings;
+ private final transient Map namedQueries;
+ private final transient Map namedSqlQueries;
+ private final transient Map sqlResultSetMappings;
private final transient Map filters;
private final transient Map fetchProfiles;
- private final transient Map imports;
- private final transient Interceptor interceptor;
+ private final transient Map imports;
private final transient SessionFactoryServiceRegistry serviceRegistry;
private final transient Settings settings;
private final transient Properties properties;
@@ -196,7 +197,6 @@ public final class SessionFactoryImpl
private final transient Map queryCaches;
private final transient ConcurrentMap allCacheRegions = new ConcurrentHashMap();
private final transient CurrentSessionContext currentSessionContext;
- private final transient EntityNotFoundDelegate entityNotFoundDelegate;
private final transient SQLFunctionRegistry sqlFunctionRegistry;
private final transient SessionFactoryObserverChain observer = new SessionFactoryObserverChain();
private final transient HashMap entityNameResolvers = new HashMap();
@@ -206,18 +206,44 @@ public final class SessionFactoryImpl
private final transient TypeResolver typeResolver;
private final transient TypeHelper typeHelper;
private final transient TransactionEnvironment transactionEnvironment;
+ private final transient SessionFactoryOptions sessionFactoryOptions;
@SuppressWarnings( {"unchecked"} )
public SessionFactoryImpl(
- Configuration cfg,
+ final Configuration cfg,
Mapping mapping,
ServiceRegistry serviceRegistry,
Settings settings,
SessionFactoryObserver observer) throws HibernateException {
LOG.debug( "Building session factory" );
+ sessionFactoryOptions = new SessionFactoryOptions() {
+ private EntityNotFoundDelegate entityNotFoundDelegate;
+
+ @Override
+ public Interceptor getInterceptor() {
+ return cfg.getInterceptor();
+ }
+
+ @Override
+ public EntityNotFoundDelegate getEntityNotFoundDelegate() {
+ if ( entityNotFoundDelegate == null ) {
+ if ( cfg.getEntityNotFoundDelegate() != null ) {
+ entityNotFoundDelegate = cfg.getEntityNotFoundDelegate();
+ }
+ else {
+ entityNotFoundDelegate = new EntityNotFoundDelegate() {
+ public void handleEntityNotFound(String entityName, Serializable id) {
+ throw new ObjectNotFoundException( id, entityName );
+ }
+ };
+ }
+ }
+ return entityNotFoundDelegate;
+ }
+ };
+
this.settings = settings;
- this.interceptor = cfg.getInterceptor();
this.properties = new Properties();
this.properties.putAll( cfg.getProperties() );
@@ -377,10 +403,10 @@ public final class SessionFactoryImpl
collectionRolesByEntityParticipant = Collections.unmodifiableMap( tmpEntityToCollectionRoleMap );
//Named Queries:
- namedQueries = new HashMap( cfg.getNamedQueries() );
- namedSqlQueries = new HashMap( cfg.getNamedSQLQueries() );
- sqlResultSetMappings = new HashMap( cfg.getSqlResultSetMappings() );
- imports = new HashMap( cfg.getImports() );
+ namedQueries = new HashMap( cfg.getNamedQueries() );
+ namedSqlQueries = new HashMap( cfg.getNamedSQLQueries() );
+ sqlResultSetMappings = new HashMap( cfg.getSqlResultSetMappings() );
+ imports = new HashMap( cfg.getImports() );
// after *all* persisters and named queries are registered
Iterator iter = entityPersisters.values().iterator();
@@ -455,17 +481,6 @@ public final class SessionFactoryImpl
}
}
- // EntityNotFoundDelegate
- EntityNotFoundDelegate entityNotFoundDelegate = cfg.getEntityNotFoundDelegate();
- if ( entityNotFoundDelegate == null ) {
- entityNotFoundDelegate = new EntityNotFoundDelegate() {
- public void handleEntityNotFound(String entityName, Serializable id) {
- throw new ObjectNotFoundException( id, entityName );
- }
- };
- }
- this.entityNotFoundDelegate = entityNotFoundDelegate;
-
// this needs to happen after persisters are all ready to go...
this.fetchProfiles = new HashMap();
itr = cfg.iterateFetchProfiles();
@@ -509,52 +524,41 @@ public final class SessionFactoryImpl
public SessionFactoryImpl(
MetadataImplementor metadata,
- Mapping mapping,
- ServiceRegistry serviceRegistry,
+ SessionFactoryOptions sessionFactoryOptions,
SessionFactoryObserver observer) throws HibernateException {
LOG.debug( "Building session factory" );
// TODO: remove initialization of final variables; just setting to null to make compiler happy
this.name = null;
this.uuid = null;
- this.entityPersisters = null;
- this.classMetadata = null;
- this.collectionPersisters = null;
- this.collectionMetadata = null;
- this.collectionRolesByEntityParticipant = null;
- this.identifierGenerators = null;
- this.namedQueries = null;
- this.namedSqlQueries = null;
- this.sqlResultSetMappings = null;
this.fetchProfiles = null;
- this.imports = null;
- this.interceptor = null;
this.queryCache = null;
this.updateTimestampsCache = null;
this.queryCaches = null;
this.currentSessionContext = null;
- this.entityNotFoundDelegate = null;
this.sqlFunctionRegistry = null;
- this.queryPlanCache = null;
this.transactionEnvironment = null;
- ConfigurationService configurationService = serviceRegistry.getService( ConfigurationService.class );
- this.settings = null;
+ this.sessionFactoryOptions = sessionFactoryOptions;
- this.serviceRegistry = serviceRegistry.getService( SessionFactoryServiceRegistryFactory.class ).buildServiceRegistry(
- this,
- metadata
+ this.properties = createPropertiesFromMap(
+ metadata.getServiceRegistry().getService( ConfigurationService.class ).getSettings()
);
- // TODO: get Interceptor from ConfurationService
- //this.interceptor = cfg.getInterceptor();
+ // TODO: these should be moved into SessionFactoryOptions
+ this.settings = new SettingsFactory().buildSettings(
+ properties,
+ metadata.getServiceRegistry()
+ );
- // TODO: find references to properties and make sure everything needed is available to services via
- // ConfigurationService
- this.properties = null;
+ this.serviceRegistry =
+ metadata.getServiceRegistry()
+ .getService( SessionFactoryServiceRegistryFactory.class )
+ .buildServiceRegistry( this, metadata );
+
+ // TODO: get SQL functions from a new service
+ // this.sqlFunctionRegistry = new SQLFunctionRegistry( getDialect(), cfg.getSqlFunctions() );
- // TODO: should this be build along w/ metadata? seems like it should so app has more control over it...
- //this.sqlFunctionRegistry = new SQLFunctionRegistry( getDialect(), metadata.getSqlFunctions() );
if ( observer != null ) {
this.observer.addObserver( observer );
}
@@ -568,10 +572,203 @@ public final class SessionFactoryImpl
}
LOG.debugf("Session factory constructed with filter configurations : %s", filters);
- LOG.debugf("Instantiating session factory with properties: %s", configurationService.getSettings() );
+ LOG.debugf("Instantiating session factory with properties: %s", properties );
+
+ // TODO: get RegionFactory from service registry
+ settings.getRegionFactory().start( settings, properties );
+ this.queryPlanCache = new QueryPlanCache( this );
+
+ class IntegratorObserver implements SessionFactoryObserver {
+ private ArrayList integrators = new ArrayList();
+
+ @Override
+ public void sessionFactoryCreated(SessionFactory factory) {
+ }
+
+ @Override
+ public void sessionFactoryClosed(SessionFactory factory) {
+ for ( Integrator integrator : integrators ) {
+ integrator.disintegrate( SessionFactoryImpl.this, SessionFactoryImpl.this.serviceRegistry );
+ }
+ }
+ }
+
+ final IntegratorObserver integratorObserver = new IntegratorObserver();
+ this.observer.addObserver( integratorObserver );
+ for ( Integrator integrator : serviceRegistry.getService( IntegratorService.class ).getIntegrators() ) {
+ // TODO: add Integrator.integrate(MetadataImplementor, ...)
+ // integrator.integrate( cfg, this, this.serviceRegistry );
+ integratorObserver.integrators.add( integrator );
+ }
+
+
+ //Generators:
+
+ identifierGenerators = new HashMap();
+ for ( EntityBinding entityBinding : metadata.getEntityBindings() ) {
+ if ( entityBinding.isRoot() ) {
+ // TODO: create the IdentifierGenerator while the metadata is being build, then simply
+ // use EntityBinding.getIdentifierGenerator() (also remove getIdentifierGeneratorFactory from Mappings)
+ // TODO: this is broken; throws NullPointerException
+ //IdentifierGenerator generator = entityBinding.getEntityIdentifier().createIdentifierGenerator(
+ // metadata.getIdentifierGeneratorFactory()
+ //);
+ //identifierGenerators.put( entityBinding.getEntity().getName(), generator );
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // Prepare persisters and link them up with their cache
+ // region/access-strategy
+
+ StringBuilder stringBuilder = new StringBuilder();
+ if ( settings.getCacheRegionPrefix() != null) {
+ stringBuilder
+ .append( settings.getCacheRegionPrefix() )
+ .append( '.' );
+ }
+ final String cacheRegionPrefix = stringBuilder.toString();
+
+ entityPersisters = new HashMap();
+ Map entityAccessStrategies = new HashMap();
+ Map classMeta = new HashMap();
+ for ( EntityBinding model : metadata.getEntityBindings() ) {
+ // TODO: should temp table prep happen when metadata is being built?
+ //model.prepareTemporaryTables( metadata, getDialect() );
+ // cache region is defined by the root-class in the hierarchy...
+ EntityBinding rootEntityBinding = metadata.getRootEntityBinding( model.getEntity().getName() );
+ EntityRegionAccessStrategy accessStrategy = null;
+ if ( settings.isSecondLevelCacheEnabled() &&
+ rootEntityBinding.getCaching() != null &&
+ model.getCaching() != null &&
+ model.getCaching().getAccessType() != null ) {
+ final String cacheRegionName = cacheRegionPrefix + rootEntityBinding.getCaching().getRegion();
+ accessStrategy = EntityRegionAccessStrategy.class.cast( entityAccessStrategies.get( cacheRegionName ) );
+ if ( accessStrategy == null ) {
+ final AccessType accessType = model.getCaching().getAccessType();
+ LOG.trace("Building cache for entity data [" + model.getEntity().getName() + "]");
+ EntityRegion entityRegion =
+ settings.getRegionFactory().buildEntityRegion(
+ cacheRegionName,
+ properties,
+ CacheDataDescriptionImpl.decode( model )
+ );
+ accessStrategy = entityRegion.buildAccessStrategy( accessType );
+ entityAccessStrategies.put( cacheRegionName, accessStrategy );
+ allCacheRegions.put( cacheRegionName, entityRegion );
+ }
+ }
+ EntityPersister cp = serviceRegistry.getService( PersisterFactory.class ).createEntityPersister(
+ model, accessStrategy, this, metadata
+ );
+ entityPersisters.put( model.getEntity().getName(), cp );
+ classMeta.put( model.getEntity().getName(), cp.getClassMetadata() );
+ }
+ this.classMetadata = Collections.unmodifiableMap(classMeta);
+
+ Map> tmpEntityToCollectionRoleMap = new HashMap>();
+ collectionPersisters = new HashMap();
+ for ( PluralAttributeBinding model : metadata.getCollectionBindings() ) {
+ if ( model.getAttribute() == null ) {
+ throw new IllegalStateException( "No attribute defined for a PluralAttributeBinding: " + model );
+ }
+ if ( model.getAttribute().isSingular() ) {
+ throw new IllegalStateException(
+ "PluralAttributeBinding has a Singular attribute defined: " + model.getAttribute().getName()
+ );
+ }
+ // TODO: Add PluralAttributeBinding.getCaching()
+ final String cacheRegionName = cacheRegionPrefix + model.getCacheRegionName();
+ final AccessType accessType = AccessType.fromExternalName( model.getCacheConcurrencyStrategy() );
+ CollectionRegionAccessStrategy accessStrategy = null;
+ if ( accessType != null && settings.isSecondLevelCacheEnabled() ) {
+ // TODO: is model.getAttribute().getName() the collection's role??? For now, assuming it is
+ LOG.trace("Building cache for collection data [" + model.getAttribute().getName() + "]");
+ CollectionRegion collectionRegion =
+ settings.getRegionFactory()
+ .buildCollectionRegion(
+ cacheRegionName, properties, CacheDataDescriptionImpl.decode( model )
+ );
+ accessStrategy = collectionRegion.buildAccessStrategy( accessType );
+ entityAccessStrategies.put( cacheRegionName, accessStrategy );
+ allCacheRegions.put( cacheRegionName, collectionRegion );
+ }
+ CollectionPersister persister =
+ serviceRegistry
+ .getService( PersisterFactory.class )
+ .createCollectionPersister( metadata, model, accessStrategy, this );
+ // TODO: is model.getAttribute().getName() the collection's role??? For now, assuming it is
+ collectionPersisters.put( model.getAttribute().getName(), persister.getCollectionMetadata() );
+ Type indexType = persister.getIndexType();
+ if ( indexType != null && indexType.isAssociationType() && !indexType.isAnyType() ) {
+ String entityName = ( ( AssociationType ) indexType ).getAssociatedEntityName( this );
+ Set roles = tmpEntityToCollectionRoleMap.get( entityName );
+ if ( roles == null ) {
+ roles = new HashSet();
+ tmpEntityToCollectionRoleMap.put( entityName, roles );
+ }
+ roles.add( persister.getRole() );
+ }
+ Type elementType = persister.getElementType();
+ if ( elementType.isAssociationType() && !elementType.isAnyType() ) {
+ String entityName = ( ( AssociationType ) elementType ).getAssociatedEntityName( this );
+ Set roles = tmpEntityToCollectionRoleMap.get( entityName );
+ if ( roles == null ) {
+ roles = new HashSet();
+ tmpEntityToCollectionRoleMap.put( entityName, roles );
+ }
+ roles.add( persister.getRole() );
+ }
+ }
+ collectionMetadata = Collections.unmodifiableMap(collectionPersisters);
+ Iterator itr = tmpEntityToCollectionRoleMap.entrySet().iterator();
+ while ( itr.hasNext() ) {
+ final Map.Entry entry = ( Map.Entry ) itr.next();
+ entry.setValue( Collections.unmodifiableSet( ( Set ) entry.getValue() ) );
+ }
+ collectionRolesByEntityParticipant = Collections.unmodifiableMap( tmpEntityToCollectionRoleMap );
+
+ //Named Queries:
+ namedQueries = new HashMap();
+ for ( NamedQueryDefinition namedQueryDefinition : metadata.getNamedQueryDefinitions() ) {
+ namedQueries.put( namedQueryDefinition.getName(), namedQueryDefinition );
+ }
+ namedSqlQueries = new HashMap();
+ for ( NamedSQLQueryDefinition namedNativeQueryDefinition: metadata.getNamedNativeQueryDefinitions() ) {
+ namedSqlQueries.put( namedNativeQueryDefinition.getName(), namedNativeQueryDefinition );
+ }
+ sqlResultSetMappings = new HashMap();
+ for( ResultSetMappingDefinition resultSetMappingDefinition : metadata.getResultSetMappingDefinitions() ) {
+ sqlResultSetMappings.put( resultSetMappingDefinition.getName(), resultSetMappingDefinition );
+ }
+ imports = new HashMap();
+ for ( Map.Entry importEntry : metadata.getImports() ) {
+ imports.put( importEntry.getKey(), importEntry.getValue() );
+ }
+
+ // after *all* persisters and named queries are registered
+ Iterator iter = entityPersisters.values().iterator();
+ while ( iter.hasNext() ) {
+ final EntityPersister persister = ( ( EntityPersister ) iter.next() );
+ // TODO: broken
+ //persister.postInstantiate();
+ registerEntityNameResolvers( persister );
+
+ }
+ iter = collectionPersisters.values().iterator();
+ while ( iter.hasNext() ) {
+ final CollectionPersister persister = ( ( CollectionPersister ) iter.next() );
+ persister.postInstantiate();
+ }
// TODO: implement
+ }
+ @SuppressWarnings( {"unchecked"} )
+ private static Properties createPropertiesFromMap(Map map) {
+ Properties properties = new Properties();
+ properties.putAll( map );
+ return properties;
}
public Session openSession() throws HibernateException {
@@ -762,6 +959,11 @@ public final class SessionFactoryImpl
return settings;
}
+ @Override
+ public SessionFactoryOptions getSessionFactoryOptions() {
+ return sessionFactoryOptions;
+ }
+
public JdbcServices getJdbcServices() {
return serviceRegistry.getService( JdbcServices.class );
}
@@ -775,7 +977,7 @@ public final class SessionFactoryImpl
public Interceptor getInterceptor()
{
- return interceptor;
+ return sessionFactoryOptions.getInterceptor();
}
public SQLExceptionConverter getSQLExceptionConverter() {
@@ -1315,7 +1517,7 @@ public final class SessionFactoryImpl
@Override
public EntityNotFoundDelegate getEntityNotFoundDelegate() {
- return entityNotFoundDelegate;
+ return sessionFactoryOptions.getEntityNotFoundDelegate();
}
public SQLFunctionRegistry getSqlFunctionRegistry() {
diff --git a/hibernate-core/src/main/java/org/hibernate/jmx/SessionFactoryStub.java b/hibernate-core/src/main/java/org/hibernate/jmx/SessionFactoryStub.java
index 777592156e..26bfb32f9d 100644
--- a/hibernate-core/src/main/java/org/hibernate/jmx/SessionFactoryStub.java
+++ b/hibernate-core/src/main/java/org/hibernate/jmx/SessionFactoryStub.java
@@ -38,6 +38,8 @@ import org.jboss.logging.Logger;
import org.hibernate.AssertionFailure;
import org.hibernate.Cache;
import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.ObjectNotFoundException;
import org.hibernate.StatelessSessionBuilder;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.Session;
@@ -51,6 +53,7 @@ import org.hibernate.id.UUIDGenerator;
import org.hibernate.internal.SessionFactoryRegistry;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
+import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.service.jndi.internal.JndiServiceImpl;
import org.hibernate.stat.Statistics;
@@ -88,6 +91,11 @@ public class SessionFactoryStub implements SessionFactory {
SessionFactoryRegistry.INSTANCE.addSessionFactory( uuid, name, this, new JndiServiceImpl( service.getProperties() ) );
}
+ @Override
+ public SessionFactoryOptions getSessionFactoryOptions() {
+ return impl.getSessionFactoryOptions();
+ }
+
@Override
public SessionBuilder withOptions() {
return getImpl().withOptions();
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java b/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java
index a3cd180f49..8f3f861b4f 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java
@@ -24,14 +24,19 @@
package org.hibernate.metamodel;
+import java.util.Map;
import javax.persistence.SharedCacheMode;
import org.hibernate.SessionFactory;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.spi.FilterDefinition;
+import org.hibernate.engine.spi.NamedQueryDefinition;
+import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.IdGenerator;
+import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef;
/**
@@ -53,15 +58,34 @@ public interface Metadata {
public Options getOptions();
+ public SessionFactoryBuilder getSessionFactoryBuilder();
+
public SessionFactory buildSessionFactory();
public Iterable getEntityBindings();
public EntityBinding getEntityBinding(String entityName);
+ /**
+ * Get the "root" entity binding
+ * @param entityName
+ * @return the "root entity binding; simply returns entityBinding if it is the root entity binding
+ */
+ public EntityBinding getRootEntityBinding(String entityName);
+
+ public Iterable getCollectionBindings();
+
public Iterable getTypeDefinitions();
public Iterable getFilterDefinitions();
+ public Iterable getNamedQueryDefinitions();
+
+ public Iterable getNamedNativeQueryDefinitions();
+
+ public Iterable getResultSetMappingDefinitions();
+
+ public Iterable> getImports();
+
public IdGenerator getIdGenerator(String name);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/SessionFactoryBuilder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/SessionFactoryBuilder.java
new file mode 100644
index 0000000000..c97ede7191
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/SessionFactoryBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+import org.hibernate.Interceptor;
+import org.hibernate.SessionFactory;
+import org.hibernate.proxy.EntityNotFoundDelegate;
+
+/**
+ * @author Gail Badner
+ */
+public interface SessionFactoryBuilder {
+ public SessionFactoryBuilder with(Interceptor interceptor);
+
+ public SessionFactoryBuilder with(EntityNotFoundDelegate entityNotFoundDelegate);
+
+ public SessionFactory buildSessionFactory();
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityBinding.java
index b9adc3bd1e..9cf6599423 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityBinding.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityBinding.java
@@ -229,6 +229,10 @@ public class EntityBinding {
return entityInheritanceType;
}
+ public boolean isVersioned() {
+ return versionBinding != null;
+ }
+
public SimpleAttributeBinding getVersioningValueBinding() {
return versionBinding;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/QueryBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/QueryBinder.java
index 2a86402719..660843ff7a 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/QueryBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/global/QueryBinder.java
@@ -124,8 +124,8 @@ public class QueryBinder {
comment = null;
}
metadata.addNamedQuery(
- name,
new NamedQueryDefinition(
+ name,
query, getBoolean( hints, QueryHints.CACHEABLE, name ), cacheRegion,
timeout, fetchSize, getFlushMode( hints, QueryHints.FLUSH_MODE, name ),
getCacheMode( hints, QueryHints.CACHE_MODE, name ),
@@ -167,6 +167,7 @@ public class QueryBinder {
NamedSQLQueryDefinition def;
if ( StringHelper.isNotEmpty( resultSetMapping ) ) {
def = new NamedSQLQueryDefinition(
+ name,
query, resultSetMapping, null, cacheable,
cacheRegion, timeout, fetchSize,
flushMode, cacheMode, readOnly, comment,
@@ -179,6 +180,7 @@ public class QueryBinder {
throw new NotYetImplementedException( "Pure native scalar queries are not yet supported" );
}
def = new NamedSQLQueryDefinition(
+ name,
query, new NativeSQLQueryRootReturn[] {
new NativeSQLQueryRootReturn(
"alias1",
@@ -192,7 +194,7 @@ public class QueryBinder {
);
}
- metadata.addNamedNativeQuery( name, def );
+ metadata.addNamedNativeQuery( def );
LOG.debugf( "Binding named native query: %s => %s", name, query );
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java
index b3c35ff6f2..29cf6993bf 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java
@@ -33,15 +33,20 @@ import java.util.Map;
import org.jboss.logging.Logger;
import org.hibernate.DuplicateMappingException;
+import org.hibernate.MappingException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.engine.spi.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.id.factory.DefaultIdentifierGeneratorFactory;
+import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.MetadataSources;
+import org.hibernate.metamodel.SessionFactoryBuilder;
import org.hibernate.metamodel.SourceProcessingOrder;
+import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.IdGenerator;
@@ -58,6 +63,7 @@ import org.hibernate.metamodel.source.spi.MetaAttributeContext;
import org.hibernate.metamodel.source.spi.MetadataImplementor;
import org.hibernate.service.BasicServiceRegistry;
import org.hibernate.service.classloading.spi.ClassLoaderService;
+import org.hibernate.type.Type;
import org.hibernate.type.TypeResolver;
/**
@@ -65,6 +71,7 @@ import org.hibernate.type.TypeResolver;
*
* @author Steve Ebersole
* @author Hardy Ferentschik
+ * @author Gail Badner
*/
public class MetadataImpl implements MetadataImplementor, Serializable {
@@ -78,6 +85,9 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
private ClassLoaderService classLoaderService;
private TypeResolver typeResolver = new TypeResolver();
+
+ private SessionFactoryBuilder sessionFactoryBuilder = new SessionFactoryBuilderImpl( this );
+
private DefaultIdentifierGeneratorFactory identifierGeneratorFactory = new DefaultIdentifierGeneratorFactory();
private final Database database = new Database();
@@ -88,13 +98,15 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
* Maps the fully qualified class name of an entity to its entity binding
*/
private Map entityBindingMap = new HashMap();
+ private Map rootEntityBindingMap = new HashMap();
private Map collectionBindingMap = new HashMap();
private Map fetchProfiles = new HashMap();
- private Map imports;
+ private Map imports = new HashMap();
private Map typeDefs = new HashMap();
private Map idGenerators = new HashMap();
private Map namedQueryDefs = new HashMap();
private Map namedNativeQueryDefs = new HashMap();
+ private Map resultSetMappings = new HashMap();
private Map filterDefs = new HashMap();
// todo : keep as part of Database?
@@ -164,11 +176,17 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
@Override
public void addFetchProfile(FetchProfile profile) {
+ if ( profile == null || profile.getName() == null ) {
+ throw new IllegalArgumentException( "Fetch profile object or name is null: " + profile );
+ }
fetchProfiles.put( profile.getName(), profile );
}
@Override
public void addFilterDefinition(FilterDefinition def) {
+ if ( def == null || def.getFilterName() == null ) {
+ throw new IllegalArgumentException( "Filter definition object or name is null: " + def );
+ }
filterDefs.put( def.getFilterName(), def );
}
@@ -178,6 +196,9 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
@Override
public void addIdGenerator(IdGenerator generator) {
+ if ( generator == null || generator.getName() == null ) {
+ throw new IllegalArgumentException( "ID generator object or name is null." );
+ }
idGenerators.put( generator.getName(), generator );
}
@@ -195,12 +216,18 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
@Override
public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject) {
+ if ( auxiliaryDatabaseObject == null ) {
+ throw new IllegalArgumentException( "Auxiliary database object is null." );
+ }
auxiliaryDatabaseObjects.add( auxiliaryDatabaseObject );
}
@Override
- public void addNamedNativeQuery(String name, NamedSQLQueryDefinition def) {
- namedNativeQueryDefs.put( name, def );
+ public void addNamedNativeQuery(NamedSQLQueryDefinition def) {
+ if ( def == null || def.getName() == null ) {
+ throw new IllegalArgumentException( "Named native query definition object or name is null: " + def.getQueryString() );
+ }
+ namedNativeQueryDefs.put( def.getName(), def );
}
public NamedSQLQueryDefinition getNamedNativeQuery(String name) {
@@ -211,8 +238,16 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
}
@Override
- public void addNamedQuery(String name, NamedQueryDefinition def) {
- namedQueryDefs.put( name, def );
+ public Iterable getNamedNativeQueryDefinitions() {
+ return namedNativeQueryDefs.values();
+ }
+
+ @Override
+ public void addNamedQuery(NamedQueryDefinition def) {
+ if ( def == null || def.getName() == null ) {
+ throw new IllegalArgumentException( "Named query definition object or name is null: " + def.getQueryString() );
+ }
+ namedQueryDefs.put( def.getName(), def );
}
public NamedQueryDefinition getNamedQuery(String name) {
@@ -222,8 +257,29 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
return namedQueryDefs.get( name );
}
+ @Override
+ public Iterable getNamedQueryDefinitions() {
+ return namedQueryDefs.values();
+ }
+
+ @Override
+ public void addResultSetMapping(ResultSetMappingDefinition resultSetMappingDefinition) {
+ if ( resultSetMappingDefinition == null || resultSetMappingDefinition.getName() == null ) {
+ throw new IllegalArgumentException( "Resultset mappping object or name is null: " + resultSetMappingDefinition );
+ }
+ resultSetMappings.put( resultSetMappingDefinition.getName(), resultSetMappingDefinition );
+ }
+
+ @Override
+ public Iterable getResultSetMappingDefinitions() {
+ return resultSetMappings.values();
+ }
+
@Override
public void addTypeDefinition(TypeDef typeDef) {
+ if ( typeDef == null || typeDef.getName() == null ) {
+ throw new IllegalArgumentException( "Type definition object or name is null: " + typeDef.getTypeClass() );
+ }
final TypeDef previous = typeDefs.put( typeDef.getName(), typeDef );
if ( previous != null ) {
LOG.debugf( "Duplicate typedef name [%s] now -> %s", typeDef.getName(), typeDef.getTypeClass() );
@@ -253,8 +309,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
@Override
public SessionFactory buildSessionFactory() {
- // todo : implement!!!!
- return null;
+ return sessionFactoryBuilder.buildSessionFactory();
}
@Override
@@ -271,6 +326,28 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
return entityBindingMap.get( entityName );
}
+ @Override
+ public EntityBinding getRootEntityBinding(String entityName) {
+ EntityBinding rootEntityBinding = rootEntityBindingMap.get( entityName );
+ if ( rootEntityBinding == null ) {
+ EntityBinding entityBinding = entityBindingMap.get( entityName );
+ if ( entityBinding == null ) {
+ throw new IllegalStateException( "Unknown entity binding: " + entityName );
+ }
+ if ( entityBinding.isRoot() ) {
+ rootEntityBinding = entityBinding;
+ }
+ else {
+ if ( entityBinding.getEntity().getSuperType() == null ) {
+ throw new IllegalStateException( "Entity binding has no root: " + entityName );
+ }
+ rootEntityBinding = getRootEntityBinding( entityBinding.getEntity().getSuperType().getName() );
+ }
+ rootEntityBindingMap.put( entityName, rootEntityBinding );
+ }
+ return rootEntityBinding;
+ }
+
public Iterable getEntityBindings() {
return entityBindingMap.values();
}
@@ -287,7 +364,8 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
return collectionBindingMap.get( collectionRole );
}
- public Iterable getCollections() {
+ @Override
+ public Iterable getCollectionBindings() {
return collectionBindingMap.values();
}
@@ -302,8 +380,8 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
}
public void addImport(String importName, String entityName) {
- if ( imports == null ) {
- imports = new HashMap();
+ if ( importName == null || entityName == null ) {
+ throw new IllegalArgumentException( "Import name or entity name is null" );
}
LOG.trace( "Import: " + importName + " -> " + entityName );
String old = imports.put( importName, entityName );
@@ -312,6 +390,10 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
}
}
+ public Iterable> getImports() {
+ return imports.entrySet();
+ }
+
public Iterable getFetchProfiles() {
return fetchProfiles.values();
}
@@ -320,6 +402,11 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
return typeResolver;
}
+ @Override
+ public SessionFactoryBuilder getSessionFactoryBuilder() {
+ return sessionFactoryBuilder;
+ }
+
@Override
public NamingStrategy getNamingStrategy() {
return options.getNamingStrategy();
@@ -347,6 +434,48 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
private static final String DEFAULT_CASCADE = "none";
private static final String DEFAULT_PROPERTY_ACCESS = "property";
+ @Override
+ public IdentifierGeneratorFactory getIdentifierGeneratorFactory() {
+ return identifierGeneratorFactory;
+ }
+
+ @Override
+ public Type getIdentifierType(String entityName) throws MappingException {
+ EntityBinding entityBinding = getEntityBinding( entityName );
+ if ( entityBinding == null ) {
+ throw new MappingException( "Entity binding not known: " + entityName );
+ }
+ return entityBinding
+ .getEntityIdentifier()
+ .getValueBinding()
+ .getHibernateTypeDescriptor()
+ .getExplicitType();
+ }
+
+ @Override
+ public String getIdentifierPropertyName(String entityName) throws MappingException {
+ EntityBinding entityBinding = getEntityBinding( entityName );
+ if ( entityBinding == null ) {
+ throw new MappingException( "Entity binding not known: " + entityName );
+ }
+ AttributeBinding idBinding = entityBinding.getEntityIdentifier().getValueBinding();
+ return idBinding == null ? null : idBinding.getAttribute().getName();
+ }
+
+ @Override
+ public Type getReferencedPropertyType(String entityName, String propertyName) throws MappingException {
+ EntityBinding entityBinding = getEntityBinding( entityName );
+ if ( entityBinding == null ) {
+ throw new MappingException( "Entity binding not known: " + entityName );
+ }
+ // TODO: should this call EntityBinding.getReferencedAttributeBindingString), which does not exist yet?
+ AttributeBinding attributeBinding = entityBinding.getAttributeBinding( propertyName );
+ if ( attributeBinding == null ) {
+ throw new MappingException( "unknown property: " + entityName + '.' + propertyName );
+ }
+ return attributeBinding.getHibernateTypeDescriptor().getExplicitType();
+ }
+
private class MappingDefaultsImpl implements MappingDefaults {
@Override
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/SessionFactoryBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/SessionFactoryBuilderImpl.java
new file mode 100644
index 0000000000..c3ec4978eb
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/SessionFactoryBuilderImpl.java
@@ -0,0 +1,88 @@
+/*
+ * 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.metamodel.source.internal;
+
+import java.io.Serializable;
+
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.Interceptor;
+import org.hibernate.ObjectNotFoundException;
+import org.hibernate.SessionFactory;
+import org.hibernate.internal.SessionFactoryImpl;
+import org.hibernate.metamodel.SessionFactoryBuilder;
+import org.hibernate.metamodel.source.spi.MetadataImplementor;
+import org.hibernate.proxy.EntityNotFoundDelegate;
+
+/**
+ * @author Gail Badner
+ */
+public class SessionFactoryBuilderImpl implements SessionFactoryBuilder {
+ SessionFactoryOptionsImpl options;
+
+ private final MetadataImplementor metadata;
+
+ /* package-protected */
+ SessionFactoryBuilderImpl(MetadataImplementor metadata) {
+ this.metadata = metadata;
+ options = new SessionFactoryOptionsImpl();
+ }
+
+ @Override
+ public SessionFactoryBuilder with(Interceptor interceptor) {
+ this.options.interceptor = interceptor;
+ return this;
+ }
+
+ @Override
+ public SessionFactoryBuilder with(EntityNotFoundDelegate entityNotFoundDelegate) {
+ this.options.entityNotFoundDelegate = entityNotFoundDelegate;
+ return this;
+ }
+
+ @Override
+ public SessionFactory buildSessionFactory() {
+ return new SessionFactoryImpl(metadata, options, null );
+ }
+
+ private static class SessionFactoryOptionsImpl implements SessionFactory.SessionFactoryOptions {
+ private Interceptor interceptor = EmptyInterceptor.INSTANCE;
+
+ // TODO: should there be a DefaultEntityNotFoundDelegate.INSTANCE?
+ private EntityNotFoundDelegate entityNotFoundDelegate = new EntityNotFoundDelegate() {
+ public void handleEntityNotFound(String entityName, Serializable id) {
+ throw new ObjectNotFoundException( id, entityName );
+ }
+ };
+
+ @Override
+ public Interceptor getInterceptor() {
+ return interceptor;
+ }
+
+ @Override
+ public EntityNotFoundDelegate getEntityNotFoundDelegate() {
+ return entityNotFoundDelegate;
+ }
+ }
+}
\ No newline at end of file
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/spi/MetadataImplementor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/spi/MetadataImplementor.java
index 8afd249da7..0ab0f2619e 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/spi/MetadataImplementor.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/spi/MetadataImplementor.java
@@ -23,10 +23,13 @@
*/
package org.hibernate.metamodel.source.spi;
+import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.spi.FilterDefinition;
+import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.metamodel.Metadata;
+import org.hibernate.metamodel.SessionFactoryBuilder;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.IdGenerator;
@@ -40,7 +43,7 @@ import org.hibernate.type.TypeResolver;
/**
* @author Steve Ebersole
*/
-public interface MetadataImplementor extends Metadata, BindingContext {
+public interface MetadataImplementor extends Metadata, BindingContext, Mapping {
public BasicServiceRegistry getServiceRegistry();
public Database getDatabase();
@@ -63,9 +66,11 @@ public interface MetadataImplementor extends Metadata, BindingContext {
public void registerIdentifierGenerator(String name, String clazz);
- public void addNamedNativeQuery(String name, NamedSQLQueryDefinition def);
+ public void addNamedNativeQuery(NamedSQLQueryDefinition def);
- public void addNamedQuery(String name, NamedQueryDefinition def);
+ public void addNamedQuery(NamedQueryDefinition def);
+
+ public void addResultSetMapping(ResultSetMappingDefinition resultSetMappingDefinition);
public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject);
}
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 a02bada59e..82f6c457f0 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
@@ -92,6 +92,7 @@ import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Selectable;
import org.hibernate.metadata.ClassMetadata;
+import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.property.BackrefPropertyAccessor;
import org.hibernate.sql.Alias;
@@ -754,6 +755,75 @@ public abstract class AbstractEntityPersister
temporaryIdTableDDL = persistentClass.getTemporaryIdTableDDL();
}
+
+ public AbstractEntityPersister(
+ final EntityBinding entityBinding,
+ final EntityRegionAccessStrategy cacheAccessStrategy,
+ final SessionFactoryImplementor factory) throws HibernateException {
+ // TODO: Implement! Initializing final fields to make compiler happy
+ this.factory = factory;
+ this.cacheAccessStrategy = cacheAccessStrategy;
+ isLazyPropertiesCacheable = false;
+ cacheEntryStructure = null;
+ entityMetamodel = null;
+ rootTableKeyColumnNames = null;
+ rootTableKeyColumnReaders = null;
+ rootTableKeyColumnReaderTemplates = null;
+ identifierAliases = null;
+ identifierColumnSpan = -1;
+ versionColumnName = null;
+ hasFormulaProperties = false;
+ batchSize = -1;
+ hasSubselectLoadableCollections = false;
+ rowIdName = null;
+ lazyProperties = null;
+ sqlWhereString = null;
+ sqlWhereStringTemplate = null;
+ propertyColumnSpans = null;
+ propertySubclassNames = null;
+ propertyColumnAliases = null;
+ propertyColumnNames = null;
+ propertyColumnFormulaTemplates = null;
+ propertyColumnReaderTemplates = null;
+ propertyColumnWriters = null;
+ propertyColumnUpdateable = null;
+ propertyColumnInsertable = null;
+ propertyUniqueness = null;
+ propertySelectable = null;
+ lazyPropertyNames = null;
+ lazyPropertyNumbers = null;
+ lazyPropertyTypes = null;
+ lazyPropertyColumnAliases = null;
+ subclassPropertyNameClosure = null;
+ subclassPropertySubclassNameClosure = null;
+ subclassPropertyTypeClosure = null;
+ subclassPropertyFormulaTemplateClosure = null;
+ subclassPropertyColumnNameClosure = null;
+ subclassPropertyColumnReaderClosure = null;
+ subclassPropertyColumnReaderTemplateClosure = null;
+ subclassPropertyFetchModeClosure = null;
+ subclassPropertyNullabilityClosure = null;
+ propertyDefinedOnSubclass = null;
+ subclassPropertyColumnNumberClosure = null;
+ subclassPropertyFormulaNumberClosure = null;
+ subclassPropertyCascadeStyleClosure = null;
+ subclassColumnClosure = null;
+ subclassColumnLazyClosure = null;
+ subclassColumnAliasClosure = null;
+ subclassColumnSelectableClosure = null;
+ subclassColumnReaderTemplateClosure = null;
+ subclassFormulaClosure = null;
+ subclassFormulaTemplateClosure = null;
+ subclassFormulaAliasClosure = null;
+ subclassFormulaLazyClosure = null;
+ filterHelper = null;
+ loaderName = null;
+ queryLoader = null;
+ temporaryIdTableName = null;
+ temporaryIdTableDDL = null;
+ propertyMapping = null;
+ }
+
protected String generateLazySelectString() {
if ( !entityMetamodel.hasLazyProperties() ) {
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java
index 17793e33bc..9b367a5cf4 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java
@@ -47,6 +47,7 @@ import org.hibernate.mapping.Property;
import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.Table;
+import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.SelectFragment;
import org.hibernate.type.StandardBasicTypes;
@@ -492,6 +493,43 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
}
+ public JoinedSubclassEntityPersister(
+ final EntityBinding entityBinding,
+ final EntityRegionAccessStrategy cacheAccessStrategy,
+ final SessionFactoryImplementor factory,
+ final Mapping mapping) throws HibernateException {
+ super( entityBinding, cacheAccessStrategy, factory );
+ // TODO: implement!!! initializing final fields to null to make compiler happy
+ tableSpan = -1;
+ tableNames = null;
+ naturalOrderTableNames = null;
+ tableKeyColumns = null;
+ tableKeyColumnReaders = null;
+ tableKeyColumnReaderTemplates = null;
+ naturalOrderTableKeyColumns = null;
+ naturalOrderTableKeyColumnReaders = null;
+ naturalOrderTableKeyColumnReaderTemplates = null;
+ naturalOrderCascadeDeleteEnabled = null;
+ spaces = null;
+ subclassClosure = null;
+ subclassTableNameClosure = null;
+ subclassTableKeyColumnClosure= null;
+ isClassOrSuperclassTable = null;
+ naturalOrderPropertyTableNumbers = null;
+ propertyTableNumbers = null;
+ subclassPropertyTableNumberClosure = null;
+ subclassColumnTableNumberClosure = null;
+ subclassFormulaTableNumberClosure = null;
+ subclassTableSequentialSelect = null;
+ subclassTableIsLazyClosure = null;
+ discriminatorValues = null;
+ notNullColumnNames = null;
+ notNullColumnTableNumbers = null;
+ constraintOrderedTableNames = null;
+ constraintOrderedKeyColumnNames = null;
+ discriminatorSQLString = null;
+ }
+
protected boolean isSubclassTableSequentialSelect(int j) {
return subclassTableSequentialSelect[j] && !isClassOrSuperclassTable[j];
}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java
index fc6501a6b7..8585b5d718 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java
@@ -47,6 +47,7 @@ import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value;
+import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.sql.InFragment;
import org.hibernate.sql.Insert;
import org.hibernate.sql.SelectFragment;
@@ -438,6 +439,49 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
}
+ public SingleTableEntityPersister(
+ final EntityBinding entityBinding,
+ final EntityRegionAccessStrategy cacheAccessStrategy,
+ final SessionFactoryImplementor factory,
+ final Mapping mapping) throws HibernateException {
+
+ super( entityBinding, cacheAccessStrategy, factory );
+
+ //TODO: implement!!!! initializing final fields to make compiler happy...
+ joinSpan = -1;
+ qualifiedTableNames = null;
+ isInverseTable = null;
+ isNullableTable = null;
+ keyColumnNames = null;
+ cascadeDeleteEnabled = null;
+ hasSequentialSelects = false;
+ spaces = null;
+ subclassClosure = null;
+ subclassTableNameClosure = null;
+ subclassTableIsLazyClosure = null;
+ isInverseSubclassTable = null;
+ isNullableSubclassTable = null;
+ subclassTableSequentialSelect = null;
+ subclassTableKeyColumnClosure = null;
+ isClassOrSuperclassTable = null;
+ propertyTableNumbers = null;
+ subclassPropertyTableNumberClosure = null;
+ subclassColumnTableNumberClosure = null;
+ subclassFormulaTableNumberClosure = null;
+ forceDiscriminator = false;
+ discriminatorColumnName = null;
+ discriminatorColumnReaders = null;
+ discriminatorColumnReaderTemplate = null;
+ discriminatorFormula = null;
+ discriminatorFormulaTemplate = null;
+ discriminatorAlias = null;
+ discriminatorType = null;
+ discriminatorSQLValue = null;
+ discriminatorInsertable = false;
+ constraintOrderedTableNames = null;
+ constraintOrderedKeyColumnNames = null;
+ }
+
protected boolean isInverseTable(int j) {
return isInverseTable[j];
}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java
index b041286f0a..d9347ddcf4 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java
@@ -49,6 +49,7 @@ import org.hibernate.mapping.Column;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.Table;
+import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.sql.SelectFragment;
import org.hibernate.sql.SimpleSelect;
import org.hibernate.type.StandardBasicTypes;
@@ -235,6 +236,23 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
}
+ public UnionSubclassEntityPersister(
+ final EntityBinding entityBinding,
+ final EntityRegionAccessStrategy cacheAccessStrategy,
+ final SessionFactoryImplementor factory,
+ final Mapping mapping) throws HibernateException {
+ super(entityBinding, cacheAccessStrategy, factory );
+ // TODO: implement!!! initializing final fields to null to make compiler happy.
+ subquery = null;
+ tableName = null;
+ subclassClosure = null;
+ spaces = null;
+ subclassSpaces = null;
+ discriminatorSQLValue = null;
+ constraintOrderedTableNames = null;
+ constraintOrderedKeyColumnNames = null;
+ }
+
public Serializable[] getQuerySpaces() {
return subclassSpaces;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryImpl.java
index 271c78856c..fd81d4962b 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryImpl.java
@@ -34,6 +34,7 @@ import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
+import org.hibernate.metamodel.source.spi.MetadataImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.spi.PersisterClassResolver;
@@ -104,7 +105,7 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
private static final Class[] COLLECTION_PERSISTER_CONSTRUCTOR_ARGS_NEW = new Class[] {
PluralAttributeBinding.class,
CollectionRegionAccessStrategy.class,
- Configuration.class,
+ MetadataImplementor.class,
SessionFactoryImplementor.class
};
@@ -183,44 +184,44 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
@SuppressWarnings( {"unchecked"})
public CollectionPersister createCollectionPersister(
Configuration cfg,
- Collection metadata,
+ Collection collectionMetadata,
CollectionRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory) throws HibernateException {
- Class extends CollectionPersister> persisterClass = metadata.getCollectionPersisterClass();
+ Class extends CollectionPersister> persisterClass = collectionMetadata.getCollectionPersisterClass();
if ( persisterClass == null ) {
- persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getCollectionPersisterClass( metadata );
+ persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getCollectionPersisterClass( collectionMetadata );
}
- return create( persisterClass, COLLECTION_PERSISTER_CONSTRUCTOR_ARGS, cfg, metadata, cacheAccessStrategy, factory );
+ return create( persisterClass, COLLECTION_PERSISTER_CONSTRUCTOR_ARGS, cfg, collectionMetadata, cacheAccessStrategy, factory );
}
@Override
@SuppressWarnings( {"unchecked"})
-
- public CollectionPersister createCollectionPersister(Configuration cfg,
- PluralAttributeBinding metadata,
+ public CollectionPersister createCollectionPersister(MetadataImplementor metadata,
+ PluralAttributeBinding collectionMetadata,
CollectionRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory) throws HibernateException {
- Class extends CollectionPersister> persisterClass = metadata.getCollectionPersisterClass();
+ Class extends CollectionPersister> persisterClass = collectionMetadata.getCollectionPersisterClass();
if ( persisterClass == null ) {
- persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getCollectionPersisterClass( metadata );
+ persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getCollectionPersisterClass( collectionMetadata );
}
- return create( persisterClass, COLLECTION_PERSISTER_CONSTRUCTOR_ARGS_NEW, cfg, metadata, cacheAccessStrategy, factory );
+ return create( persisterClass, COLLECTION_PERSISTER_CONSTRUCTOR_ARGS_NEW, metadata, collectionMetadata, cacheAccessStrategy, factory );
}
- // TODO: change metadata arg type to PluralAttributeBinding when new metadata is integrated
+ // TODO: change collectionMetadata arg type to PluralAttributeBinding when new metadata is integrated
+ // TODO: change metadata arg type to MetadataImplementor when new metadata is integrated
private static CollectionPersister create(
Class extends CollectionPersister> persisterClass,
Class[] persisterConstructorArgs,
- Configuration cfg,
- Object metadata,
+ Object cfg,
+ Object collectionMetadata,
CollectionRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory) throws HibernateException {
try {
Constructor extends CollectionPersister> constructor = persisterClass.getConstructor( persisterConstructorArgs );
try {
- return constructor.newInstance( metadata, cacheAccessStrategy, cfg, factory );
+ return constructor.newInstance( collectionMetadata, cacheAccessStrategy, cfg, factory );
}
catch (MappingException e) {
throw e;
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/internal/StandardPersisterClassResolver.java b/hibernate-core/src/main/java/org/hibernate/persister/internal/StandardPersisterClassResolver.java
index 9c6ab9b647..e67fa86a1f 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/internal/StandardPersisterClassResolver.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/internal/StandardPersisterClassResolver.java
@@ -47,9 +47,13 @@ public class StandardPersisterClassResolver implements PersisterClassResolver {
public Class extends EntityPersister> getEntityPersisterClass(EntityBinding metadata) {
// todo : make sure this is based on an attribute kept on the metamodel in the new code, not the concrete PersistentClass impl found!
+
+ if ( metadata.isRoot() ) {
+ return singleTableEntityPersister(); // EARLY RETURN!
+ }
switch ( metadata.getInheritanceType() ) {
case JOINED: {
- joinedSubclassEntityPersister();
+ return joinedSubclassEntityPersister();
}
case SINGLE_TABLE: {
return singleTableEntityPersister();
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterFactory.java b/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterFactory.java
index b8cf709380..7cc75f8c32 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterFactory.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterFactory.java
@@ -33,6 +33,7 @@ import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
+import org.hibernate.metamodel.source.spi.MetadataImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.Service;
@@ -110,7 +111,7 @@ public interface PersisterFactory extends Service {
/**
* Create a collection persister instance.
*
- * @param cfg The configuration
+ * @param metadata The metadata
* @param model The O/R mapping metamodel definition for the collection
* @param cacheAccessStrategy The caching strategy for this collection
* @param factory The session factory
@@ -120,7 +121,7 @@ public interface PersisterFactory extends Service {
* @throws HibernateException Indicates a problem building the persister.
*/
public CollectionPersister createCollectionPersister(
- Configuration cfg,
+ MetadataImplementor metadata,
PluralAttributeBinding model,
CollectionRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory) throws HibernateException;
diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java
index 3754334ed6..6e54be196b 100644
--- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java
+++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java
@@ -33,6 +33,7 @@ import org.junit.Test;
import org.hibernate.metamodel.MetadataSources;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.source.internal.MetadataImpl;
+import org.hibernate.metamodel.source.spi.MetadataImplementor;
import org.hibernate.service.BasicServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.hibernate.service.internal.BasicServiceRegistryImpl;
@@ -74,6 +75,7 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
public void testSimpleEntityMapping() {
MetadataImpl metadata = addSourcesForSimpleEntityBinding( sources );
EntityBinding entityBinding = metadata.getEntityBinding( SimpleEntity.class.getName() );
+ assertRoot( metadata, entityBinding );
assertIdAndSimpleProperty( entityBinding );
assertNull( entityBinding.getVersioningValueBinding() );
@@ -123,7 +125,6 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
assertNotNull( entityBinding );
assertNotNull( entityBinding.getEntityIdentifier() );
assertNotNull( entityBinding.getEntityIdentifier().getValueBinding() );
- assertTrue( entityBinding.isRoot() );
AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" );
assertNotNull( idAttributeBinding );
@@ -137,4 +138,9 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
assertNotNull( nameBinding.getAttribute() );
assertNotNull( nameBinding.getValue() );
}
+
+ protected void assertRoot(MetadataImplementor metadata, EntityBinding entityBinding) {
+ assertTrue( entityBinding.isRoot() );
+ assertSame( entityBinding, metadata.getRootEntityBinding( entityBinding.getEntity().getName() ) );
+ }
}
diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/BaseAnnotationBindingTestCase.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/BaseAnnotationBindingTestCase.java
index 6ff3fc50c6..787968c82f 100644
--- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/BaseAnnotationBindingTestCase.java
+++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/BaseAnnotationBindingTestCase.java
@@ -57,6 +57,14 @@ public abstract class BaseAnnotationBindingTestCase extends BaseUnitTestCase {
}
return meta.getEntityBinding( clazz.getName() );
}
+
+ public EntityBinding getRootEntityBinding(Class> clazz) {
+ if ( meta == null ) {
+ meta = (MetadataImpl) sources.buildMetadata();
+ }
+ return meta.getRootEntityBinding( clazz.getName() );
+ }
+
}
diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/InheritanceTypeTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/InheritanceTypeTest.java
index cf914916aa..9fc6b785ea 100644
--- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/InheritanceTypeTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/InheritanceTypeTest.java
@@ -34,6 +34,7 @@ import org.hibernate.metamodel.binding.EntityBinding;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertSame;
import static junit.framework.Assert.assertTrue;
/**
@@ -44,7 +45,6 @@ public class InheritanceTypeTest extends BaseAnnotationBindingTestCase {
public void testNoInheritance() {
buildMetadataSources( SingleEntity.class );
EntityBinding entityBinding = getEntityBinding( SingleEntity.class );
- assertTrue( entityBinding.isRoot() );
assertNull( entityBinding.getEntityDiscriminator() );
}
@@ -54,10 +54,29 @@ public class InheritanceTypeTest extends BaseAnnotationBindingTestCase {
RootOfSingleTableInheritance.class, SubclassOfSingleTableInheritance.class
);
EntityBinding entityBinding = getEntityBinding( SubclassOfSingleTableInheritance.class );
- assertFalse( entityBinding.isRoot() );
assertEquals( "Wrong discriminator value", "foo", entityBinding.getDiscriminatorValue() );
}
+ @Test
+ public void testRootEntityBinding() {
+ buildMetadataSources(
+ SubclassOfSingleTableInheritance.class, SingleEntity.class, RootOfSingleTableInheritance.class
+ );
+
+ EntityBinding noInheritanceEntityBinding = getEntityBinding( SingleEntity.class );
+ EntityBinding subclassEntityBinding = getEntityBinding( SubclassOfSingleTableInheritance.class );
+ EntityBinding rootEntityBinding = getEntityBinding( RootOfSingleTableInheritance.class );
+
+ assertTrue( noInheritanceEntityBinding.isRoot() );
+ assertSame( noInheritanceEntityBinding, getRootEntityBinding( SingleEntity.class ) );
+
+ assertFalse( subclassEntityBinding.isRoot() );
+ assertSame( rootEntityBinding, getRootEntityBinding( SubclassOfSingleTableInheritance.class ) );
+
+ assertTrue( rootEntityBinding.isRoot() );
+ assertSame( rootEntityBinding, getRootEntityBinding( RootOfSingleTableInheritance.class ));
+ }
+
@Entity
class SingleEntity {
@Id
diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/internal/MetadataImplTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/internal/MetadataImplTest.java
index 607e295299..dd35e2836d 100644
--- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/internal/MetadataImplTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/internal/MetadataImplTest.java
@@ -27,14 +27,21 @@ import java.util.Iterator;
import org.junit.Test;
+import org.hibernate.EmptyInterceptor;
import org.hibernate.HibernateException;
+import org.hibernate.SessionFactory;
+import org.hibernate.metamodel.Metadata;
import org.hibernate.metamodel.MetadataSources;
+import org.hibernate.metamodel.SessionFactoryBuilder;
import org.hibernate.metamodel.binding.FetchProfile;
+import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.service.ServiceRegistryBuilder;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertSame;
import static junit.framework.Assert.assertTrue;
/**
@@ -81,6 +88,19 @@ public class MetadataImplTest extends BaseUnitTestCase {
assertFetchProfile( metadata );
}
+ @Test
+ public void testGettingSessionFactoryBuilder() {
+ MetadataSources sources = new MetadataSources( new ServiceRegistryBuilder().buildServiceRegistry() );
+ Metadata metadata = sources.buildMetadata();
+
+ SessionFactoryBuilder sessionFactoryBuilder = metadata.getSessionFactoryBuilder();
+ assertNotNull( sessionFactoryBuilder );
+ assertTrue( SessionFactoryBuilderImpl.class.isInstance( sessionFactoryBuilder ) );
+
+ SessionFactory sessionFactory = metadata.buildSessionFactory();
+ assertNotNull( sessionFactory );
+ }
+
private void assertFetchProfile(MetadataImpl metadata) {
Iterator profiles = metadata.getFetchProfiles().iterator();
assertTrue( profiles.hasNext() );
diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/internal/SessionFactoryBuilderImplTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/internal/SessionFactoryBuilderImplTest.java
new file mode 100644
index 0000000000..75c5ec0ef1
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/internal/SessionFactoryBuilderImplTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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.source.internal;
+
+import java.io.Serializable;
+import java.util.Iterator;
+
+import org.junit.Test;
+
+import org.hibernate.CallbackException;
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.EntityMode;
+import org.hibernate.Interceptor;
+import org.hibernate.ObjectNotFoundException;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.metamodel.MetadataSources;
+import org.hibernate.metamodel.SessionFactoryBuilder;
+import org.hibernate.proxy.EntityNotFoundDelegate;
+import org.hibernate.service.ServiceRegistryBuilder;
+import org.hibernate.testing.junit4.BaseUnitTestCase;
+import org.hibernate.type.Type;
+
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertSame;
+import static junit.framework.Assert.assertTrue;
+
+/**
+ * @author Gail Badner
+ */
+public class SessionFactoryBuilderImplTest extends BaseUnitTestCase {
+
+ @Test
+ public void testGettingSessionFactoryBuilder() {
+ SessionFactoryBuilder sessionFactoryBuilder = getSessionFactoryBuilder();
+ assertNotNull( sessionFactoryBuilder );
+ assertTrue( SessionFactoryBuilderImpl.class.isInstance( sessionFactoryBuilder ) );
+ }
+
+ @Test
+ public void testBuildSessionFactoryWithDefaultOptions() {
+ SessionFactoryBuilder sessionFactoryBuilder = getSessionFactoryBuilder();
+ SessionFactory sessionFactory = sessionFactoryBuilder.buildSessionFactory();
+ assertSame( EmptyInterceptor.INSTANCE, sessionFactory.getSessionFactoryOptions().getInterceptor() );
+ assertTrue( EntityNotFoundDelegate.class.isInstance(
+ sessionFactory.getSessionFactoryOptions().getEntityNotFoundDelegate()
+ ) );
+ }
+
+ @Test
+ public void testBuildSessionFactoryWithUpdatedOptions() {
+ SessionFactoryBuilder sessionFactoryBuilder = getSessionFactoryBuilder();
+ Interceptor interceptor = new AnInterceptor();
+ EntityNotFoundDelegate entityNotFoundDelegate = new EntityNotFoundDelegate() {
+ @Override
+ public void handleEntityNotFound(String entityName, Serializable id) {
+ throw new ObjectNotFoundException( id, entityName );
+ }
+ };
+ sessionFactoryBuilder.with( interceptor );
+ sessionFactoryBuilder.with( entityNotFoundDelegate );
+ SessionFactory sessionFactory = sessionFactoryBuilder.buildSessionFactory();
+ assertSame( interceptor, sessionFactory.getSessionFactoryOptions().getInterceptor() );
+ assertSame( entityNotFoundDelegate, sessionFactory.getSessionFactoryOptions().getEntityNotFoundDelegate() );
+ }
+
+ private SessionFactoryBuilder getSessionFactoryBuilder() {
+ MetadataSources sources = new MetadataSources( new ServiceRegistryBuilder().buildServiceRegistry() );
+ sources.addAnnotatedClass( SimpleEntity.class );
+ MetadataImpl metadata = (MetadataImpl) sources.buildMetadata();
+ return metadata.getSessionFactoryBuilder();
+ }
+
+ private static class AnInterceptor implements Interceptor {
+ private static final Interceptor INSTANCE = EmptyInterceptor.INSTANCE;
+
+ @Override
+ public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
+ throws CallbackException {
+ return INSTANCE.onLoad( entity, id, state, propertyNames, types );
+ }
+
+ @Override
+ public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types)
+ throws CallbackException {
+ return INSTANCE.onFlushDirty( entity, id, currentState, previousState, propertyNames, types );
+ }
+
+ @Override
+ public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
+ throws CallbackException {
+ return INSTANCE.onSave( entity, id, state, propertyNames, types );
+ }
+
+ @Override
+ public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
+ throws CallbackException {
+ INSTANCE.onDelete( entity, id, state, propertyNames, types );
+ }
+
+ @Override
+ public void onCollectionRecreate(Object collection, Serializable key) throws CallbackException {
+ INSTANCE.onCollectionRecreate( collection, key );
+ }
+
+ @Override
+ public void onCollectionRemove(Object collection, Serializable key) throws CallbackException {
+ INSTANCE.onCollectionRemove( collection, key );
+ }
+
+ @Override
+ public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException {
+ INSTANCE.onCollectionUpdate( collection, key );
+ }
+
+ @Override
+ public void preFlush(Iterator entities) throws CallbackException {
+ INSTANCE.preFlush( entities );
+ }
+
+ @Override
+ public void postFlush(Iterator entities) throws CallbackException {
+ INSTANCE.postFlush( entities );
+ }
+
+ @Override
+ public Boolean isTransient(Object entity) {
+ return INSTANCE.isTransient( entity );
+ }
+
+ @Override
+ public int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
+ return INSTANCE.findDirty( entity, id, currentState, previousState, propertyNames, types );
+ }
+
+ @Override
+ public Object instantiate(String entityName, EntityMode entityMode, Serializable id)
+ throws CallbackException {
+ return INSTANCE.instantiate( entityName, entityMode, id );
+ }
+
+ @Override
+ public String getEntityName(Object object) throws CallbackException {
+ return INSTANCE.getEntityName( object );
+ }
+
+ @Override
+ public Object getEntity(String entityName, Serializable id) throws CallbackException {
+ return INSTANCE.getEntity( entityName, id );
+ }
+
+ @Override
+ public void afterTransactionBegin(Transaction tx) {
+ INSTANCE.afterTransactionBegin( tx );
+ }
+
+ @Override
+ public void beforeTransactionCompletion(Transaction tx) {
+ INSTANCE.beforeTransactionCompletion( tx );
+ }
+
+ @Override
+ public void afterTransactionCompletion(Transaction tx) {
+ INSTANCE.afterTransactionCompletion( tx );
+ }
+
+ @Override
+ public String onPrepareStatement(String sql) {
+ return INSTANCE.onPrepareStatement( sql );
+ }
+ }
+}
+
+
diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/internal/SimpleEntity.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/internal/SimpleEntity.java
new file mode 100644
index 0000000000..c6f1c5c763
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/internal/SimpleEntity.java
@@ -0,0 +1,60 @@
+/*
+ * 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.metamodel.source.internal;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * @author Steve Ebersole
+ */
+@Entity
+public class SimpleEntity {
+ @Id
+ private Long id;
+ private String name;
+
+ public SimpleEntity() {
+ }
+
+ public SimpleEntity(String name) {
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}