HHH-8285 Initial JPA 2.1 entity graph support (EntityManager.find())
This commit is contained in:
parent
dd28adb1ae
commit
b3871f319b
|
@ -35,13 +35,13 @@ public interface AvailableSettings {
|
|||
*
|
||||
* @see #SESSION_FACTORY_NAME_IS_JNDI
|
||||
*/
|
||||
public static final String SESSION_FACTORY_NAME = "hibernate.session_factory_name";
|
||||
String SESSION_FACTORY_NAME = "hibernate.session_factory_name";
|
||||
|
||||
/**
|
||||
* Does the value defined by {@link #SESSION_FACTORY_NAME} represent a {@literal JNDI} namespace into which
|
||||
* the {@link org.hibernate.SessionFactory} should be bound?
|
||||
*/
|
||||
public static final String SESSION_FACTORY_NAME_IS_JNDI = "hibernate.session_factory_name_is_jndi";
|
||||
String SESSION_FACTORY_NAME_IS_JNDI = "hibernate.session_factory_name_is_jndi";
|
||||
|
||||
/**
|
||||
* Names the {@link org.hibernate.engine.jdbc.connections.spi.ConnectionProvider} to use for obtaining
|
||||
|
@ -50,17 +50,17 @@ public interface AvailableSettings {
|
|||
* reference to the {@link org.hibernate.engine.jdbc.connections.spi.ConnectionProvider} implementation
|
||||
* class.
|
||||
*/
|
||||
public static final String CONNECTION_PROVIDER ="hibernate.connection.provider_class";
|
||||
String CONNECTION_PROVIDER ="hibernate.connection.provider_class";
|
||||
|
||||
/**
|
||||
* Names the {@literal JDBC} driver class
|
||||
*/
|
||||
public static final String DRIVER ="hibernate.connection.driver_class";
|
||||
String DRIVER ="hibernate.connection.driver_class";
|
||||
|
||||
/**
|
||||
* Names the {@literal JDBC} connection url.
|
||||
*/
|
||||
public static final String URL ="hibernate.connection.url";
|
||||
String URL ="hibernate.connection.url";
|
||||
|
||||
/**
|
||||
* Names the connection user. This might mean one of 2 things in out-of-the-box Hibernate
|
||||
|
@ -69,210 +69,210 @@ public interface AvailableSettings {
|
|||
* <li>The username used to obtain a JDBC connection from a data source</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static final String USER ="hibernate.connection.username";
|
||||
String USER ="hibernate.connection.username";
|
||||
|
||||
/**
|
||||
* Names the connection password. See usage discussion on {@link #USER}
|
||||
*/
|
||||
public static final String PASS ="hibernate.connection.password";
|
||||
String PASS ="hibernate.connection.password";
|
||||
|
||||
/**
|
||||
* Names the {@literal JDBC} transaction isolation level
|
||||
*/
|
||||
public static final String ISOLATION ="hibernate.connection.isolation";
|
||||
String ISOLATION ="hibernate.connection.isolation";
|
||||
|
||||
/**
|
||||
* Names the {@literal JDBC} autocommit mode
|
||||
*/
|
||||
public static final String AUTOCOMMIT ="hibernate.connection.autocommit";
|
||||
String AUTOCOMMIT ="hibernate.connection.autocommit";
|
||||
|
||||
/**
|
||||
* Maximum number of inactive connections for the built-in Hibernate connection pool.
|
||||
*/
|
||||
public static final String POOL_SIZE ="hibernate.connection.pool_size";
|
||||
String POOL_SIZE ="hibernate.connection.pool_size";
|
||||
|
||||
/**
|
||||
* Names a {@link javax.sql.DataSource}. Can either reference a {@link javax.sql.DataSource} instance or
|
||||
* a {@literal JNDI} name under which to locate the {@link javax.sql.DataSource}.
|
||||
*/
|
||||
public static final String DATASOURCE ="hibernate.connection.datasource";
|
||||
String DATASOURCE ="hibernate.connection.datasource";
|
||||
|
||||
/**
|
||||
* Names a prefix used to define arbitrary JDBC connection properties. These properties are passed along to
|
||||
* the {@literal JDBC} provider when creating a connection.
|
||||
*/
|
||||
public static final String CONNECTION_PREFIX = "hibernate.connection";
|
||||
String CONNECTION_PREFIX = "hibernate.connection";
|
||||
|
||||
/**
|
||||
* Names the {@literal JNDI} {@link javax.naming.InitialContext} class.
|
||||
*
|
||||
* @see javax.naming.Context#INITIAL_CONTEXT_FACTORY
|
||||
*/
|
||||
public static final String JNDI_CLASS ="hibernate.jndi.class";
|
||||
String JNDI_CLASS ="hibernate.jndi.class";
|
||||
|
||||
/**
|
||||
* Names the {@literal JNDI} provider/connection url
|
||||
*
|
||||
* @see javax.naming.Context#PROVIDER_URL
|
||||
*/
|
||||
public static final String JNDI_URL ="hibernate.jndi.url";
|
||||
String JNDI_URL ="hibernate.jndi.url";
|
||||
|
||||
/**
|
||||
* Names a prefix used to define arbitrary {@literal JNDI} {@link javax.naming.InitialContext} properties. These
|
||||
* properties are passed along to {@link javax.naming.InitialContext#InitialContext(java.util.Hashtable)}
|
||||
*/
|
||||
public static final String JNDI_PREFIX = "hibernate.jndi";
|
||||
String JNDI_PREFIX = "hibernate.jndi";
|
||||
|
||||
/**
|
||||
* Names the Hibernate {@literal SQL} {@link org.hibernate.dialect.Dialect} class
|
||||
*/
|
||||
public static final String DIALECT ="hibernate.dialect";
|
||||
String DIALECT ="hibernate.dialect";
|
||||
|
||||
/**
|
||||
* Names any additional {@link org.hibernate.engine.jdbc.dialect.spi.DialectResolver} implementations to
|
||||
* register with the standard {@link org.hibernate.engine.jdbc.dialect.spi.DialectFactory}.
|
||||
*/
|
||||
public static final String DIALECT_RESOLVERS = "hibernate.dialect_resolvers";
|
||||
String DIALECT_RESOLVERS = "hibernate.dialect_resolvers";
|
||||
|
||||
|
||||
/**
|
||||
* A default database schema (owner) name to use for unqualified tablenames
|
||||
*/
|
||||
public static final String DEFAULT_SCHEMA = "hibernate.default_schema";
|
||||
String DEFAULT_SCHEMA = "hibernate.default_schema";
|
||||
/**
|
||||
* A default database catalog name to use for unqualified tablenames
|
||||
*/
|
||||
public static final String DEFAULT_CATALOG = "hibernate.default_catalog";
|
||||
String DEFAULT_CATALOG = "hibernate.default_catalog";
|
||||
|
||||
/**
|
||||
* Enable logging of generated SQL to the console
|
||||
*/
|
||||
public static final String SHOW_SQL ="hibernate.show_sql";
|
||||
String SHOW_SQL ="hibernate.show_sql";
|
||||
/**
|
||||
* Enable formatting of SQL logged to the console
|
||||
*/
|
||||
public static final String FORMAT_SQL ="hibernate.format_sql";
|
||||
String FORMAT_SQL ="hibernate.format_sql";
|
||||
/**
|
||||
* Add comments to the generated SQL
|
||||
*/
|
||||
public static final String USE_SQL_COMMENTS ="hibernate.use_sql_comments";
|
||||
String USE_SQL_COMMENTS ="hibernate.use_sql_comments";
|
||||
/**
|
||||
* Maximum depth of outer join fetching
|
||||
*/
|
||||
public static final String MAX_FETCH_DEPTH = "hibernate.max_fetch_depth";
|
||||
String MAX_FETCH_DEPTH = "hibernate.max_fetch_depth";
|
||||
/**
|
||||
* The default batch size for batch fetching
|
||||
*/
|
||||
public static final String DEFAULT_BATCH_FETCH_SIZE = "hibernate.default_batch_fetch_size";
|
||||
String DEFAULT_BATCH_FETCH_SIZE = "hibernate.default_batch_fetch_size";
|
||||
/**
|
||||
* Use <tt>java.io</tt> streams to read / write binary data from / to JDBC
|
||||
*/
|
||||
public static final String USE_STREAMS_FOR_BINARY = "hibernate.jdbc.use_streams_for_binary";
|
||||
String USE_STREAMS_FOR_BINARY = "hibernate.jdbc.use_streams_for_binary";
|
||||
/**
|
||||
* Use JDBC scrollable <tt>ResultSet</tt>s. This property is only necessary when there is
|
||||
* no <tt>ConnectionProvider</tt>, ie. the user is supplying JDBC connections.
|
||||
*/
|
||||
public static final String USE_SCROLLABLE_RESULTSET = "hibernate.jdbc.use_scrollable_resultset";
|
||||
String USE_SCROLLABLE_RESULTSET = "hibernate.jdbc.use_scrollable_resultset";
|
||||
/**
|
||||
* Tells the JDBC driver to attempt to retrieve row Id with the JDBC 3.0 PreparedStatement.getGeneratedKeys()
|
||||
* method. In general, performance will be better if this property is set to true and the underlying
|
||||
* JDBC driver supports getGeneratedKeys().
|
||||
*/
|
||||
public static final String USE_GET_GENERATED_KEYS = "hibernate.jdbc.use_get_generated_keys";
|
||||
String USE_GET_GENERATED_KEYS = "hibernate.jdbc.use_get_generated_keys";
|
||||
/**
|
||||
* Gives the JDBC driver a hint as to the number of rows that should be fetched from the database
|
||||
* when more rows are needed. If <tt>0</tt>, JDBC driver default settings will be used.
|
||||
*/
|
||||
public static final String STATEMENT_FETCH_SIZE = "hibernate.jdbc.fetch_size";
|
||||
String STATEMENT_FETCH_SIZE = "hibernate.jdbc.fetch_size";
|
||||
/**
|
||||
* Maximum JDBC batch size. A nonzero value enables batch updates.
|
||||
*/
|
||||
public static final String STATEMENT_BATCH_SIZE = "hibernate.jdbc.batch_size";
|
||||
String STATEMENT_BATCH_SIZE = "hibernate.jdbc.batch_size";
|
||||
/**
|
||||
* Select a custom batcher.
|
||||
*/
|
||||
public static final String BATCH_STRATEGY = "hibernate.jdbc.factory_class";
|
||||
String BATCH_STRATEGY = "hibernate.jdbc.factory_class";
|
||||
/**
|
||||
* Should versioned data be included in batching?
|
||||
*/
|
||||
public static final String BATCH_VERSIONED_DATA = "hibernate.jdbc.batch_versioned_data";
|
||||
String BATCH_VERSIONED_DATA = "hibernate.jdbc.batch_versioned_data";
|
||||
/**
|
||||
* An XSLT resource used to generate "custom" XML
|
||||
*/
|
||||
public static final String OUTPUT_STYLESHEET ="hibernate.xml.output_stylesheet";
|
||||
String OUTPUT_STYLESHEET ="hibernate.xml.output_stylesheet";
|
||||
|
||||
/**
|
||||
* Maximum size of C3P0 connection pool
|
||||
*/
|
||||
public static final String C3P0_MAX_SIZE = "hibernate.c3p0.max_size";
|
||||
String C3P0_MAX_SIZE = "hibernate.c3p0.max_size";
|
||||
/**
|
||||
* Minimum size of C3P0 connection pool
|
||||
*/
|
||||
public static final String C3P0_MIN_SIZE = "hibernate.c3p0.min_size";
|
||||
String C3P0_MIN_SIZE = "hibernate.c3p0.min_size";
|
||||
|
||||
/**
|
||||
* Maximum idle time for C3P0 connection pool
|
||||
*/
|
||||
public static final String C3P0_TIMEOUT = "hibernate.c3p0.timeout";
|
||||
String C3P0_TIMEOUT = "hibernate.c3p0.timeout";
|
||||
/**
|
||||
* Maximum size of C3P0 statement cache
|
||||
*/
|
||||
public static final String C3P0_MAX_STATEMENTS = "hibernate.c3p0.max_statements";
|
||||
String C3P0_MAX_STATEMENTS = "hibernate.c3p0.max_statements";
|
||||
/**
|
||||
* Number of connections acquired when pool is exhausted
|
||||
*/
|
||||
public static final String C3P0_ACQUIRE_INCREMENT = "hibernate.c3p0.acquire_increment";
|
||||
String C3P0_ACQUIRE_INCREMENT = "hibernate.c3p0.acquire_increment";
|
||||
/**
|
||||
* Idle time before a C3P0 pooled connection is validated
|
||||
*/
|
||||
public static final String C3P0_IDLE_TEST_PERIOD = "hibernate.c3p0.idle_test_period";
|
||||
String C3P0_IDLE_TEST_PERIOD = "hibernate.c3p0.idle_test_period";
|
||||
|
||||
/**
|
||||
* Proxool/Hibernate property prefix
|
||||
* @deprecated Use {@link #PROXOOL_CONFIG_PREFIX} instead
|
||||
*/
|
||||
public static final String PROXOOL_PREFIX = "hibernate.proxool";
|
||||
String PROXOOL_PREFIX = "hibernate.proxool";
|
||||
/**
|
||||
* Proxool property to configure the Proxool Provider using an XML (<tt>/path/to/file.xml</tt>)
|
||||
*/
|
||||
public static final String PROXOOL_XML = "hibernate.proxool.xml";
|
||||
String PROXOOL_XML = "hibernate.proxool.xml";
|
||||
/**
|
||||
* Proxool property to configure the Proxool Provider using a properties file (<tt>/path/to/proxool.properties</tt>)
|
||||
*/
|
||||
public static final String PROXOOL_PROPERTIES = "hibernate.proxool.properties";
|
||||
String PROXOOL_PROPERTIES = "hibernate.proxool.properties";
|
||||
/**
|
||||
* Proxool property to configure the Proxool Provider from an already existing pool (<tt>true</tt> / <tt>false</tt>)
|
||||
*/
|
||||
public static final String PROXOOL_EXISTING_POOL = "hibernate.proxool.existing_pool";
|
||||
String PROXOOL_EXISTING_POOL = "hibernate.proxool.existing_pool";
|
||||
/**
|
||||
* Proxool property with the Proxool pool alias to use
|
||||
* (Required for <tt>PROXOOL_EXISTING_POOL</tt>, <tt>PROXOOL_PROPERTIES</tt>, or
|
||||
* <tt>PROXOOL_XML</tt>)
|
||||
*/
|
||||
public static final String PROXOOL_POOL_ALIAS = "hibernate.proxool.pool_alias";
|
||||
String PROXOOL_POOL_ALIAS = "hibernate.proxool.pool_alias";
|
||||
|
||||
/**
|
||||
* Enable automatic session close at end of transaction
|
||||
*/
|
||||
public static final String AUTO_CLOSE_SESSION = "hibernate.transaction.auto_close_session";
|
||||
String AUTO_CLOSE_SESSION = "hibernate.transaction.auto_close_session";
|
||||
/**
|
||||
* Enable automatic flush during the JTA <tt>beforeCompletion()</tt> callback
|
||||
*/
|
||||
public static final String FLUSH_BEFORE_COMPLETION = "hibernate.transaction.flush_before_completion";
|
||||
String FLUSH_BEFORE_COMPLETION = "hibernate.transaction.flush_before_completion";
|
||||
/**
|
||||
* Specifies how Hibernate should release JDBC connections.
|
||||
*/
|
||||
public static final String RELEASE_CONNECTIONS = "hibernate.connection.release_mode";
|
||||
String RELEASE_CONNECTIONS = "hibernate.connection.release_mode";
|
||||
/**
|
||||
* Context scoping impl for {@link org.hibernate.SessionFactory#getCurrentSession()} processing.
|
||||
*/
|
||||
public static final String CURRENT_SESSION_CONTEXT_CLASS = "hibernate.current_session_context_class";
|
||||
String CURRENT_SESSION_CONTEXT_CLASS = "hibernate.current_session_context_class";
|
||||
|
||||
/**
|
||||
* Names the implementation of {@link org.hibernate.engine.transaction.spi.TransactionFactory} to use for
|
||||
* creating {@link org.hibernate.Transaction} instances
|
||||
*/
|
||||
public static final String TRANSACTION_STRATEGY = "hibernate.transaction.factory_class";
|
||||
String TRANSACTION_STRATEGY = "hibernate.transaction.factory_class";
|
||||
|
||||
/**
|
||||
* Names the {@link org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform} implementation to use for integrating
|
||||
|
@ -280,91 +280,91 @@ public interface AvailableSettings {
|
|||
* instance or the name of the {@link org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform} implementation class
|
||||
* @since 4.0
|
||||
*/
|
||||
public static final String JTA_PLATFORM = "hibernate.transaction.jta.platform";
|
||||
String JTA_PLATFORM = "hibernate.transaction.jta.platform";
|
||||
|
||||
/**
|
||||
* Names the {@link org.hibernate.engine.transaction.jta.platform.spi.JtaPlatformResolver} implementation to use.
|
||||
* @since 4.3
|
||||
*/
|
||||
public static final String JTA_PLATFORM_RESOLVER = "hibernate.transaction.jta.platform_resolver";
|
||||
String JTA_PLATFORM_RESOLVER = "hibernate.transaction.jta.platform_resolver";
|
||||
|
||||
/**
|
||||
* The {@link org.hibernate.cache.spi.RegionFactory} implementation class
|
||||
*/
|
||||
public static final String CACHE_REGION_FACTORY = "hibernate.cache.region.factory_class";
|
||||
String CACHE_REGION_FACTORY = "hibernate.cache.region.factory_class";
|
||||
|
||||
/**
|
||||
* The <tt>CacheProvider</tt> implementation class
|
||||
*/
|
||||
public static final String CACHE_PROVIDER_CONFIG = "hibernate.cache.provider_configuration_file_resource_path";
|
||||
String CACHE_PROVIDER_CONFIG = "hibernate.cache.provider_configuration_file_resource_path";
|
||||
/**
|
||||
* The <tt>CacheProvider</tt> JNDI namespace, if pre-bound to JNDI.
|
||||
*/
|
||||
public static final String CACHE_NAMESPACE = "hibernate.cache.jndi";
|
||||
String CACHE_NAMESPACE = "hibernate.cache.jndi";
|
||||
/**
|
||||
* Enable the query cache (disabled by default)
|
||||
*/
|
||||
public static final String USE_QUERY_CACHE = "hibernate.cache.use_query_cache";
|
||||
String USE_QUERY_CACHE = "hibernate.cache.use_query_cache";
|
||||
/**
|
||||
* The <tt>QueryCacheFactory</tt> implementation class.
|
||||
*/
|
||||
public static final String QUERY_CACHE_FACTORY = "hibernate.cache.query_cache_factory";
|
||||
String QUERY_CACHE_FACTORY = "hibernate.cache.query_cache_factory";
|
||||
/**
|
||||
* Enable the second-level cache (enabled by default)
|
||||
*/
|
||||
public static final String USE_SECOND_LEVEL_CACHE = "hibernate.cache.use_second_level_cache";
|
||||
String USE_SECOND_LEVEL_CACHE = "hibernate.cache.use_second_level_cache";
|
||||
/**
|
||||
* Optimize the cache for minimal puts instead of minimal gets
|
||||
*/
|
||||
public static final String USE_MINIMAL_PUTS = "hibernate.cache.use_minimal_puts";
|
||||
String USE_MINIMAL_PUTS = "hibernate.cache.use_minimal_puts";
|
||||
/**
|
||||
* The <tt>CacheProvider</tt> region name prefix
|
||||
*/
|
||||
public static final String CACHE_REGION_PREFIX = "hibernate.cache.region_prefix";
|
||||
String CACHE_REGION_PREFIX = "hibernate.cache.region_prefix";
|
||||
/**
|
||||
* Enable use of structured second-level cache entries
|
||||
*/
|
||||
public static final String USE_STRUCTURED_CACHE = "hibernate.cache.use_structured_entries";
|
||||
String USE_STRUCTURED_CACHE = "hibernate.cache.use_structured_entries";
|
||||
/**
|
||||
* Enables the automatic eviction of a bi-directional association's collection cache when an element in the
|
||||
* ManyToOne collection is added/updated/removed without properly managing the change on the OneToMany side.
|
||||
*/
|
||||
public static final String AUTO_EVICT_COLLECTION_CACHE = "hibernate.cache.auto_evict_collection_cache";
|
||||
String AUTO_EVICT_COLLECTION_CACHE = "hibernate.cache.auto_evict_collection_cache";
|
||||
/**
|
||||
* Enable statistics collection
|
||||
*/
|
||||
public static final String GENERATE_STATISTICS = "hibernate.generate_statistics";
|
||||
String GENERATE_STATISTICS = "hibernate.generate_statistics";
|
||||
|
||||
public static final String USE_IDENTIFIER_ROLLBACK = "hibernate.use_identifier_rollback";
|
||||
String USE_IDENTIFIER_ROLLBACK = "hibernate.use_identifier_rollback";
|
||||
|
||||
/**
|
||||
* Use bytecode libraries optimized property access
|
||||
*/
|
||||
public static final String USE_REFLECTION_OPTIMIZER = "hibernate.bytecode.use_reflection_optimizer";
|
||||
String USE_REFLECTION_OPTIMIZER = "hibernate.bytecode.use_reflection_optimizer";
|
||||
|
||||
/**
|
||||
* The classname of the HQL query parser factory
|
||||
*/
|
||||
public static final String QUERY_TRANSLATOR = "hibernate.query.factory_class";
|
||||
String QUERY_TRANSLATOR = "hibernate.query.factory_class";
|
||||
|
||||
/**
|
||||
* A comma-separated list of token substitutions to use when translating a Hibernate
|
||||
* query to SQL
|
||||
*/
|
||||
public static final String QUERY_SUBSTITUTIONS = "hibernate.query.substitutions";
|
||||
String QUERY_SUBSTITUTIONS = "hibernate.query.substitutions";
|
||||
|
||||
/**
|
||||
* Should named queries be checked during startup (the default is enabled).
|
||||
* <p/>
|
||||
* Mainly intended for test environments.
|
||||
*/
|
||||
public static final String QUERY_STARTUP_CHECKING = "hibernate.query.startup_check";
|
||||
String QUERY_STARTUP_CHECKING = "hibernate.query.startup_check";
|
||||
|
||||
/**
|
||||
* Auto export/update schema using hbm2ddl tool. Valid values are <tt>update</tt>,
|
||||
* <tt>create</tt>, <tt>create-drop</tt> and <tt>validate</tt>.
|
||||
*/
|
||||
public static final String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
|
||||
String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
|
||||
|
||||
/**
|
||||
* Comma-separated names of the optional files containing SQL DML statements executed
|
||||
|
@ -377,7 +377,7 @@ public interface AvailableSettings {
|
|||
*
|
||||
* The default value is <tt>/import.sql</tt>
|
||||
*/
|
||||
public static final String HBM2DDL_IMPORT_FILES = "hibernate.hbm2ddl.import_files";
|
||||
String HBM2DDL_IMPORT_FILES = "hibernate.hbm2ddl.import_files";
|
||||
|
||||
/**
|
||||
* {@link String} reference to {@link org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor} implementation class.
|
||||
|
@ -385,46 +385,46 @@ public interface AvailableSettings {
|
|||
*
|
||||
* The default value is <tt>org.hibernate.tool.hbm2ddl.SingleLineSqlCommandExtractor</tt>.
|
||||
*/
|
||||
public static final String HBM2DDL_IMPORT_FILES_SQL_EXTRACTOR = "hibernate.hbm2ddl.import_files_sql_extractor";
|
||||
String HBM2DDL_IMPORT_FILES_SQL_EXTRACTOR = "hibernate.hbm2ddl.import_files_sql_extractor";
|
||||
|
||||
/**
|
||||
* The {@link org.hibernate.exception.spi.SQLExceptionConverter} to use for converting SQLExceptions
|
||||
* to Hibernate's JDBCException hierarchy. The default is to use the configured
|
||||
* {@link org.hibernate.dialect.Dialect}'s preferred SQLExceptionConverter.
|
||||
*/
|
||||
public static final String SQL_EXCEPTION_CONVERTER = "hibernate.jdbc.sql_exception_converter";
|
||||
String SQL_EXCEPTION_CONVERTER = "hibernate.jdbc.sql_exception_converter";
|
||||
|
||||
/**
|
||||
* Enable wrapping of JDBC result sets in order to speed up column name lookups for
|
||||
* broken JDBC drivers
|
||||
*/
|
||||
public static final String WRAP_RESULT_SETS = "hibernate.jdbc.wrap_result_sets";
|
||||
String WRAP_RESULT_SETS = "hibernate.jdbc.wrap_result_sets";
|
||||
|
||||
/**
|
||||
* Enable ordering of update statements by primary key value
|
||||
*/
|
||||
public static final String ORDER_UPDATES = "hibernate.order_updates";
|
||||
String ORDER_UPDATES = "hibernate.order_updates";
|
||||
|
||||
/**
|
||||
* Enable ordering of insert statements for the purpose of more efficient JDBC batching.
|
||||
*/
|
||||
public static final String ORDER_INSERTS = "hibernate.order_inserts";
|
||||
String ORDER_INSERTS = "hibernate.order_inserts";
|
||||
|
||||
/**
|
||||
* Default precedence of null values in {@code ORDER BY} clause. Supported options: {@code none} (default),
|
||||
* {@code first}, {@code last}.
|
||||
*/
|
||||
public static final String DEFAULT_NULL_ORDERING = "hibernate.order_by.default_null_ordering";
|
||||
String DEFAULT_NULL_ORDERING = "hibernate.order_by.default_null_ordering";
|
||||
|
||||
/**
|
||||
* The EntityMode in which set the Session opened from the SessionFactory.
|
||||
*/
|
||||
public static final String DEFAULT_ENTITY_MODE = "hibernate.default_entity_mode";
|
||||
String DEFAULT_ENTITY_MODE = "hibernate.default_entity_mode";
|
||||
|
||||
/**
|
||||
* Should all database identifiers be quoted.
|
||||
*/
|
||||
public static final String GLOBALLY_QUOTED_IDENTIFIERS = "hibernate.globally_quoted_identifiers";
|
||||
String GLOBALLY_QUOTED_IDENTIFIERS = "hibernate.globally_quoted_identifiers";
|
||||
|
||||
/**
|
||||
* Enable nullability checking.
|
||||
|
@ -432,32 +432,32 @@ public interface AvailableSettings {
|
|||
* Default to false if Bean Validation is present in the classpath and Hibernate Annotations is used,
|
||||
* true otherwise.
|
||||
*/
|
||||
public static final String CHECK_NULLABILITY = "hibernate.check_nullability";
|
||||
String CHECK_NULLABILITY = "hibernate.check_nullability";
|
||||
|
||||
|
||||
public static final String BYTECODE_PROVIDER = "hibernate.bytecode.provider";
|
||||
String BYTECODE_PROVIDER = "hibernate.bytecode.provider";
|
||||
|
||||
public static final String JPAQL_STRICT_COMPLIANCE= "hibernate.query.jpaql_strict_compliance";
|
||||
String JPAQL_STRICT_COMPLIANCE= "hibernate.query.jpaql_strict_compliance";
|
||||
|
||||
/**
|
||||
* When using pooled {@link org.hibernate.id.enhanced.Optimizer optimizers}, prefer interpreting the
|
||||
* database value as the lower (lo) boundary. The default is to interpret it as the high boundary.
|
||||
*/
|
||||
public static final String PREFER_POOLED_VALUES_LO = "hibernate.id.optimizer.pooled.prefer_lo";
|
||||
String PREFER_POOLED_VALUES_LO = "hibernate.id.optimizer.pooled.prefer_lo";
|
||||
|
||||
/**
|
||||
* The maximum number of strong references maintained by {@link org.hibernate.engine.query.spi.QueryPlanCache}. Default is 128.
|
||||
* @deprecated in favor of {@link #QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String QUERY_PLAN_CACHE_MAX_STRONG_REFERENCES = "hibernate.query.plan_cache_max_strong_references";
|
||||
String QUERY_PLAN_CACHE_MAX_STRONG_REFERENCES = "hibernate.query.plan_cache_max_strong_references";
|
||||
|
||||
/**
|
||||
* The maximum number of soft references maintained by {@link org.hibernate.engine.query.spi.QueryPlanCache}. Default is 2048.
|
||||
* @deprecated in favor of {@link #QUERY_PLAN_CACHE_MAX_SIZE}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String QUERY_PLAN_CACHE_MAX_SOFT_REFERENCES = "hibernate.query.plan_cache_max_soft_references";
|
||||
String QUERY_PLAN_CACHE_MAX_SOFT_REFERENCES = "hibernate.query.plan_cache_max_soft_references";
|
||||
|
||||
/**
|
||||
* The maximum number of entries including:
|
||||
|
@ -469,18 +469,18 @@ public interface AvailableSettings {
|
|||
*
|
||||
* maintained by {@link org.hibernate.engine.query.spi.QueryPlanCache}. Default is 2048.
|
||||
*/
|
||||
public static final String QUERY_PLAN_CACHE_MAX_SIZE = "hibernate.query.plan_cache_max_size";
|
||||
String QUERY_PLAN_CACHE_MAX_SIZE = "hibernate.query.plan_cache_max_size";
|
||||
|
||||
/**
|
||||
* The maximum number of {@link org.hibernate.engine.query.spi.ParameterMetadata} maintained
|
||||
* by {@link org.hibernate.engine.query.spi.QueryPlanCache}. Default is 128.
|
||||
*/
|
||||
public static final String QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE = "hibernate.query.plan_parameter_metadata_max_size";
|
||||
String QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE = "hibernate.query.plan_parameter_metadata_max_size";
|
||||
|
||||
/**
|
||||
* Should we not use contextual LOB creation (aka based on {@link java.sql.Connection#createBlob()} et al).
|
||||
*/
|
||||
public static final String NON_CONTEXTUAL_LOB_CREATION = "hibernate.jdbc.lob.non_contextual_creation";
|
||||
String NON_CONTEXTUAL_LOB_CREATION = "hibernate.jdbc.lob.non_contextual_creation";
|
||||
|
||||
/**
|
||||
* Used to define a {@link java.util.Collection} of the {@link ClassLoader} instances Hibernate should use for
|
||||
|
@ -488,7 +488,7 @@ public interface AvailableSettings {
|
|||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public static final String CLASSLOADERS = "hibernate.classLoaders";
|
||||
String CLASSLOADERS = "hibernate.classLoaders";
|
||||
|
||||
/**
|
||||
* Names the {@link ClassLoader} used to load user application classes.
|
||||
|
@ -497,7 +497,7 @@ public interface AvailableSettings {
|
|||
* @deprecated Use {@link #CLASSLOADERS} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String APP_CLASSLOADER = "hibernate.classLoader.application";
|
||||
String APP_CLASSLOADER = "hibernate.classLoader.application";
|
||||
|
||||
/**
|
||||
* Names the {@link ClassLoader} Hibernate should use to perform resource loading.
|
||||
|
@ -505,7 +505,7 @@ public interface AvailableSettings {
|
|||
* @deprecated Use {@link #CLASSLOADERS} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String RESOURCES_CLASSLOADER = "hibernate.classLoader.resources";
|
||||
String RESOURCES_CLASSLOADER = "hibernate.classLoader.resources";
|
||||
|
||||
/**
|
||||
* Names the {@link ClassLoader} responsible for loading Hibernate classes. By default this is
|
||||
|
@ -514,7 +514,7 @@ public interface AvailableSettings {
|
|||
* @deprecated Use {@link #CLASSLOADERS} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String HIBERNATE_CLASSLOADER = "hibernate.classLoader.hibernate";
|
||||
String HIBERNATE_CLASSLOADER = "hibernate.classLoader.hibernate";
|
||||
|
||||
/**
|
||||
* Names the {@link ClassLoader} used when Hibernate is unable to locates classes on the
|
||||
|
@ -523,54 +523,54 @@ public interface AvailableSettings {
|
|||
* @deprecated Use {@link #CLASSLOADERS} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String ENVIRONMENT_CLASSLOADER = "hibernate.classLoader.environment";
|
||||
String ENVIRONMENT_CLASSLOADER = "hibernate.classLoader.environment";
|
||||
|
||||
|
||||
public static final String C3P0_CONFIG_PREFIX = "hibernate.c3p0";
|
||||
String C3P0_CONFIG_PREFIX = "hibernate.c3p0";
|
||||
|
||||
public static final String PROXOOL_CONFIG_PREFIX = "hibernate.proxool";
|
||||
String PROXOOL_CONFIG_PREFIX = "hibernate.proxool";
|
||||
|
||||
|
||||
public static final String JMX_ENABLED = "hibernate.jmx.enabled";
|
||||
public static final String JMX_PLATFORM_SERVER = "hibernate.jmx.usePlatformServer";
|
||||
public static final String JMX_AGENT_ID = "hibernate.jmx.agentId";
|
||||
public static final String JMX_DOMAIN_NAME = "hibernate.jmx.defaultDomain";
|
||||
public static final String JMX_SF_NAME = "hibernate.jmx.sessionFactoryName";
|
||||
public static final String JMX_DEFAULT_OBJ_NAME_DOMAIN = "org.hibernate.core";
|
||||
String JMX_ENABLED = "hibernate.jmx.enabled";
|
||||
String JMX_PLATFORM_SERVER = "hibernate.jmx.usePlatformServer";
|
||||
String JMX_AGENT_ID = "hibernate.jmx.agentId";
|
||||
String JMX_DOMAIN_NAME = "hibernate.jmx.defaultDomain";
|
||||
String JMX_SF_NAME = "hibernate.jmx.sessionFactoryName";
|
||||
String JMX_DEFAULT_OBJ_NAME_DOMAIN = "org.hibernate.core";
|
||||
|
||||
/**
|
||||
* A configuration value key used to indicate that it is safe to cache
|
||||
* {@link javax.transaction.TransactionManager} references.
|
||||
* @since 4.0
|
||||
*/
|
||||
public static final String JTA_CACHE_TM = "hibernate.jta.cacheTransactionManager";
|
||||
String JTA_CACHE_TM = "hibernate.jta.cacheTransactionManager";
|
||||
|
||||
/**
|
||||
* A configuration value key used to indicate that it is safe to cache
|
||||
* {@link javax.transaction.UserTransaction} references.
|
||||
* @since 4.0
|
||||
*/
|
||||
public static final String JTA_CACHE_UT = "hibernate.jta.cacheUserTransaction";
|
||||
String JTA_CACHE_UT = "hibernate.jta.cacheUserTransaction";
|
||||
|
||||
/**
|
||||
* Setting used to give the name of the default {@link org.hibernate.annotations.CacheConcurrencyStrategy}
|
||||
* to use when either {@link javax.persistence.Cacheable @Cacheable} or
|
||||
* {@link org.hibernate.annotations.Cache @Cache} is used. {@link org.hibernate.annotations.Cache @Cache(strategy="..")} is used to override.
|
||||
*/
|
||||
public static final String DEFAULT_CACHE_CONCURRENCY_STRATEGY = "hibernate.cache.default_cache_concurrency_strategy";
|
||||
String DEFAULT_CACHE_CONCURRENCY_STRATEGY = "hibernate.cache.default_cache_concurrency_strategy";
|
||||
|
||||
/**
|
||||
* Setting which indicates whether or not the new {@link org.hibernate.id.IdentifierGenerator} are used
|
||||
* for AUTO, TABLE and SEQUENCE.
|
||||
* Default to false to keep backward compatibility.
|
||||
*/
|
||||
public static final String USE_NEW_ID_GENERATOR_MAPPINGS = "hibernate.id.new_generator_mappings";
|
||||
String USE_NEW_ID_GENERATOR_MAPPINGS = "hibernate.id.new_generator_mappings";
|
||||
|
||||
/**
|
||||
* Setting to identify a {@link org.hibernate.CustomEntityDirtinessStrategy} to use. May point to
|
||||
* either a class name or instance.
|
||||
*/
|
||||
public static final String CUSTOM_ENTITY_DIRTINESS_STRATEGY = "hibernate.entity_dirtiness_strategy";
|
||||
String CUSTOM_ENTITY_DIRTINESS_STRATEGY = "hibernate.entity_dirtiness_strategy";
|
||||
|
||||
/**
|
||||
* Strategy for multi-tenancy.
|
||||
|
@ -578,7 +578,7 @@ public interface AvailableSettings {
|
|||
* @see org.hibernate.MultiTenancyStrategy
|
||||
* @since 4.0
|
||||
*/
|
||||
public static final String MULTI_TENANT = "hibernate.multiTenancy";
|
||||
String MULTI_TENANT = "hibernate.multiTenancy";
|
||||
|
||||
/**
|
||||
* Names a {@link org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider} implementation to
|
||||
|
@ -587,7 +587,7 @@ public interface AvailableSettings {
|
|||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
public static final String MULTI_TENANT_CONNECTION_PROVIDER = "hibernate.multi_tenant_connection_provider";
|
||||
String MULTI_TENANT_CONNECTION_PROVIDER = "hibernate.multi_tenant_connection_provider";
|
||||
|
||||
/**
|
||||
* Names a {@link org.hibernate.context.spi.CurrentTenantIdentifierResolver} implementation to use.
|
||||
|
@ -600,33 +600,33 @@ public interface AvailableSettings {
|
|||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
public static final String MULTI_TENANT_IDENTIFIER_RESOLVER = "hibernate.tenant_identifier_resolver";
|
||||
String MULTI_TENANT_IDENTIFIER_RESOLVER = "hibernate.tenant_identifier_resolver";
|
||||
|
||||
public static final String FORCE_DISCRIMINATOR_IN_SELECTS_BY_DEFAULT = "hibernate.discriminator.force_in_select";
|
||||
String FORCE_DISCRIMINATOR_IN_SELECTS_BY_DEFAULT = "hibernate.discriminator.force_in_select";
|
||||
|
||||
public static final String ENABLE_LAZY_LOAD_NO_TRANS = "hibernate.enable_lazy_load_no_trans";
|
||||
String ENABLE_LAZY_LOAD_NO_TRANS = "hibernate.enable_lazy_load_no_trans";
|
||||
|
||||
public static final String HQL_BULK_ID_STRATEGY = "hibernate.hql.bulk_id_strategy";
|
||||
String HQL_BULK_ID_STRATEGY = "hibernate.hql.bulk_id_strategy";
|
||||
|
||||
/**
|
||||
* Names the {@link org.hibernate.loader.BatchFetchStyle} to use. Can specify either the
|
||||
* {@link org.hibernate.loader.BatchFetchStyle} name (insensitively), or a
|
||||
* {@link org.hibernate.loader.BatchFetchStyle} instance.
|
||||
*/
|
||||
public static final String BATCH_FETCH_STYLE = "hibernate.batch_fetch_style";
|
||||
String BATCH_FETCH_STYLE = "hibernate.batch_fetch_style";
|
||||
|
||||
/**
|
||||
* Enable direct storage of entity references into the second level cache when applicable (immutable data, etc).
|
||||
* Default is to not store direct references.
|
||||
*/
|
||||
public static final String USE_DIRECT_REFERENCE_CACHE_ENTRIES = "hibernate.cache.use_reference_entries";
|
||||
String USE_DIRECT_REFERENCE_CACHE_ENTRIES = "hibernate.cache.use_reference_entries";
|
||||
|
||||
/**
|
||||
* Enable nationalized character support on all string / clob based attribute ( string, char, clob, text etc ).
|
||||
*
|
||||
* Default is <clode>false</clode>.
|
||||
*/
|
||||
public static final String USE_NATIONALIZED_CHARACTER_DATA = "hibernate.use_nationalized_character_data";
|
||||
String USE_NATIONALIZED_CHARACTER_DATA = "hibernate.use_nationalized_character_data";
|
||||
|
||||
/**
|
||||
* A transaction can be rolled back by another thread ("tracking by thread")
|
||||
|
@ -637,11 +637,11 @@ public interface AvailableSettings {
|
|||
*
|
||||
* Default is <code>true</code> (enabled).
|
||||
*/
|
||||
public static final String JTA_TRACK_BY_THREAD = "hibernate.jta.track_by_thread";
|
||||
String JTA_TRACK_BY_THREAD = "hibernate.jta.track_by_thread";
|
||||
|
||||
public static final String JACC_CONTEXT_ID = "hibernate.jacc_context_id";
|
||||
public static final String JACC_PREFIX = "hibernate.jacc";
|
||||
public static final String JACC_ENABLED = "hibernate.jacc.enabled";
|
||||
String JACC_CONTEXT_ID = "hibernate.jacc_context_id";
|
||||
String JACC_PREFIX = "hibernate.jacc";
|
||||
String JACC_ENABLED = "hibernate.jacc.enabled";
|
||||
|
||||
/**
|
||||
* If enabled, allows {@link org.hibernate.tool.hbm2ddl.DatabaseMetadata} to
|
||||
|
@ -649,7 +649,7 @@ public interface AvailableSettings {
|
|||
* possibility that this would return duplicate tables (especially in
|
||||
* Oracle), this is disabled by default.
|
||||
*/
|
||||
public static final String ENABLE_SYNONYMS = "hibernate.synonyms";
|
||||
String ENABLE_SYNONYMS = "hibernate.synonyms";
|
||||
|
||||
/**
|
||||
* Unique columns and unique keys both use unique constraints in most dialects.
|
||||
|
@ -667,5 +667,5 @@ public interface AvailableSettings {
|
|||
* {@link org.hibernate.tool.hbm2ddl.UniqueConstraintSchemaUpdateStrategy#SKIP}:
|
||||
* do not attempt to create unique constraints on a schema update
|
||||
*/
|
||||
public static final String UNIQUE_CONSTRAINT_SCHEMA_UPDATE_STRATEGY = "hibernate.schema_update.unique_constraint_strategy";
|
||||
String UNIQUE_CONSTRAINT_SCHEMA_UPDATE_STRATEGY = "hibernate.schema_update.unique_constraint_strategy";
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@ import java.util.HashSet;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.EntityGraph;
|
||||
|
||||
import org.hibernate.Filter;
|
||||
import org.hibernate.UnknownProfileException;
|
||||
import org.hibernate.internal.FilterImpl;
|
||||
|
@ -57,6 +59,8 @@ public class LoadQueryInfluencers implements Serializable {
|
|||
private String internalFetchProfile;
|
||||
private final Map<String,Filter> enabledFilters;
|
||||
private final Set<String> enabledFetchProfileNames;
|
||||
private EntityGraph fetchGraph;
|
||||
private EntityGraph loadGraph;
|
||||
|
||||
public LoadQueryInfluencers() {
|
||||
this( null );
|
||||
|
@ -195,4 +199,19 @@ public class LoadQueryInfluencers implements Serializable {
|
|||
enabledFetchProfileNames.remove( name );
|
||||
}
|
||||
|
||||
public EntityGraph getFetchGraph() {
|
||||
return fetchGraph;
|
||||
}
|
||||
|
||||
public void setFetchGraph(final EntityGraph fetchGraph) {
|
||||
this.fetchGraph = fetchGraph;
|
||||
}
|
||||
|
||||
public EntityGraph getLoadGraph() {
|
||||
return loadGraph;
|
||||
}
|
||||
|
||||
public void setLoadGraph(final EntityGraph loadGraph) {
|
||||
this.loadGraph = loadGraph;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,20 +21,15 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.graph.spi;
|
||||
package org.hibernate.graph.spi;
|
||||
|
||||
import javax.persistence.AttributeNode;
|
||||
import javax.persistence.metamodel.Attribute;
|
||||
|
||||
import org.hibernate.jpa.HibernateEntityManagerFactory;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
public interface AttributeNodeImplementor<T> extends AttributeNode<T> {
|
||||
public HibernateEntityManagerFactory entityManagerFactory();
|
||||
|
||||
public Attribute<?,T> getAttribute();
|
||||
|
||||
public AttributeNodeImplementor<T> makeImmutableCopy();
|
||||
}
|
|
@ -21,20 +21,15 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.graph.spi;
|
||||
package org.hibernate.graph.spi;
|
||||
|
||||
import javax.persistence.AttributeNode;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.jpa.HibernateEntityManagerFactory;
|
||||
import javax.persistence.AttributeNode;
|
||||
|
||||
/**
|
||||
* Extended contract for a "graph node" (entity-graph or sub-graph).
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
public interface GraphNodeImplementor {
|
||||
public HibernateEntityManagerFactory entityManagerFactory();
|
||||
public List<AttributeNodeImplementor<?>> attributeImplementorNodes();
|
||||
public List<AttributeNode<?>> attributeNodes();
|
||||
List<AttributeNodeImplementor<?>> attributeImplementorNodes();
|
||||
List<AttributeNode<?>> attributeNodes();
|
||||
}
|
|
@ -40,7 +40,10 @@ import org.hibernate.engine.spi.SessionImplementor;
|
|||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.loader.entity.UniqueEntityLoader;
|
||||
import org.hibernate.loader.plan2.build.internal.FetchGraphLoadPlanBuildingStrategy;
|
||||
import org.hibernate.loader.plan2.build.internal.FetchStyleLoadPlanBuildingAssociationVisitationStrategy;
|
||||
import org.hibernate.loader.plan2.build.internal.LoadGraphLoadPlanBuildingStrategy;
|
||||
import org.hibernate.loader.plan2.build.spi.LoadPlanBuildingAssociationVisitationStrategy;
|
||||
import org.hibernate.loader.plan2.build.spi.MetamodelDrivenLoadPlanBuilder;
|
||||
import org.hibernate.loader.plan2.exec.internal.AbstractLoadPlanBasedLoader;
|
||||
import org.hibernate.loader.plan2.exec.query.spi.NamedParameterContext;
|
||||
|
@ -80,11 +83,22 @@ public abstract class AbstractLoadPlanBasedEntityLoader extends AbstractLoadPlan
|
|||
this.uniqueKeyType = uniqueKeyType;
|
||||
this.entityName = entityPersister.getEntityName();
|
||||
|
||||
final FetchStyleLoadPlanBuildingAssociationVisitationStrategy strategy = new FetchStyleLoadPlanBuildingAssociationVisitationStrategy(
|
||||
factory,
|
||||
buildingParameters.getQueryInfluencers(),
|
||||
buildingParameters.getLockMode()
|
||||
);
|
||||
final LoadPlanBuildingAssociationVisitationStrategy strategy;
|
||||
if ( buildingParameters.getQueryInfluencers().getFetchGraph() != null ) {
|
||||
strategy = new FetchGraphLoadPlanBuildingStrategy(
|
||||
factory, buildingParameters.getQueryInfluencers(),buildingParameters.getLockMode()
|
||||
);
|
||||
}
|
||||
else if ( buildingParameters.getQueryInfluencers().getLoadGraph() != null ) {
|
||||
strategy = new LoadGraphLoadPlanBuildingStrategy(
|
||||
factory, buildingParameters.getQueryInfluencers(),buildingParameters.getLockMode()
|
||||
);
|
||||
}
|
||||
else {
|
||||
strategy = new FetchStyleLoadPlanBuildingAssociationVisitationStrategy(
|
||||
factory, buildingParameters.getQueryInfluencers(),buildingParameters.getLockMode()
|
||||
);
|
||||
}
|
||||
|
||||
this.plan = MetamodelDrivenLoadPlanBuilder.buildRootEntityLoadPlan( strategy, entityPersister );
|
||||
this.staticLoadQuery = EntityLoadQueryDetails.makeForBatching(
|
||||
|
|
|
@ -0,0 +1,359 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, 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.loader.plan2.build.internal;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.persistence.AttributeNode;
|
||||
import javax.persistence.Subgraph;
|
||||
import javax.persistence.metamodel.Attribute;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.graph.spi.GraphNodeImplementor;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.loader.plan2.build.spi.AbstractLoadPlanBuildingAssociationVisitationStrategy;
|
||||
import org.hibernate.loader.plan2.spi.EntityReturn;
|
||||
import org.hibernate.loader.plan2.spi.LoadPlan;
|
||||
import org.hibernate.loader.plan2.spi.Return;
|
||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||
import org.hibernate.persister.walking.spi.WalkingException;
|
||||
|
||||
/**
|
||||
* Abstract strategy of building loadplan based on entity graph.
|
||||
*
|
||||
* The problem we're resolving here is, we have TWO trees to walk (only entity loading here):
|
||||
* <ul>
|
||||
* <ol>entity metadata and its associations</ol>
|
||||
* <ol>entity graph and attribute nodes</ol>
|
||||
* </ul>
|
||||
*
|
||||
* And most time, the entity graph tree is partial of entity metadata tree.
|
||||
*
|
||||
* So, the idea here is, we walk the entity metadata tree, just as how we build the static loadplan from mappings,
|
||||
* and we try to match the node to entity graph ( and subgraph ), if there is a match, then the attribute is fetched,
|
||||
* it is not, then depends on which property is used to apply this entity graph.
|
||||
*
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
public abstract class AbstractEntityGraphVisitationStrategy
|
||||
extends AbstractLoadPlanBuildingAssociationVisitationStrategy {
|
||||
private static final Logger LOG = CoreLogging.logger( AbstractEntityGraphVisitationStrategy.class );
|
||||
/**
|
||||
* The JPA 2.1 SPEC's Entity Graph only defines _WHEN_ to load an attribute, it doesn't define _HOW_ to load it
|
||||
* So I'm here just making an assumption that when it is EAGER, then we use JOIN, and when it is LAZY, then we use SELECT.
|
||||
*
|
||||
* NOTE: this may be changed in the near further, though ATM I have no idea how this will be changed to :)
|
||||
* -- stliu
|
||||
*/
|
||||
protected static final FetchStrategy DEFAULT_EAGER = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN );
|
||||
protected static final FetchStrategy DEFAULT_LAZY = new FetchStrategy( FetchTiming.DELAYED, FetchStyle.SELECT );
|
||||
protected final LoadQueryInfluencers loadQueryInfluencers;
|
||||
protected final ArrayDeque<GraphNodeImplementor> graphStack = new ArrayDeque<GraphNodeImplementor>();
|
||||
protected final ArrayDeque<AttributeNodeImplementor> attributeStack = new ArrayDeque<AttributeNodeImplementor>();
|
||||
//the attribute nodes defined in the current graph node (entity graph or subgraph) we're working on
|
||||
protected Map<String, AttributeNodeImplementor> attributeNodeImplementorMap = Collections.emptyMap();
|
||||
private EntityReturn rootEntityReturn;
|
||||
private final LockMode lockMode;
|
||||
|
||||
protected AbstractEntityGraphVisitationStrategy(
|
||||
final SessionFactoryImplementor sessionFactory, final LoadQueryInfluencers loadQueryInfluencers,
|
||||
final LockMode lockMode) {
|
||||
super( sessionFactory );
|
||||
this.loadQueryInfluencers = loadQueryInfluencers;
|
||||
this.lockMode = lockMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
super.start();
|
||||
graphStack.addLast( getRootEntityGraph() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
graphStack.removeLast();
|
||||
//applying a little internal stack checking
|
||||
if ( !graphStack.isEmpty() || !attributeStack.isEmpty() || !attributeNodeImplementorMap.isEmpty() ) {
|
||||
throw new WalkingException( "Internal stack error" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startingEntity(final EntityDefinition entityDefinition) {
|
||||
//TODO check if the passed in entity definition is the same as the root entity graph (a.k.a they are came from same entity class)?
|
||||
//this maybe the root entity graph or a sub graph.
|
||||
attributeNodeImplementorMap = buildAttributeNodeMap();
|
||||
super.startingEntity( entityDefinition );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build "name" -- "attribute node" map from the current entity graph we're visiting.
|
||||
*/
|
||||
protected Map<String, AttributeNodeImplementor> buildAttributeNodeMap() {
|
||||
GraphNodeImplementor graphNode = graphStack.peekLast();
|
||||
List<AttributeNodeImplementor<?>> attributeNodeImplementors = graphNode.attributeImplementorNodes();
|
||||
Map<String, AttributeNodeImplementor> attributeNodeImplementorMap = attributeNodeImplementors.isEmpty() ? Collections
|
||||
.<String, AttributeNodeImplementor>emptyMap() : new HashMap<String, AttributeNodeImplementor>(
|
||||
attributeNodeImplementors.size()
|
||||
);
|
||||
for ( AttributeNodeImplementor attribute : attributeNodeImplementors ) {
|
||||
attributeNodeImplementorMap.put( attribute.getAttributeName(), attribute );
|
||||
}
|
||||
return attributeNodeImplementorMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingEntity(final EntityDefinition entityDefinition) {
|
||||
attributeNodeImplementorMap = Collections.emptyMap();
|
||||
super.finishingEntity( entityDefinition );
|
||||
}
|
||||
|
||||
/**
|
||||
* I'm using NULL-OBJECT pattern here, for attributes that not existing in the EntityGraph,
|
||||
* a predefined NULL-ATTRIBUTE-NODE is pushed to the stack.
|
||||
*
|
||||
* and for an not existing sub graph, a predefined NULL-SUBGRAPH is pushed to the stack.
|
||||
*
|
||||
* So, whenever we're start visiting an attribute, there will be a attribute node pushed to the attribute stack,
|
||||
* and a subgraph node pushed to the graph stack.
|
||||
*
|
||||
* when we're finish visiting an attribute, these two will be poped from each stack.
|
||||
*/
|
||||
@Override
|
||||
public boolean startingAttribute(AttributeDefinition attributeDefinition) {
|
||||
final String attrName = attributeDefinition.getName();
|
||||
AttributeNodeImplementor attributeNode = NON_EXIST_ATTRIBUTE_NODE;
|
||||
GraphNodeImplementor subGraphNode = NON_EXIST_SUBGRAPH_NODE;
|
||||
//the attribute is in the EntityGraph, so, let's continue
|
||||
if ( attributeNodeImplementorMap.containsKey( attrName ) ) {
|
||||
attributeNode = attributeNodeImplementorMap.get( attrName );
|
||||
//here we need to check if there is a subgraph (or sub key graph if it is an indexed attribute )
|
||||
Map<Class, Subgraph> subGraphs = attributeNode.getSubgraphs();
|
||||
Class javaType = attributeDefinition.getType().getReturnedClass();
|
||||
if ( !subGraphs.isEmpty() && subGraphs.containsKey( javaType ) ) {
|
||||
subGraphNode = (GraphNodeImplementor) subGraphs.get( javaType );
|
||||
}
|
||||
|
||||
}
|
||||
attributeStack.addLast( attributeNode );
|
||||
graphStack.addLast( subGraphNode );
|
||||
return super.startingAttribute( attributeDefinition );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void finishingAttribute(final AttributeDefinition attributeDefinition) {
|
||||
attributeStack.removeLast();
|
||||
graphStack.removeLast();
|
||||
super.finishingAttribute( attributeDefinition );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean handleAssociationAttribute(
|
||||
final AssociationAttributeDefinition attributeDefinition) {
|
||||
return super.handleAssociationAttribute( attributeDefinition );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean handleCompositeAttribute(
|
||||
final CompositionDefinition attributeDefinition) {
|
||||
return super.handleCompositeAttribute( attributeDefinition );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void startingComposite(final CompositionDefinition compositionDefinition) {
|
||||
super.startingComposite( compositionDefinition );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void finishingComposite(final CompositionDefinition compositionDefinition) {
|
||||
super.finishingComposite( compositionDefinition );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void startingCollection(final CollectionDefinition collectionDefinition) {
|
||||
super.startingCollection( collectionDefinition );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingCollection(final CollectionDefinition collectionDefinition) {
|
||||
super.finishingCollection( collectionDefinition );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void startingCollectionElements(
|
||||
final CollectionElementDefinition elementDefinition) {
|
||||
super.startingCollectionElements( elementDefinition );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingCollectionElements(
|
||||
final CollectionElementDefinition elementDefinition) {
|
||||
super.finishingCollectionElements( elementDefinition );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void startingCollectionIndex(final CollectionIndexDefinition indexDefinition) {
|
||||
AttributeNodeImplementor attributeNode = attributeStack.peekLast();
|
||||
GraphNodeImplementor subGraphNode = NON_EXIST_SUBGRAPH_NODE;
|
||||
Map<Class, Subgraph> subGraphs = attributeNode.getKeySubgraphs();
|
||||
Class javaType = indexDefinition.getType().getReturnedClass();
|
||||
if ( !subGraphs.isEmpty() && subGraphs.containsKey( javaType ) ) {
|
||||
subGraphNode = (GraphNodeImplementor) subGraphs.get( javaType );
|
||||
}
|
||||
graphStack.addLast( subGraphNode );
|
||||
super.startingCollectionIndex( indexDefinition );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingCollectionIndex(final CollectionIndexDefinition indexDefinition) {
|
||||
super.finishingCollectionIndex( indexDefinition );
|
||||
graphStack.removeLast();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean supportsRootCollectionReturns() {
|
||||
return false; //entity graph doesn't support root collection.
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void addRootReturn(final Return rootReturn) {
|
||||
if ( this.rootEntityReturn != null ) {
|
||||
throw new HibernateException( "Root return already identified" );
|
||||
}
|
||||
if ( !( rootReturn instanceof EntityReturn ) ) {
|
||||
throw new HibernateException( "Load entity graph only supports EntityReturn" );
|
||||
}
|
||||
this.rootEntityReturn = (EntityReturn) rootReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FetchStrategy determineFetchStrategy(
|
||||
final AssociationAttributeDefinition attributeDefinition) {
|
||||
return attributeStack.peekLast() != NON_EXIST_ATTRIBUTE_NODE ? DEFAULT_EAGER : resolveImplicitFetchStrategyFromEntityGraph(
|
||||
attributeDefinition
|
||||
);
|
||||
}
|
||||
|
||||
protected abstract FetchStrategy resolveImplicitFetchStrategyFromEntityGraph(
|
||||
final AssociationAttributeDefinition attributeDefinition);
|
||||
|
||||
protected FetchStrategy adjustJoinFetchIfNeeded(
|
||||
AssociationAttributeDefinition attributeDefinition, FetchStrategy fetchStrategy) {
|
||||
if ( lockMode.greaterThan( LockMode.READ ) ) {
|
||||
return new FetchStrategy( fetchStrategy.getTiming(), FetchStyle.SELECT );
|
||||
}
|
||||
|
||||
final Integer maxFetchDepth = sessionFactory().getSettings().getMaximumFetchDepth();
|
||||
if ( maxFetchDepth != null && currentDepth() > maxFetchDepth ) {
|
||||
return new FetchStrategy( fetchStrategy.getTiming(), FetchStyle.SELECT );
|
||||
}
|
||||
|
||||
if ( attributeDefinition.getType().isCollectionType() && isTooManyCollections() ) {
|
||||
// todo : have this revert to batch or subselect fetching once "sql gen redesign" is in place
|
||||
return new FetchStrategy( fetchStrategy.getTiming(), FetchStyle.SELECT );
|
||||
}
|
||||
|
||||
return fetchStrategy;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public LoadPlan buildLoadPlan() {
|
||||
LOG.debug( "Building LoadPlan..." );
|
||||
return new LoadPlanImpl( rootEntityReturn, getQuerySpaces() );
|
||||
}
|
||||
|
||||
abstract protected GraphNodeImplementor getRootEntityGraph();
|
||||
|
||||
private static final AttributeNodeImplementor NON_EXIST_ATTRIBUTE_NODE = new AttributeNodeImplementor() {
|
||||
@Override
|
||||
public Attribute getAttribute() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeNodeImplementor makeImmutableCopy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttributeName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Class, Subgraph> getSubgraphs() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Class, Subgraph> getKeySubgraphs() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Mocked NON-EXIST attribute node";
|
||||
}
|
||||
};
|
||||
private static final GraphNodeImplementor NON_EXIST_SUBGRAPH_NODE = new GraphNodeImplementor() {
|
||||
@Override
|
||||
public List<AttributeNodeImplementor<?>> attributeImplementorNodes() {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AttributeNode<?>> attributeNodes() {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, 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.loader.plan2.build.internal;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.graph.spi.GraphNodeImplementor;
|
||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||
|
||||
/**
|
||||
* Loadplan building strategy for {@link javax.persistence.EntityGraph} is applied in {@code javax.persistence.fetchgraph} mode.
|
||||
*
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
public class FetchGraphLoadPlanBuildingStrategy extends AbstractEntityGraphVisitationStrategy {
|
||||
private final GraphNodeImplementor rootEntityGraph;
|
||||
|
||||
public FetchGraphLoadPlanBuildingStrategy(
|
||||
final SessionFactoryImplementor sessionFactory, final LoadQueryInfluencers loadQueryInfluencers,
|
||||
final LockMode lockMode) {
|
||||
super( sessionFactory, loadQueryInfluencers, lockMode );
|
||||
this.rootEntityGraph = (GraphNodeImplementor) loadQueryInfluencers.getFetchGraph();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GraphNodeImplementor getRootEntityGraph() {
|
||||
return rootEntityGraph;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FetchStrategy resolveImplicitFetchStrategyFromEntityGraph(
|
||||
final AssociationAttributeDefinition attributeDefinition) {
|
||||
//under fetchgraph mode, according to the SPEC, all other attributes that no in entity graph are supposed to be lazily loaded
|
||||
return DEFAULT_LAZY;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, 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.loader.plan2.build.internal;
|
||||
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.graph.spi.GraphNodeImplementor;
|
||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||
|
||||
/**
|
||||
* Loadplan building strategy for {@link javax.persistence.EntityGraph} is applied in {@code javax.persistence.loadgraph} mode.
|
||||
*
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
public class LoadGraphLoadPlanBuildingStrategy extends AbstractEntityGraphVisitationStrategy {
|
||||
private final GraphNodeImplementor rootEntityGraph;
|
||||
|
||||
public LoadGraphLoadPlanBuildingStrategy(
|
||||
final SessionFactoryImplementor sessionFactory, final LoadQueryInfluencers loadQueryInfluencers,final LockMode lockMode) {
|
||||
super( sessionFactory, loadQueryInfluencers , lockMode);
|
||||
this.rootEntityGraph = (GraphNodeImplementor) loadQueryInfluencers.getLoadGraph();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GraphNodeImplementor getRootEntityGraph() {
|
||||
return rootEntityGraph;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FetchStrategy resolveImplicitFetchStrategyFromEntityGraph(
|
||||
final AssociationAttributeDefinition attributeDefinition) {
|
||||
FetchStrategy fetchStrategy = attributeDefinition.determineFetchPlan(
|
||||
loadQueryInfluencers,
|
||||
currentPropertyPath
|
||||
);
|
||||
if ( fetchStrategy.getTiming() == FetchTiming.IMMEDIATE && fetchStrategy.getStyle() == FetchStyle.JOIN ) {
|
||||
// see if we need to alter the join fetch to another form for any reason
|
||||
fetchStrategy = adjustJoinFetchIfNeeded( attributeDefinition, fetchStrategy );
|
||||
}
|
||||
|
||||
return fetchStrategy;
|
||||
}
|
||||
|
||||
}
|
|
@ -4031,6 +4031,11 @@ public abstract class AbstractEntityPersister
|
|||
affectingFetchProfileNames.add( fetchProfileName );
|
||||
}
|
||||
|
||||
private boolean isAffectedByEntityGraph(SessionImplementor session) {
|
||||
return session.getLoadQueryInfluencers().getFetchGraph() != null || session.getLoadQueryInfluencers()
|
||||
.getLoadGraph() != null;
|
||||
}
|
||||
|
||||
private boolean isAffectedByEnabledFetchProfiles(SessionImplementor session) {
|
||||
for ( String s : session.getLoadQueryInfluencers().getEnabledFetchProfileNames() ) {
|
||||
if ( affectingFetchProfileNames.contains( s ) ) {
|
||||
|
@ -4067,6 +4072,9 @@ public abstract class AbstractEntityPersister
|
|||
// SQL query used for loading based on those influencers
|
||||
return createEntityLoader(lockOptions, session.getLoadQueryInfluencers() );
|
||||
}
|
||||
else if ( isAffectedByEntityGraph( session ) ) {
|
||||
return createEntityLoader( lockOptions, session.getLoadQueryInfluencers() );
|
||||
}
|
||||
else if ( lockOptions.getTimeOut() != LockOptions.WAIT_FOREVER ) {
|
||||
return createEntityLoader( lockOptions, session.getLoadQueryInfluencers() );
|
||||
}
|
||||
|
|
|
@ -41,28 +41,28 @@ public interface AvailableSettings {
|
|||
* <p/>
|
||||
* See JPA 2 sections 9.4.3 and 8.2.1.4
|
||||
*/
|
||||
public static final String PROVIDER = "javax.persistence.provider";
|
||||
String PROVIDER = "javax.persistence.provider";
|
||||
|
||||
/**
|
||||
* The type of transactions supported by the entity managers.
|
||||
* <p/>
|
||||
* See JPA 2 sections 9.4.3 and 8.2.1.2
|
||||
*/
|
||||
public static final String TRANSACTION_TYPE = "javax.persistence.transactionType";
|
||||
String TRANSACTION_TYPE = "javax.persistence.transactionType";
|
||||
|
||||
/**
|
||||
* The JNDI name of a JTA {@link javax.sql.DataSource}.
|
||||
* <p/>
|
||||
* See JPA 2 sections 9.4.3 and 8.2.1.5
|
||||
*/
|
||||
public static final String JTA_DATASOURCE = "javax.persistence.jtaDataSource";
|
||||
String JTA_DATASOURCE = "javax.persistence.jtaDataSource";
|
||||
|
||||
/**
|
||||
* The JNDI name of a non-JTA {@link javax.sql.DataSource}.
|
||||
* <p/>
|
||||
* See JPA 2 sections 9.4.3 and 8.2.1.5
|
||||
*/
|
||||
public static final String NON_JTA_DATASOURCE = "javax.persistence.nonJtaDataSource";
|
||||
String NON_JTA_DATASOURCE = "javax.persistence.nonJtaDataSource";
|
||||
|
||||
/**
|
||||
* The name of a JDBC driver to use to connect to the database.
|
||||
|
@ -73,7 +73,7 @@ public interface AvailableSettings {
|
|||
* <p/>
|
||||
* See section 8.2.1.9
|
||||
*/
|
||||
public static final String JDBC_DRIVER = "javax.persistence.jdbc.driver";
|
||||
String JDBC_DRIVER = "javax.persistence.jdbc.driver";
|
||||
|
||||
/**
|
||||
* The JDBC connection url to use to connect to the database.
|
||||
|
@ -84,7 +84,7 @@ public interface AvailableSettings {
|
|||
* <p/>
|
||||
* See section 8.2.1.9
|
||||
*/
|
||||
public static final String JDBC_URL = "javax.persistence.jdbc.url";
|
||||
String JDBC_URL = "javax.persistence.jdbc.url";
|
||||
|
||||
/**
|
||||
* The JDBC connection user name.
|
||||
|
@ -95,7 +95,7 @@ public interface AvailableSettings {
|
|||
* <p/>
|
||||
* See section 8.2.1.9
|
||||
*/
|
||||
public static final String JDBC_USER = "javax.persistence.jdbc.user";
|
||||
String JDBC_USER = "javax.persistence.jdbc.user";
|
||||
|
||||
/**
|
||||
* The JDBC connection password.
|
||||
|
@ -106,7 +106,7 @@ public interface AvailableSettings {
|
|||
* <p/>
|
||||
* See JPA 2 section 8.2.1.9
|
||||
*/
|
||||
public static final String JDBC_PASSWORD = "javax.persistence.jdbc.password";
|
||||
String JDBC_PASSWORD = "javax.persistence.jdbc.password";
|
||||
|
||||
/**
|
||||
* Used to indicate whether second-level (what JPA terms shared cache) caching is
|
||||
|
@ -115,7 +115,7 @@ public interface AvailableSettings {
|
|||
* See JPA 2 sections 9.4.3 and 8.2.1.7
|
||||
* @see javax.persistence.SharedCacheMode
|
||||
*/
|
||||
public static final String SHARED_CACHE_MODE = "javax.persistence.sharedCache.mode";
|
||||
String SHARED_CACHE_MODE = "javax.persistence.sharedCache.mode";
|
||||
|
||||
/**
|
||||
* NOTE : Not a valid EMF property...
|
||||
|
@ -125,7 +125,7 @@ public interface AvailableSettings {
|
|||
*
|
||||
* @see javax.persistence.CacheRetrieveMode
|
||||
*/
|
||||
public static final String SHARED_CACHE_RETRIEVE_MODE ="javax.persistence.cache.retrieveMode";
|
||||
String SHARED_CACHE_RETRIEVE_MODE ="javax.persistence.cache.retrieveMode";
|
||||
|
||||
/**
|
||||
* NOTE : Not a valid EMF property...
|
||||
|
@ -135,7 +135,7 @@ public interface AvailableSettings {
|
|||
*
|
||||
* @see javax.persistence.CacheStoreMode
|
||||
*/
|
||||
public static final String SHARED_CACHE_STORE_MODE ="javax.persistence.cache.storeMode";
|
||||
String SHARED_CACHE_STORE_MODE ="javax.persistence.cache.storeMode";
|
||||
|
||||
/**
|
||||
* Used to indicate what form of automatic validation is in effect as per rules defined
|
||||
|
@ -144,52 +144,52 @@ public interface AvailableSettings {
|
|||
* See JPA 2 sections 9.4.3 and 8.2.1.8
|
||||
* @see javax.persistence.ValidationMode
|
||||
*/
|
||||
public static final String VALIDATION_MODE = "javax.persistence.validation.mode";
|
||||
String VALIDATION_MODE = "javax.persistence.validation.mode";
|
||||
|
||||
/**
|
||||
* Used to pass along any discovered validator factory.
|
||||
*/
|
||||
public static final String VALIDATION_FACTORY = "javax.persistence.validation.factory";
|
||||
String VALIDATION_FACTORY = "javax.persistence.validation.factory";
|
||||
|
||||
/**
|
||||
* Used to request (hint) a pessimistic lock scope.
|
||||
* <p/>
|
||||
* See JPA 2 sections 8.2.1.9 and 3.4.4.3
|
||||
*/
|
||||
public static final String LOCK_SCOPE = "javax.persistence.lock.scope";
|
||||
String LOCK_SCOPE = "javax.persistence.lock.scope";
|
||||
|
||||
/**
|
||||
* Used to request (hint) a pessimistic lock timeout (in milliseconds).
|
||||
* <p/>
|
||||
* See JPA 2 sections 8.2.1.9 and 3.4.4.3
|
||||
*/
|
||||
public static final String LOCK_TIMEOUT = "javax.persistence.lock.timeout";
|
||||
String LOCK_TIMEOUT = "javax.persistence.lock.timeout";
|
||||
|
||||
/**
|
||||
* Used to coordinate with bean validators
|
||||
* <p/>
|
||||
* See JPA 2 section 8.2.1.9
|
||||
*/
|
||||
public static final String PERSIST_VALIDATION_GROUP = "javax.persistence.validation.group.pre-persist";
|
||||
String PERSIST_VALIDATION_GROUP = "javax.persistence.validation.group.pre-persist";
|
||||
|
||||
/**
|
||||
* Used to coordinate with bean validators
|
||||
* <p/>
|
||||
* See JPA 2 section 8.2.1.9
|
||||
*/
|
||||
public static final String UPDATE_VALIDATION_GROUP = "javax.persistence.validation.group.pre-update";
|
||||
String UPDATE_VALIDATION_GROUP = "javax.persistence.validation.group.pre-update";
|
||||
|
||||
/**
|
||||
* Used to coordinate with bean validators
|
||||
* <p/>
|
||||
* See JPA 2 section 8.2.1.9
|
||||
*/
|
||||
public static final String REMOVE_VALIDATION_GROUP = "javax.persistence.validation.group.pre-remove";
|
||||
String REMOVE_VALIDATION_GROUP = "javax.persistence.validation.group.pre-remove";
|
||||
|
||||
/**
|
||||
* Used to pass along the CDI BeanManager, if any, to be used.
|
||||
*/
|
||||
public static final String CDI_BEAN_MANAGER = "javax.persistence.bean.manager";
|
||||
String CDI_BEAN_MANAGER = "javax.persistence.bean.manager";
|
||||
|
||||
/**
|
||||
* Specifies whether schema generation commands for schema creation are to be determine based on object/relational
|
||||
|
@ -205,7 +205,7 @@ public interface AvailableSettings {
|
|||
*
|
||||
* @see SchemaGenSource
|
||||
*/
|
||||
public static final String SCHEMA_GEN_CREATE_SOURCE = "javax.persistence.schema-generation.create-source";
|
||||
String SCHEMA_GEN_CREATE_SOURCE = "javax.persistence.schema-generation.create-source";
|
||||
|
||||
/**
|
||||
* Specifies whether schema generation commands for schema dropping are to be determine based on object/relational
|
||||
|
@ -221,7 +221,7 @@ public interface AvailableSettings {
|
|||
*
|
||||
* @see SchemaGenSource
|
||||
*/
|
||||
public static final String SCHEMA_GEN_DROP_SOURCE = "javax.persistence.schema-generation.drop-source";
|
||||
String SCHEMA_GEN_DROP_SOURCE = "javax.persistence.schema-generation.drop-source";
|
||||
|
||||
/**
|
||||
* Specifies the CREATE script file as either a {@link java.io.Reader} configured for reading of the DDL script
|
||||
|
@ -230,7 +230,7 @@ public interface AvailableSettings {
|
|||
* @see #SCHEMA_GEN_CREATE_SOURCE
|
||||
* @see #SCHEMA_GEN_DROP_SCRIPT_SOURCE
|
||||
*/
|
||||
public static final String SCHEMA_GEN_CREATE_SCRIPT_SOURCE = "javax.persistence.schema-generation.create-script-source";
|
||||
String SCHEMA_GEN_CREATE_SCRIPT_SOURCE = "javax.persistence.schema-generation.create-script-source";
|
||||
|
||||
/**
|
||||
* Specifies the DROP script file as either a {@link java.io.Reader} configured for reading of the DDL script
|
||||
|
@ -239,7 +239,7 @@ public interface AvailableSettings {
|
|||
* @see #SCHEMA_GEN_DROP_SOURCE
|
||||
* @see #SCHEMA_GEN_CREATE_SCRIPT_SOURCE
|
||||
*/
|
||||
public static final String SCHEMA_GEN_DROP_SCRIPT_SOURCE = "javax.persistence.schema-generation.drop-script-source";
|
||||
String SCHEMA_GEN_DROP_SCRIPT_SOURCE = "javax.persistence.schema-generation.drop-script-source";
|
||||
|
||||
/**
|
||||
* Specifies the type of schema generation action to be taken by the persistence provider in regards to sending
|
||||
|
@ -249,7 +249,7 @@ public interface AvailableSettings {
|
|||
*
|
||||
* @see SchemaGenAction
|
||||
*/
|
||||
public static final String SCHEMA_GEN_DATABASE_ACTION = "javax.persistence.schema-generation.database.action";
|
||||
String SCHEMA_GEN_DATABASE_ACTION = "javax.persistence.schema-generation.database.action";
|
||||
|
||||
/**
|
||||
* Specifies the type of schema generation action to be taken by the persistence provider in regards to writing
|
||||
|
@ -259,7 +259,7 @@ public interface AvailableSettings {
|
|||
*
|
||||
* @see SchemaGenAction
|
||||
*/
|
||||
public static final String SCHEMA_GEN_SCRIPTS_ACTION = "javax.persistence.schema-generation.scripts.action";
|
||||
String SCHEMA_GEN_SCRIPTS_ACTION = "javax.persistence.schema-generation.scripts.action";
|
||||
|
||||
/**
|
||||
* For cases where the {@value #SCHEMA_GEN_SCRIPTS_ACTION} value indicates that schema creation commands should
|
||||
|
@ -270,7 +270,7 @@ public interface AvailableSettings {
|
|||
* @see #SCHEMA_GEN_SCRIPTS_ACTION
|
||||
*/
|
||||
@SuppressWarnings("JavaDoc")
|
||||
public static final String SCHEMA_GEN_SCRIPTS_CREATE_TARGET = "javax.persistence.schema-generation.scripts.create-target";
|
||||
String SCHEMA_GEN_SCRIPTS_CREATE_TARGET = "javax.persistence.schema-generation.scripts.create-target";
|
||||
|
||||
/**
|
||||
* For cases where the {@value #SCHEMA_GEN_SCRIPTS_ACTION} value indicates that schema drop commands should
|
||||
|
@ -281,7 +281,7 @@ public interface AvailableSettings {
|
|||
* @see #SCHEMA_GEN_SCRIPTS_ACTION
|
||||
*/
|
||||
@SuppressWarnings("JavaDoc")
|
||||
public static final String SCHEMA_GEN_SCRIPTS_DROP_TARGET = "javax.persistence.schema-generation.scripts.drop-target";
|
||||
String SCHEMA_GEN_SCRIPTS_DROP_TARGET = "javax.persistence.schema-generation.scripts.drop-target";
|
||||
|
||||
/**
|
||||
* Specifies whether the persistence provider is to create the database schema(s) in addition to creating
|
||||
|
@ -290,7 +290,7 @@ public interface AvailableSettings {
|
|||
* contains “CREATE SCHEMA” commands. If this property is not supplied (or is explicitly {@code false}), the
|
||||
* provider should not attempt to create database schemas.
|
||||
*/
|
||||
public static final String SCHEMA_GEN_CREATE_SCHEMAS = "javax.persistence.create-database-schemas";
|
||||
String SCHEMA_GEN_CREATE_SCHEMAS = "javax.persistence.create-database-schemas";
|
||||
|
||||
/**
|
||||
* Allows passing the specific {@link java.sql.Connection} instance to be used for performing schema generation
|
||||
|
@ -299,7 +299,7 @@ public interface AvailableSettings {
|
|||
* May also be used to determine the values for {@value #SCHEMA_GEN_DB_NAME},
|
||||
* {@value #SCHEMA_GEN_DB_MAJOR_VERSION} and {@value #SCHEMA_GEN_DB_MINOR_VERSION}.
|
||||
*/
|
||||
public static final String SCHEMA_GEN_CONNECTION = "javax.persistence.schema-generation-connection";
|
||||
String SCHEMA_GEN_CONNECTION = "javax.persistence.schema-generation-connection";
|
||||
|
||||
/**
|
||||
* Specifies the name of the database provider in cases where a Connection to the underlying database is
|
||||
|
@ -316,7 +316,7 @@ public interface AvailableSettings {
|
|||
* @see #SCHEMA_GEN_DB_MINOR_VERSION
|
||||
*/
|
||||
@SuppressWarnings("JavaDoc")
|
||||
public static final String SCHEMA_GEN_DB_NAME = "javax.persistence.database-product-name";
|
||||
String SCHEMA_GEN_DB_NAME = "javax.persistence.database-product-name";
|
||||
|
||||
/**
|
||||
* Specifies the major version of the underlying database, as would be returned by
|
||||
|
@ -327,7 +327,7 @@ public interface AvailableSettings {
|
|||
* @see #SCHEMA_GEN_DB_NAME
|
||||
* @see #SCHEMA_GEN_DB_MINOR_VERSION
|
||||
*/
|
||||
public static final String SCHEMA_GEN_DB_MAJOR_VERSION = "javax.persistence.database-major-version";
|
||||
String SCHEMA_GEN_DB_MAJOR_VERSION = "javax.persistence.database-major-version";
|
||||
|
||||
/**
|
||||
* Specifies the minor version of the underlying database, as would be returned by
|
||||
|
@ -339,7 +339,7 @@ public interface AvailableSettings {
|
|||
* @see #SCHEMA_GEN_DB_NAME
|
||||
* @see #SCHEMA_GEN_DB_MAJOR_VERSION
|
||||
*/
|
||||
public static final String SCHEMA_GEN_DB_MINOR_VERSION = "javax.persistence.database-minor-version";
|
||||
String SCHEMA_GEN_DB_MINOR_VERSION = "javax.persistence.database-minor-version";
|
||||
|
||||
/**
|
||||
* Specifies a {@link java.io.Reader} configured for reading of the SQL load script or a string designating the
|
||||
|
@ -347,7 +347,7 @@ public interface AvailableSettings {
|
|||
* <p/>
|
||||
* A "SQL load script" is a script that performs some database initialization (INSERT, etc).
|
||||
*/
|
||||
public static final String SCHEMA_GEN_LOAD_SCRIPT_SOURCE = "javax.persistence.sql-load-script-source";
|
||||
String SCHEMA_GEN_LOAD_SCRIPT_SOURCE = "javax.persistence.sql-load-script-source";
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -367,75 +367,75 @@ public interface AvailableSettings {
|
|||
* would apply <code>someLockMode</code> to the alias <code>"a"</code>.
|
||||
*/
|
||||
//Use the org.hibernate prefix. instead of hibernate. as it is a query hint se QueryHints
|
||||
public static final String ALIAS_SPECIFIC_LOCK_MODE = "org.hibernate.lockMode";
|
||||
String ALIAS_SPECIFIC_LOCK_MODE = "org.hibernate.lockMode";
|
||||
|
||||
/**
|
||||
* JAR autodetection artifacts class, hbm
|
||||
*/
|
||||
public static final String AUTODETECTION = "hibernate.archive.autodetection";
|
||||
String AUTODETECTION = "hibernate.archive.autodetection";
|
||||
|
||||
/**
|
||||
* cfg.xml configuration file used
|
||||
*/
|
||||
public static final String CFG_FILE = "hibernate.ejb.cfgfile";
|
||||
String CFG_FILE = "hibernate.ejb.cfgfile";
|
||||
|
||||
/**
|
||||
* Caching configuration should follow the following pattern
|
||||
* hibernate.ejb.classcache.<fully.qualified.Classname> usage[, region]
|
||||
* where usage is the cache strategy used and region the cache region name
|
||||
*/
|
||||
public static final String CLASS_CACHE_PREFIX = "hibernate.ejb.classcache";
|
||||
String CLASS_CACHE_PREFIX = "hibernate.ejb.classcache";
|
||||
|
||||
/**
|
||||
* Caching configuration should follow the following pattern
|
||||
* hibernate.ejb.collectioncache.<fully.qualified.Classname>.<role> usage[, region]
|
||||
* where usage is the cache strategy used and region the cache region name
|
||||
*/
|
||||
public static final String COLLECTION_CACHE_PREFIX = "hibernate.ejb.collectioncache";
|
||||
String COLLECTION_CACHE_PREFIX = "hibernate.ejb.collectioncache";
|
||||
|
||||
/**
|
||||
* Interceptor class name, the class has to have a no-arg constructor
|
||||
* the interceptor instance is shared amongst all EntityManager of a given EntityManagerFactory
|
||||
*/
|
||||
public static final String INTERCEPTOR = "hibernate.ejb.interceptor";
|
||||
String INTERCEPTOR = "hibernate.ejb.interceptor";
|
||||
|
||||
/**
|
||||
* Interceptor class name, the class has to have a no-arg constructor
|
||||
*/
|
||||
public static final String SESSION_INTERCEPTOR = "hibernate.ejb.interceptor.session_scoped";
|
||||
String SESSION_INTERCEPTOR = "hibernate.ejb.interceptor.session_scoped";
|
||||
|
||||
/**
|
||||
* SessionFactoryObserver class name, the class must have a no-arg constructor
|
||||
*/
|
||||
public static final String SESSION_FACTORY_OBSERVER = "hibernate.ejb.session_factory_observer";
|
||||
String SESSION_FACTORY_OBSERVER = "hibernate.ejb.session_factory_observer";
|
||||
|
||||
/**
|
||||
* Naming strategy class name, the class has to have a no-arg constructor
|
||||
*/
|
||||
public static final String NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
|
||||
String NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
|
||||
|
||||
/**
|
||||
* IdentifierGeneratorStrategyProvider class name, the class must have a no-arg constructor
|
||||
* @deprecated if possible wait of Hibernate 4.1 and theService registry (MutableIdentifierGeneratorStrategy service)
|
||||
*/
|
||||
public static final String IDENTIFIER_GENERATOR_STRATEGY_PROVIDER = "hibernate.ejb.identifier_generator_strategy_provider";
|
||||
String IDENTIFIER_GENERATOR_STRATEGY_PROVIDER = "hibernate.ejb.identifier_generator_strategy_provider";
|
||||
|
||||
/**
|
||||
* Event configuration should follow the following pattern
|
||||
* hibernate.ejb.event.[eventType] f.q.c.n.EventListener1, f.q.c.n.EventListener12 ...
|
||||
*/
|
||||
public static final String EVENT_LISTENER_PREFIX = "hibernate.ejb.event";
|
||||
String EVENT_LISTENER_PREFIX = "hibernate.ejb.event";
|
||||
|
||||
/**
|
||||
* Enable the class file enhancement
|
||||
*/
|
||||
public static final String USE_CLASS_ENHANCER = "hibernate.ejb.use_class_enhancer";
|
||||
String USE_CLASS_ENHANCER = "hibernate.ejb.use_class_enhancer";
|
||||
|
||||
/**
|
||||
* Whether or not discard persistent context on entityManager.close()
|
||||
* The EJB3 compliant and default choice is false
|
||||
*/
|
||||
public static final String DISCARD_PC_ON_CLOSE = "hibernate.ejb.discard_pc_on_close";
|
||||
String DISCARD_PC_ON_CLOSE = "hibernate.ejb.discard_pc_on_close";
|
||||
|
||||
/**
|
||||
* Consider this as experimental
|
||||
|
@ -445,20 +445,20 @@ public interface AvailableSettings {
|
|||
* @deprecated Configuration going away.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String CONFIGURATION_JNDI_NAME = "hibernate.ejb.configuration_jndi_name";
|
||||
String CONFIGURATION_JNDI_NAME = "hibernate.ejb.configuration_jndi_name";
|
||||
|
||||
/**
|
||||
* Used to determine flush mode.
|
||||
*/
|
||||
//Use the org.hibernate prefix. instead of hibernate. as it is a query hint se QueryHints
|
||||
public static final String FLUSH_MODE = "org.hibernate.flushMode";
|
||||
String FLUSH_MODE = "org.hibernate.flushMode";
|
||||
|
||||
/**
|
||||
* Pass an implementation of {@link org.hibernate.ejb.packaging.Scanner}:
|
||||
* - preferably an actual instance
|
||||
* - or a class name with a no-arg constructor
|
||||
*/
|
||||
public static final String SCANNER = "hibernate.ejb.resource_scanner";
|
||||
String SCANNER = "hibernate.ejb.resource_scanner";
|
||||
|
||||
/**
|
||||
* List of classes names
|
||||
|
@ -468,7 +468,7 @@ public interface AvailableSettings {
|
|||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public static final String CLASS_NAMES = "hibernate.ejb.classes";
|
||||
String CLASS_NAMES = "hibernate.ejb.classes";
|
||||
|
||||
/**
|
||||
* List of annotated packages
|
||||
|
@ -478,18 +478,18 @@ public interface AvailableSettings {
|
|||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public static final String PACKAGE_NAMES = "hibernate.ejb.packages";
|
||||
String PACKAGE_NAMES = "hibernate.ejb.packages";
|
||||
|
||||
/**
|
||||
* EntityManagerFactory name
|
||||
*/
|
||||
public static final String ENTITY_MANAGER_FACTORY_NAME = "hibernate.ejb.entitymanager_factory_name";
|
||||
String ENTITY_MANAGER_FACTORY_NAME = "hibernate.ejb.entitymanager_factory_name";
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #JPA_METAMODEL_POPULATION} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String JPA_METAMODEL_GENERATION = "hibernate.ejb.metamodel.generation";
|
||||
String JPA_METAMODEL_GENERATION = "hibernate.ejb.metamodel.generation";
|
||||
|
||||
/**
|
||||
* Setting that controls whether we seek out JPA "static metamodel" classes and populate them. Accepts
|
||||
|
@ -507,16 +507,16 @@ public interface AvailableSettings {
|
|||
* </ul>
|
||||
*
|
||||
*/
|
||||
public static final String JPA_METAMODEL_POPULATION = "hibernate.ejb.metamodel.population";
|
||||
String JPA_METAMODEL_POPULATION = "hibernate.ejb.metamodel.population";
|
||||
|
||||
|
||||
/**
|
||||
* List of classes names
|
||||
* Internal use only
|
||||
*/
|
||||
public static final String XML_FILE_NAMES = "hibernate.ejb.xml_files";
|
||||
public static final String HBXML_FILES = "hibernate.hbmxml.files";
|
||||
public static final String LOADED_CLASSES = "hibernate.ejb.loaded.classes";
|
||||
String XML_FILE_NAMES = "hibernate.ejb.xml_files";
|
||||
String HBXML_FILES = "hibernate.hbmxml.files";
|
||||
String LOADED_CLASSES = "hibernate.ejb.loaded.classes";
|
||||
|
||||
/**
|
||||
* Deprecated
|
||||
|
@ -524,7 +524,7 @@ public interface AvailableSettings {
|
|||
* @deprecated Use {@link org.hibernate.cfg.AvailableSettings#JACC_CONTEXT_ID} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String JACC_CONTEXT_ID = org.hibernate.cfg.AvailableSettings.JACC_CONTEXT_ID;
|
||||
String JACC_CONTEXT_ID = org.hibernate.cfg.AvailableSettings.JACC_CONTEXT_ID;
|
||||
|
||||
/**
|
||||
* Deprecated
|
||||
|
@ -532,7 +532,7 @@ public interface AvailableSettings {
|
|||
* @deprecated Use {@link org.hibernate.cfg.AvailableSettings#JACC_PREFIX} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String JACC_PREFIX = org.hibernate.cfg.AvailableSettings.JACC_PREFIX;
|
||||
String JACC_PREFIX = org.hibernate.cfg.AvailableSettings.JACC_PREFIX;
|
||||
|
||||
/**
|
||||
* Deprecated
|
||||
|
@ -540,11 +540,10 @@ public interface AvailableSettings {
|
|||
* @deprecated Use {@link org.hibernate.cfg.AvailableSettings#JACC_ENABLED} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String JACC_ENABLED = org.hibernate.cfg.AvailableSettings.JACC_ENABLED;
|
||||
String JACC_ENABLED = org.hibernate.cfg.AvailableSettings.JACC_ENABLED;
|
||||
|
||||
/**
|
||||
* Used to pass along the name of the persistence unit.
|
||||
*/
|
||||
public static final String PERSISTENCE_UNIT_NAME = "hibernate.ejb.persistenceUnitName";
|
||||
|
||||
String PERSISTENCE_UNIT_NAME = "hibernate.ejb.persistenceUnitName";
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
package org.hibernate.jpa.graph.internal;
|
||||
|
||||
import javax.persistence.AttributeNode;
|
||||
import javax.persistence.Subgraph;
|
||||
import javax.persistence.metamodel.Attribute;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -34,17 +33,18 @@ import java.util.Map;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.graph.spi.GraphNodeImplementor;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.jpa.HibernateEntityManagerFactory;
|
||||
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.jpa.graph.spi.GraphNodeImplementor;
|
||||
import org.hibernate.jpa.spi.HibernateEntityManagerFactoryAware;
|
||||
|
||||
/**
|
||||
* Base class for EntityGraph and Subgraph implementations.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractGraphNode<T> implements GraphNodeImplementor {
|
||||
public abstract class AbstractGraphNode<T> implements GraphNodeImplementor, HibernateEntityManagerFactoryAware{
|
||||
private static final Logger log = Logger.getLogger( AbstractGraphNode.class );
|
||||
|
||||
private final HibernateEntityManagerFactory entityManagerFactory;
|
||||
|
@ -80,7 +80,7 @@ public abstract class AbstractGraphNode<T> implements GraphNodeImplementor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public HibernateEntityManagerFactory entityManagerFactory() {
|
||||
public HibernateEntityManagerFactory getFactory() {
|
||||
return entityManagerFactory;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,11 +34,12 @@ import javax.persistence.metamodel.ManagedType;
|
|||
import javax.persistence.metamodel.PluralAttribute;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.jpa.HibernateEntityManagerFactory;
|
||||
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.jpa.internal.metamodel.Helper;
|
||||
import org.hibernate.jpa.internal.metamodel.PluralAttributeImpl;
|
||||
import org.hibernate.jpa.spi.HibernateEntityManagerFactoryAware;
|
||||
import org.hibernate.persister.collection.QueryableCollection;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.Joinable;
|
||||
|
@ -50,7 +51,7 @@ import org.hibernate.type.Type;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class AttributeNodeImpl<T> implements AttributeNode<T>, AttributeNodeImplementor<T> {
|
||||
public class AttributeNodeImpl<T> implements AttributeNode<T>, AttributeNodeImplementor<T>, HibernateEntityManagerFactoryAware {
|
||||
private final HibernateEntityManagerFactory entityManagerFactory;
|
||||
private final Attribute<?,T> attribute;
|
||||
|
||||
|
@ -77,12 +78,12 @@ public class AttributeNodeImpl<T> implements AttributeNode<T>, AttributeNodeImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
public HibernateEntityManagerFactory entityManagerFactory() {
|
||||
public HibernateEntityManagerFactory getFactory() {
|
||||
return entityManagerFactory;
|
||||
}
|
||||
|
||||
private SessionFactoryImplementor sessionFactory() {
|
||||
return (SessionFactoryImplementor) entityManagerFactory().getSessionFactory();
|
||||
return (SessionFactoryImplementor) getFactory().getSessionFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -32,6 +32,7 @@ import javax.persistence.metamodel.IdentifiableType;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.cfg.NotYetImplementedException;
|
||||
import org.hibernate.graph.spi.GraphNodeImplementor;
|
||||
import org.hibernate.jpa.HibernateEntityManagerFactory;
|
||||
|
||||
/**
|
||||
|
@ -39,7 +40,7 @@ import org.hibernate.jpa.HibernateEntityManagerFactory;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntityGraphImpl<T> extends AbstractGraphNode<T> implements EntityGraph<T> {
|
||||
public class EntityGraphImpl<T> extends AbstractGraphNode<T> implements EntityGraph<T>, GraphNodeImplementor {
|
||||
private final String name;
|
||||
private final EntityType<T> entityType;
|
||||
|
||||
|
@ -150,7 +151,7 @@ public class EntityGraphImpl<T> extends AbstractGraphNode<T> implements EntityGr
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean appliesTo(String entityName) {
|
||||
return appliesTo( entityManagerFactory().getEntityTypeByName( entityName ) );
|
||||
return appliesTo( getFactory().getEntityTypeByName( entityName ) );
|
||||
}
|
||||
|
||||
public boolean appliesTo(EntityType<? super T> entityType) {
|
||||
|
|
|
@ -29,12 +29,13 @@ import javax.persistence.metamodel.Attribute;
|
|||
import javax.persistence.metamodel.ManagedType;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.graph.spi.GraphNodeImplementor;
|
||||
import org.hibernate.jpa.HibernateEntityManagerFactory;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SubgraphImpl<T> extends AbstractGraphNode<T> implements Subgraph<T> {
|
||||
public class SubgraphImpl<T> extends AbstractGraphNode<T> implements Subgraph<T>, GraphNodeImplementor {
|
||||
private final ManagedType managedType;
|
||||
private final Class<T> subclass;
|
||||
|
||||
|
|
|
@ -23,20 +23,10 @@
|
|||
*/
|
||||
package org.hibernate.jpa.graph.internal.advisor;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.cfg.NotYetImplementedException;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.jpa.internal.metamodel.Helper;
|
||||
import org.hibernate.loader.plan.spi.CollectionFetch;
|
||||
import org.hibernate.loader.plan.spi.CompositeFetch;
|
||||
import org.hibernate.loader.plan.spi.EntityFetch;
|
||||
import org.hibernate.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.loader.plan.spi.Fetch;
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
import org.hibernate.type.EntityType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
package org.hibernate.jpa.graph.internal.advisor;
|
||||
|
||||
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,7 +30,7 @@ import java.util.Map;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
|
||||
/**
|
||||
|
|
|
@ -29,8 +29,8 @@ import java.util.Map;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.jpa.graph.internal.EntityGraphImpl;
|
||||
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
*/
|
||||
package org.hibernate.jpa.graph.internal.advisor;
|
||||
|
||||
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
|
||||
|
||||
import org.hibernate.graph.spi.AttributeNodeImplementor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
|
|
@ -26,6 +26,7 @@ package org.hibernate.jpa.spi;
|
|||
import javax.persistence.CacheRetrieveMode;
|
||||
import javax.persistence.CacheStoreMode;
|
||||
import javax.persistence.EntityExistsException;
|
||||
import javax.persistence.EntityGraph;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
import javax.persistence.EntityTransaction;
|
||||
|
@ -109,7 +110,6 @@ import org.hibernate.engine.transaction.synchronization.spi.AfterCompletionActio
|
|||
import org.hibernate.engine.transaction.synchronization.spi.ExceptionMapper;
|
||||
import org.hibernate.engine.transaction.synchronization.spi.ManagedFlushChecker;
|
||||
import org.hibernate.engine.transaction.synchronization.spi.SynchronizationCallbackCoordinator;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.jpa.AvailableSettings;
|
||||
import org.hibernate.jpa.HibernateEntityManagerFactory;
|
||||
|
@ -1098,6 +1098,12 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
CacheMode cacheMode = determineAppropriateLocalCacheMode( properties );
|
||||
LockOptions lockOptions = null;
|
||||
try {
|
||||
if ( properties != null && !properties.isEmpty() ) {
|
||||
( (SessionImplementor) session ).getLoadQueryInfluencers()
|
||||
.setFetchGraph( (EntityGraph) properties.get( QueryHints.HINT_FETCHGRAPH ) );
|
||||
( (SessionImplementor) session ).getLoadQueryInfluencers()
|
||||
.setLoadGraph( (EntityGraph) properties.get( QueryHints.HINT_LOADGRAPH ) );
|
||||
}
|
||||
session.setCacheMode( cacheMode );
|
||||
if ( lockModeType != null ) {
|
||||
lockOptions = getLockRequest( lockModeType, properties );
|
||||
|
@ -1145,6 +1151,9 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
}
|
||||
finally {
|
||||
session.setCacheMode( previousCacheMode );
|
||||
((SessionImplementor)session).getLoadQueryInfluencers().setFetchGraph( null );
|
||||
((SessionImplementor)session).getLoadQueryInfluencers().setLoadGraph( null );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, 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.jpa.spi;
|
||||
|
||||
import org.hibernate.jpa.HibernateEntityManagerFactory;
|
||||
|
||||
/**
|
||||
* Internal contact for things that have {@link HibernateEntityManagerFactory} access.
|
||||
*
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
public interface HibernateEntityManagerFactoryAware {
|
||||
/**
|
||||
* Get access to the Hibernate extended EMF contract.
|
||||
*
|
||||
* @return The Hibernate EMF contract for this EM.
|
||||
*/
|
||||
HibernateEntityManagerFactory getFactory();
|
||||
}
|
|
@ -44,13 +44,8 @@ import org.hibernate.type.Type;
|
|||
* @author Emmanuel Bernard
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface HibernateEntityManagerImplementor extends HibernateEntityManager {
|
||||
/**
|
||||
* Get access to the Hibernate extended EMF contract.
|
||||
*
|
||||
* @return The Hibernate EMF contract for this EM.
|
||||
*/
|
||||
public HibernateEntityManagerFactory getFactory();
|
||||
public interface HibernateEntityManagerImplementor extends HibernateEntityManager, HibernateEntityManagerFactoryAware {
|
||||
|
||||
|
||||
/**
|
||||
* Used to ensure the EntityManager is open, throwing IllegalStateException if it is closed.
|
||||
|
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, 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.jpa.test.graphs;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityGraph;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.graph.internal.EntityGraphImpl;
|
||||
import org.hibernate.jpa.graph.internal.SubgraphImpl;
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
import org.hibernate.loader.plan2.build.internal.FetchGraphLoadPlanBuildingStrategy;
|
||||
import org.hibernate.loader.plan2.build.internal.FetchStyleLoadPlanBuildingAssociationVisitationStrategy;
|
||||
import org.hibernate.loader.plan2.build.internal.LoadGraphLoadPlanBuildingStrategy;
|
||||
import org.hibernate.loader.plan2.build.spi.AbstractLoadPlanBuildingAssociationVisitationStrategy;
|
||||
import org.hibernate.loader.plan2.build.spi.LoadPlanTreePrinter;
|
||||
import org.hibernate.loader.plan2.build.spi.MetamodelDrivenLoadPlanBuilder;
|
||||
import org.hibernate.loader.plan2.exec.internal.AliasResolutionContextImpl;
|
||||
import org.hibernate.loader.plan2.spi.Join;
|
||||
import org.hibernate.loader.plan2.spi.LoadPlan;
|
||||
import org.hibernate.loader.plan2.spi.QuerySpace;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
public class EntityGraphLoadPlanBuilderTest extends BaseEntityManagerFunctionalTestCase {
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] { Cat.class, Person.class, Country.class };
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class Cat {
|
||||
@Id
|
||||
String name;
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
Person owner;
|
||||
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class Person {
|
||||
@Id
|
||||
String name;
|
||||
@OneToMany(mappedBy = "owner")
|
||||
Set<Cat> pets;
|
||||
@Embedded
|
||||
Address homeAddress;
|
||||
}
|
||||
|
||||
@Embeddable
|
||||
public static class Address {
|
||||
@ManyToOne
|
||||
Country country;
|
||||
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class Country {
|
||||
@Id
|
||||
String name;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicFetchLoadPlanBuilding() {
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
EntityGraph eg = em.createEntityGraph( Cat.class );
|
||||
LoadPlan plan = buildLoadPlan( eg, Mode.FETCH );
|
||||
LoadPlanTreePrinter.INSTANCE.logTree( plan, new AliasResolutionContextImpl( sfi() ) );
|
||||
QuerySpace rootQuerySpace = plan.getQuerySpaces().getRootQuerySpaces().get( 0 );
|
||||
assertFalse(
|
||||
"With fetchgraph property and an empty EntityGraph, there should be no join at all",
|
||||
rootQuerySpace.getJoins().iterator().hasNext()
|
||||
);
|
||||
// -------------------------------------------------- another a little more complicated case
|
||||
eg = em.createEntityGraph( Cat.class );
|
||||
eg.addSubgraph( "owner", Person.class );
|
||||
plan = buildLoadPlan( eg, Mode.FETCH );
|
||||
LoadPlanTreePrinter.INSTANCE.logTree( plan, new AliasResolutionContextImpl( sfi() ) );
|
||||
rootQuerySpace = plan.getQuerySpaces().getRootQuerySpaces().get( 0 );
|
||||
Iterator<Join> iterator = rootQuerySpace.getJoins().iterator();
|
||||
assertTrue(
|
||||
"With fetchgraph property and an empty EntityGraph, there should be no join at all", iterator.hasNext()
|
||||
);
|
||||
Join personJoin = iterator.next();
|
||||
assertNotNull( personJoin );
|
||||
QuerySpace.Disposition disposition = personJoin.getRightHandSide().getDisposition();
|
||||
assertEquals(
|
||||
"This should be an entity join which fetches Person", QuerySpace.Disposition.ENTITY, disposition
|
||||
);
|
||||
|
||||
iterator = personJoin.getRightHandSide().getJoins().iterator();
|
||||
assertTrue( "The composite address should be fetched", iterator.hasNext() );
|
||||
Join addressJoin = iterator.next();
|
||||
assertNotNull( addressJoin );
|
||||
disposition = addressJoin.getRightHandSide().getDisposition();
|
||||
assertEquals( QuerySpace.Disposition.COMPOSITE, disposition );
|
||||
assertFalse( iterator.hasNext() );
|
||||
assertFalse(
|
||||
"The ManyToOne attribute in composite should not be fetched",
|
||||
addressJoin.getRightHandSide().getJoins().iterator().hasNext()
|
||||
);
|
||||
em.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicLoadLoadPlanBuilding() {
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
EntityGraph eg = em.createEntityGraph( Cat.class );
|
||||
LoadPlan plan = buildLoadPlan( eg, Mode.LOAD );
|
||||
LoadPlanTreePrinter.INSTANCE.logTree( plan, new AliasResolutionContextImpl( sfi() ) );
|
||||
QuerySpace rootQuerySpace = plan.getQuerySpaces().getRootQuerySpaces().get( 0 );
|
||||
assertFalse(
|
||||
"With fetchgraph property and an empty EntityGraph, there should be no join at all",
|
||||
rootQuerySpace.getJoins().iterator().hasNext()
|
||||
);
|
||||
// -------------------------------------------------- another a little more complicated case
|
||||
eg = em.createEntityGraph( Cat.class );
|
||||
eg.addSubgraph( "owner", Person.class );
|
||||
plan = buildLoadPlan( eg, Mode.LOAD );
|
||||
LoadPlanTreePrinter.INSTANCE.logTree( plan, new AliasResolutionContextImpl( sfi() ) );
|
||||
rootQuerySpace = plan.getQuerySpaces().getRootQuerySpaces().get( 0 );
|
||||
Iterator<Join> iterator = rootQuerySpace.getJoins().iterator();
|
||||
assertTrue(
|
||||
"With fetchgraph property and an empty EntityGraph, there should be no join at all", iterator.hasNext()
|
||||
);
|
||||
Join personJoin = iterator.next();
|
||||
assertNotNull( personJoin );
|
||||
QuerySpace.Disposition disposition = personJoin.getRightHandSide().getDisposition();
|
||||
assertEquals(
|
||||
"This should be an entity join which fetches Person", QuerySpace.Disposition.ENTITY, disposition
|
||||
);
|
||||
|
||||
iterator = personJoin.getRightHandSide().getJoins().iterator();
|
||||
assertTrue( "The composite address should be fetched", iterator.hasNext() );
|
||||
Join addressJoin = iterator.next();
|
||||
assertNotNull( addressJoin );
|
||||
disposition = addressJoin.getRightHandSide().getDisposition();
|
||||
assertEquals( QuerySpace.Disposition.COMPOSITE, disposition );
|
||||
iterator = addressJoin.getRightHandSide().getJoins().iterator();
|
||||
assertTrue( iterator.hasNext() );
|
||||
Join countryJoin = iterator.next();
|
||||
assertNotNull( countryJoin );
|
||||
disposition = countryJoin.getRightHandSide().getDisposition();
|
||||
assertEquals( QuerySpace.Disposition.ENTITY, disposition );
|
||||
assertFalse(
|
||||
"The ManyToOne attribute in composite should not be fetched",
|
||||
countryJoin.getRightHandSide().getJoins().iterator().hasNext()
|
||||
);
|
||||
em.close();
|
||||
}
|
||||
|
||||
private SessionFactoryImplementor sfi() {
|
||||
return entityManagerFactory().unwrap( SessionFactoryImplementor.class );
|
||||
}
|
||||
|
||||
private LoadPlan buildLoadPlan(EntityGraph entityGraph, Mode mode) {
|
||||
|
||||
LoadQueryInfluencers loadQueryInfluencers = new LoadQueryInfluencers( sfi() );
|
||||
if ( Mode.FETCH == mode ) {
|
||||
loadQueryInfluencers.setFetchGraph( entityGraph );
|
||||
}
|
||||
else {
|
||||
loadQueryInfluencers.setLoadGraph( entityGraph );
|
||||
}
|
||||
EntityPersister ep = (EntityPersister) sfi().getClassMetadata( Cat.class );
|
||||
AbstractLoadPlanBuildingAssociationVisitationStrategy strategy = Mode.FETCH == mode ? new FetchGraphLoadPlanBuildingStrategy(
|
||||
sfi(), loadQueryInfluencers, LockMode.NONE
|
||||
) : new LoadGraphLoadPlanBuildingStrategy( sfi(), loadQueryInfluencers, LockMode.NONE );
|
||||
return MetamodelDrivenLoadPlanBuilder.buildRootEntityLoadPlan( strategy, ep );
|
||||
}
|
||||
|
||||
public static enum Mode {FETCH, LOAD}
|
||||
}
|
Loading…
Reference in New Issue