org.hibernate.cfg.Environment Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate Show documentation
Show all versions of hibernate Show documentation
Relational Persistence for Java
//$Id: Environment.java 14318 2008-02-07 02:34:08Z [email protected] $
package org.hibernate.cfg;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.bytecode.BytecodeProvider;
import org.hibernate.util.ConfigHelper;
import org.hibernate.util.PropertiesHelper;
/**
* Provides access to configuration info passed in Properties objects.
*
* Hibernate has two property scopes:
*
* - Factory-level properties may be passed to the SessionFactory when it
* instantiated. Each instance might have different property values. If no
* properties are specified, the factory calls Environment.getProperties().
*
- System-level properties are shared by all factory instances and are always
* determined by the Environment properties.
*
* The only system-level properties are
*
* - hibernate.jdbc.use_streams_for_binary
*
- hibernate.cglib.use_reflection_optimizer
*
* Environment properties are populated by calling System.getProperties()
* and then from a resource named /hibernate.properties if it exists. System
* properties override properties specified in hibernate.properties.
*
* The SessionFactory is controlled by the following properties.
* Properties may be either be System properties, properties
* defined in a resource named /hibernate.properties or an instance of
* java.util.Properties passed to
* Configuration.buildSessionFactory()
*
*
* property meaning
*
* hibernate.dialect
* classname of org.hibernate.dialect.Dialect subclass
*
*
* hibernate.cache.provider_class
* classname of org.hibernate.cache.CacheProvider
* subclass (if not specified EHCache is used)
*
*
* hibernate.connection.provider_class
* classname of org.hibernate.connection.ConnectionProvider
* subclass (if not specified hueristics are used)
*
* hibernate.connection.username database username
* hibernate.connection.password database password
*
* hibernate.connection.url
* JDBC URL (when using java.sql.DriverManager)
*
*
* hibernate.connection.driver_class
* classname of JDBC driver
*
*
* hibernate.connection.isolation
* JDBC transaction isolation level (only when using
* java.sql.DriverManager)
*
*
* hibernate.connection.pool_size
* the maximum size of the connection pool (only when using
* java.sql.DriverManager)
*
*
*
* hibernate.connection.datasource
* databasource JNDI name (when using javax.sql.Datasource)
*
*
* hibernate.jndi.url JNDI InitialContext URL
*
*
* hibernate.jndi.class JNDI InitialContext classname
*
*
* hibernate.max_fetch_depth
* maximum depth of outer join fetching
*
*
* hibernate.jdbc.batch_size
* enable use of JDBC2 batch API for drivers which support it
*
*
* hibernate.jdbc.fetch_size
* set the JDBC fetch size
*
*
* hibernate.jdbc.use_scrollable_resultset
* enable use of JDBC2 scrollable resultsets (you only need this specify
* this property when using user supplied connections)
*
*
* hibernate.jdbc.use_getGeneratedKeys
* enable use of JDBC3 PreparedStatement.getGeneratedKeys() to retrieve
* natively generated keys after insert. Requires JDBC3+ driver and JRE1.4+
*
*
* hibernate.hbm2ddl.auto
* enable auto DDL export
*
*
* hibernate.default_schema
* use given schema name for unqualified tables (always optional)
*
*
* hibernate.default_catalog
* use given catalog name for unqualified tables (always optional)
*
*
* hibernate.session_factory_name
* If set, the factory attempts to bind this name to itself in the
* JNDI context. This name is also used to support cross JVM
* Session (de)serialization.
*
*
* hibernate.transaction.manager_lookup_class
* classname of org.hibernate.transaction.TransactionManagerLookup
* implementor
*
*
* hibernate.transaction.factory_class
* the factory to use for instantiating Transactions.
* (Defaults to JDBCTransactionFactory.)
*
*
* hibernate.query.substitutions query language token substitutions
*
*
*
* @see org.hibernate.SessionFactory
* @author Gavin King
*/
public final class Environment {
public static final String VERSION = "3.2.6";
/**
* ConnectionProvider implementor to use when obtaining connections
*/
public static final String CONNECTION_PROVIDER ="hibernate.connection.provider_class";
/**
* JDBC driver class
*/
public static final String DRIVER ="hibernate.connection.driver_class";
/**
* JDBC transaction isolation level
*/
public static final String ISOLATION ="hibernate.connection.isolation";
/**
* JDBC URL
*/
public static final String URL ="hibernate.connection.url";
/**
* JDBC user
*/
public static final String USER ="hibernate.connection.username";
/**
* JDBC password
*/
public static final String PASS ="hibernate.connection.password";
/**
* JDBC autocommit mode
*/
public static final String AUTOCOMMIT ="hibernate.connection.autocommit";
/**
* Maximum number of inactive connections for Hibernate's connection pool
*/
public static final String POOL_SIZE ="hibernate.connection.pool_size";
/**
* java.sql.Datasource JNDI name
*/
public static final String DATASOURCE ="hibernate.connection.datasource";
/**
* prefix for arbitrary JDBC connection properties
*/
public static final String CONNECTION_PREFIX = "hibernate.connection";
/**
* JNDI initial context class, Context.INITIAL_CONTEXT_FACTORY
*/
public static final String JNDI_CLASS ="hibernate.jndi.class";
/**
* JNDI provider URL, Context.PROVIDER_URL
*/
public static final String JNDI_URL ="hibernate.jndi.url";
/**
* prefix for arbitrary JNDI InitialContext properties
*/
public static final String JNDI_PREFIX = "hibernate.jndi";
/**
* JNDI name to bind to SessionFactory
*/
public static final String SESSION_FACTORY_NAME = "hibernate.session_factory_name";
/**
* Hibernate SQL Dialect class
*/
public static final String DIALECT ="hibernate.dialect";
/**
* A default database schema (owner) name to use for unqualified tablenames
*/
public static final 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";
/**
* Enable logging of generated SQL to the console
*/
public static final String SHOW_SQL ="hibernate.show_sql";
/**
* Enable formatting of SQL logged to the console
*/
public static final String FORMAT_SQL ="hibernate.format_sql";
/**
* Add comments to the generated SQL
*/
public static final 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";
/**
* The default batch size for batch fetching
*/
public static final String DEFAULT_BATCH_FETCH_SIZE = "hibernate.default_batch_fetch_size";
/**
* Use java.io streams to read / write binary data from / to JDBC
*/
public static final String USE_STREAMS_FOR_BINARY = "hibernate.jdbc.use_streams_for_binary";
/**
* Use JDBC scrollable ResultSets. This property is only necessary when there is
* no ConnectionProvider, ie. the user is supplying JDBC connections.
*/
public static final 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";
/**
* 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 0, JDBC driver default settings will be used.
*/
public static final 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";
/**
* Select a custom batcher.
*/
public static final 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";
/**
* An XSLT resource used to generate "custom" XML
*/
public static final String OUTPUT_STYLESHEET ="hibernate.xml.output_stylesheet";
/**
* Maximum size of C3P0 connection pool
*/
public static final 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";
/**
* Maximum idle time for C3P0 connection pool
*/
public static final String C3P0_TIMEOUT = "hibernate.c3p0.timeout";
/**
* Maximum size of C3P0 statement cache
*/
public static final 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";
/**
* Idle time before a C3P0 pooled connection is validated
*/
public static final String C3P0_IDLE_TEST_PERIOD = "hibernate.c3p0.idle_test_period";
/**
* Proxool/Hibernate property prefix
*/
public static final String PROXOOL_PREFIX = "hibernate.proxool";
/**
* Proxool property to configure the Proxool Provider using an XML (/path/to/file.xml)
*/
public static final String PROXOOL_XML = "hibernate.proxool.xml";
/**
* Proxool property to configure the Proxool Provider using a properties file (/path/to/proxool.properties)
*/
public static final String PROXOOL_PROPERTIES = "hibernate.proxool.properties";
/**
* Proxool property to configure the Proxool Provider from an already existing pool (true / false)
*/
public static final String PROXOOL_EXISTING_POOL = "hibernate.proxool.existing_pool";
/**
* Proxool property with the Proxool pool alias to use
* (Required for PROXOOL_EXISTING_POOL, PROXOOL_PROPERTIES, or
* PROXOOL_XML)
*/
public static final 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";
/**
* Enable automatic flush during the JTA beforeCompletion() callback
*/
public static final 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";
/**
* Context scoping impl for {@link org.hibernate.SessionFactory#getCurrentSession()} processing.
*/
public static final String CURRENT_SESSION_CONTEXT_CLASS = "hibernate.current_session_context_class";
/**
* TransactionFactory implementor to use for creating Transactions
*/
public static final String TRANSACTION_STRATEGY = "hibernate.transaction.factory_class";
/**
* TransactionManagerLookup implementor to use for obtaining the TransactionManager
*/
public static final String TRANSACTION_MANAGER_STRATEGY = "hibernate.transaction.manager_lookup_class";
/**
* JNDI name of JTA UserTransaction object
*/
public static final String USER_TRANSACTION = "jta.UserTransaction";
/**
* The CacheProvider implementation class
*/
public static final String CACHE_PROVIDER = "hibernate.cache.provider_class";
/**
* The CacheProvider implementation class
*/
public static final String CACHE_PROVIDER_CONFIG = "hibernate.cache.provider_configuration_file_resource_path";
/**
* The CacheProvider JNDI namespace, if pre-bound to JNDI.
*/
public static final 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";
/**
* The QueryCacheFactory implementation class.
*/
public static final 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";
/**
* Optimize the cache for mimimal puts instead of minimal gets
*/
public static final String USE_MINIMAL_PUTS = "hibernate.cache.use_minimal_puts";
/**
* The CacheProvider region name prefix
*/
public static final 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";
/**
* Enable statistics collection
*/
public static final String GENERATE_STATISTICS = "hibernate.generate_statistics";
public static final 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";
/**
* The classname of the HQL query parser factory
*/
public static final String QUERY_TRANSLATOR = "hibernate.query.factory_class";
/**
* A comma-seperated list of token substitutions to use when translating a Hibernate
* query to SQL
*/
public static final String QUERY_SUBSTITUTIONS = "hibernate.query.substitutions";
/**
* Should named queries be checked during startup (the default is enabled).
*
* Mainly intended for test environments.
*/
public static final String QUERY_STARTUP_CHECKING = "hibernate.query.startup_check";
/**
* Auto export/update schema using hbm2ddl tool. Valid values are update,
* create, create-drop and validate.
*/
public static final String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
/**
* The {@link org.hibernate.exception.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";
/**
* 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";
/**
* Enable ordering of update statements by primary key value
*/
public static final String ORDER_UPDATES = "hibernate.order_updates";
/**
* Enable ordering of insert statements for the purpose of more effecient JDBC batching.
*/
public static final String ORDER_INSERTS = "hibernate.order_inserts";
/**
* The EntityMode in which set the Session opened from the SessionFactory.
*/
public static final String DEFAULT_ENTITY_MODE = "hibernate.default_entity_mode";
/**
* The jacc context id of the deployment
*/
public static final String JACC_CONTEXTID = "hibernate.jacc_context_id";
public static final String BYTECODE_PROVIDER = "hibernate.bytecode.provider";
public static final String JPAQL_STRICT_COMPLIANCE= "hibernate.query.jpaql_strict_compliance";
private static final BytecodeProvider BYTECODE_PROVIDER_INSTANCE;
private static final boolean ENABLE_BINARY_STREAMS;
private static final boolean ENABLE_REFLECTION_OPTIMIZER;
private static final boolean JVM_SUPPORTS_LINKED_HASH_COLLECTIONS;
private static final boolean JVM_HAS_TIMESTAMP_BUG;
private static final boolean JVM_HAS_JDK14_TIMESTAMP;
private static final boolean JVM_SUPPORTS_GET_GENERATED_KEYS;
private static final Properties GLOBAL_PROPERTIES;
private static final HashMap ISOLATION_LEVELS = new HashMap();
private static final Map OBSOLETE_PROPERTIES = new HashMap();
private static final Map RENAMED_PROPERTIES = new HashMap();
private static final Log log = LogFactory.getLog(Environment.class);
/**
* Issues warnings to the user when any obsolete property names are used.
*/
public static void verifyProperties(Properties props) {
Iterator iter = props.keySet().iterator();
Map propertiesToAdd = new HashMap();
while ( iter.hasNext() ) {
final Object propertyName = iter.next();
Object newPropertyName = OBSOLETE_PROPERTIES.get( propertyName );
if ( newPropertyName != null ) {
log.warn( "Usage of obsolete property: " + propertyName + " no longer supported, use: " + newPropertyName );
}
newPropertyName = RENAMED_PROPERTIES.get( propertyName );
if ( newPropertyName != null ) {
log.warn( "Property [" + propertyName + "] has been renamed to [" + newPropertyName + "]; update your properties appropriately" );
if ( ! props.containsKey( newPropertyName ) ) {
propertiesToAdd.put( newPropertyName, props.get( propertyName ) );
}
}
}
props.putAll(propertiesToAdd);
}
static {
log.info("Hibernate " + VERSION);
RENAMED_PROPERTIES.put( "hibernate.cglib.use_reflection_optimizer", USE_REFLECTION_OPTIMIZER );
ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_NONE), "NONE" );
ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_READ_UNCOMMITTED), "READ_UNCOMMITTED" );
ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_READ_COMMITTED), "READ_COMMITTED" );
ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_REPEATABLE_READ), "REPEATABLE_READ" );
ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_SERIALIZABLE), "SERIALIZABLE" );
GLOBAL_PROPERTIES = new Properties();
//Set USE_REFLECTION_OPTIMIZER to false to fix HHH-227
GLOBAL_PROPERTIES.setProperty( USE_REFLECTION_OPTIMIZER, Boolean.FALSE.toString() );
try {
InputStream stream = ConfigHelper.getResourceAsStream("/hibernate.properties");
try {
GLOBAL_PROPERTIES.load(stream);
log.info( "loaded properties from resource hibernate.properties: " + PropertiesHelper.maskOut(GLOBAL_PROPERTIES, PASS) );
}
catch (Exception e) {
log.error("problem loading properties from hibernate.properties");
}
finally {
try{
stream.close();
}
catch (IOException ioe){
log.error("could not close stream on hibernate.properties", ioe);
}
}
}
catch (HibernateException he) {
log.info("hibernate.properties not found");
}
try {
GLOBAL_PROPERTIES.putAll( System.getProperties() );
}
catch (SecurityException se) {
log.warn("could not copy system properties, system properties will be ignored");
}
verifyProperties(GLOBAL_PROPERTIES);
ENABLE_BINARY_STREAMS = PropertiesHelper.getBoolean(USE_STREAMS_FOR_BINARY, GLOBAL_PROPERTIES);
ENABLE_REFLECTION_OPTIMIZER = PropertiesHelper.getBoolean(USE_REFLECTION_OPTIMIZER, GLOBAL_PROPERTIES);
if (ENABLE_BINARY_STREAMS) {
log.info("using java.io streams to persist binary types");
}
if (ENABLE_REFLECTION_OPTIMIZER) {
log.info("using bytecode reflection optimizer");
}
BYTECODE_PROVIDER_INSTANCE = buildBytecodeProvider( GLOBAL_PROPERTIES );
boolean getGeneratedKeysSupport;
try {
Statement.class.getMethod("getGeneratedKeys", null);
getGeneratedKeysSupport = true;
}
catch (NoSuchMethodException nsme) {
getGeneratedKeysSupport = false;
}
JVM_SUPPORTS_GET_GENERATED_KEYS = getGeneratedKeysSupport;
if (!JVM_SUPPORTS_GET_GENERATED_KEYS) log.info("JVM does not support Statement.getGeneratedKeys()");
boolean linkedHashSupport;
try {
Class.forName("java.util.LinkedHashSet");
linkedHashSupport = true;
}
catch (ClassNotFoundException cnfe) {
linkedHashSupport = false;
}
JVM_SUPPORTS_LINKED_HASH_COLLECTIONS = linkedHashSupport;
if (!JVM_SUPPORTS_LINKED_HASH_COLLECTIONS) log.info("JVM does not support LinkedHasMap, LinkedHashSet - ordered maps and sets disabled");
JVM_HAS_TIMESTAMP_BUG = new Timestamp(123456789).getTime() != 123456789;
if (JVM_HAS_TIMESTAMP_BUG) log.info("using workaround for JVM bug in java.sql.Timestamp");
Timestamp t = new Timestamp(0);
t.setNanos(5 * 1000000);
JVM_HAS_JDK14_TIMESTAMP = t.getTime() == 5;
if (JVM_HAS_JDK14_TIMESTAMP) {
log.info("using JDK 1.4 java.sql.Timestamp handling");
}
else {
log.info("using pre JDK 1.4 java.sql.Timestamp handling");
}
}
public static BytecodeProvider getBytecodeProvider() {
return BYTECODE_PROVIDER_INSTANCE;
}
/**
* Does this JVM have the IBM JDK 1.3.1. The bug is new Timestamp(x).getTime()!=x.
*/
public static boolean jvmHasTimestampBug() {
return JVM_HAS_TIMESTAMP_BUG;
}
/**
* Does this JVM handle Timestamp in the JDK 1.4 compliant way?
*/
public static boolean jvmHasJDK14Timestamp() {
return JVM_HAS_JDK14_TIMESTAMP;
}
/**
* Does this JVM support LinkedHashSet, LinkedHashMap.
* @see java.util.LinkedHashSet
* @see java.util.LinkedHashMap
*/
public static boolean jvmSupportsLinkedHashCollections() {
return JVM_SUPPORTS_LINKED_HASH_COLLECTIONS;
}
public static boolean jvmSupportsGetGeneratedKeys() {
return JVM_SUPPORTS_GET_GENERATED_KEYS;
}
/**
* Should we use streams to bind binary types to JDBC IN parameters.
* Property hibernate.jdbc.use_streams_for_binary.
* @see Environment#USE_STREAMS_FOR_BINARY
*/
public static boolean useStreamsForBinary() {
return ENABLE_BINARY_STREAMS;
}
/**
* Should we use CGLIB reflection optimizer.
* Property hibernate.jdbc.use_refection_optimizer.
* @see Environment#USE_REFLECTION_OPTIMIZER
*/
public static boolean useReflectionOptimizer() {
return ENABLE_REFLECTION_OPTIMIZER;
}
private Environment() { throw new UnsupportedOperationException(); }
/**
* Return System properties, extended by any properties specified
* in hibernate.properties.
* @return Properties
*/
public static Properties getProperties() {
Properties copy = new Properties();
copy.putAll(GLOBAL_PROPERTIES);
return copy;
}
/**
* Get the name of a JDBC transaction isolation level
*
* @see java.sql.Connection
* @param isolation as defined by java.sql.Connection
* @return a human-readable name
*/
public static String isolationLevelToString(int isolation) {
return (String) ISOLATION_LEVELS.get( new Integer(isolation) );
}
public static BytecodeProvider buildBytecodeProvider(Properties properties) {
String provider = PropertiesHelper.getString( Environment.BYTECODE_PROVIDER, properties, "cglib" );
log.info( "Bytecode provider name : " + provider );
return buildBytecodeProvider( provider );
}
private static BytecodeProvider buildBytecodeProvider(String providerName) {
if ( "javassist".equals( providerName ) ) {
return new org.hibernate.bytecode.javassist.BytecodeProviderImpl();
}
else if ( "cglib".equals( providerName ) ) {
return new org.hibernate.bytecode.cglib.BytecodeProviderImpl();
}
else {
log.warn( "unrecognized bytecode provider [" + providerName + "], using cglib by default" );
return new org.hibernate.bytecode.cglib.BytecodeProviderImpl();
}
}
}