1 package org.hibernate.cfg; 3 4 import java.io.Serializable ; 5 import java.lang.reflect.Method ; 6 import java.sql.Connection ; 7 import java.sql.DatabaseMetaData ; 8 import java.sql.ResultSet ; 9 import java.sql.SQLException ; 10 import java.util.Map ; 11 import java.util.Properties ; 12 13 import org.apache.commons.logging.Log; 14 import org.apache.commons.logging.LogFactory; 15 import org.hibernate.ConnectionReleaseMode; 16 import org.hibernate.EntityMode; 17 import org.hibernate.HibernateException; 18 import org.hibernate.cache.CacheProvider; 19 import org.hibernate.cache.NoCacheProvider; 20 import org.hibernate.cache.QueryCacheFactory; 21 import org.hibernate.connection.ConnectionProvider; 22 import org.hibernate.connection.ConnectionProviderFactory; 23 import org.hibernate.dialect.Dialect; 24 import org.hibernate.dialect.DialectFactory; 25 import org.hibernate.exception.SQLExceptionConverter; 26 import org.hibernate.exception.SQLExceptionConverterFactory; 27 import org.hibernate.hql.QueryTranslatorFactory; 28 import org.hibernate.jdbc.BatcherFactory; 29 import org.hibernate.jdbc.BatchingBatcherFactory; 30 import org.hibernate.jdbc.NonBatchingBatcherFactory; 31 import org.hibernate.transaction.TransactionFactory; 32 import org.hibernate.transaction.TransactionFactoryFactory; 33 import org.hibernate.transaction.TransactionManagerLookup; 34 import org.hibernate.transaction.TransactionManagerLookupFactory; 35 import org.hibernate.util.PropertiesHelper; 36 import org.hibernate.util.ReflectHelper; 37 import org.hibernate.util.StringHelper; 38 39 44 public class SettingsFactory implements Serializable { 45 46 private static final Log log = LogFactory.getLog(SettingsFactory.class); 47 48 protected SettingsFactory() throws HibernateException {} 49 50 public Settings buildSettings(Properties props) { 51 Settings settings = new Settings(); 52 53 55 String sessionFactoryName = props.getProperty(Environment.SESSION_FACTORY_NAME); 56 settings.setSessionFactoryName(sessionFactoryName); 57 58 60 ConnectionProvider connections = createConnectionProvider(props); 61 settings.setConnectionProvider(connections); 62 63 65 boolean metaSupportsScrollable = false; 66 boolean metaSupportsGetGeneratedKeys = false; 67 boolean metaSupportsBatchUpdates = false; 68 String databaseName = null; 69 int databaseMajorVersion = 0; 70 71 try { 72 Connection conn = connections.getConnection(); 73 try { 74 DatabaseMetaData meta = conn.getMetaData(); 75 databaseName = meta.getDatabaseProductName(); 76 databaseMajorVersion = getDatabaseMajorVersion(meta); 77 log.info("RDBMS: " + databaseName + ", version: " + meta.getDatabaseProductVersion() ); 78 log.info("JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion() ); 79 80 metaSupportsScrollable = meta.supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE); 81 metaSupportsBatchUpdates = meta.supportsBatchUpdates(); 82 83 if ( Environment.jvmSupportsGetGeneratedKeys() ) { 84 try { 85 Boolean result = (Boolean ) DatabaseMetaData .class.getMethod("supportsGetGeneratedKeys", null) 86 .invoke(meta, null); 87 metaSupportsGetGeneratedKeys = result.booleanValue(); 88 } 89 catch (AbstractMethodError ame) { 90 metaSupportsGetGeneratedKeys = false; 91 } 92 catch (Exception e) { 93 metaSupportsGetGeneratedKeys = false; 94 } 95 } 96 97 } 98 finally { 99 connections.closeConnection(conn); 100 } 101 } 102 catch (SQLException sqle) { 103 log.warn("Could not obtain connection metadata", sqle); 104 } 105 catch (UnsupportedOperationException uoe) { 106 } 108 109 Dialect dialect = determineDialect( props, databaseName, databaseMajorVersion ); 111 settings.setDialect(dialect); 112 113 final Properties properties = new Properties (); 115 properties.putAll( dialect.getDefaultProperties() ); 116 properties.putAll(props); 117 118 120 TransactionFactory transactionFactory = createTransactionFactory(properties); 121 settings.setTransactionFactory(transactionFactory); 122 settings.setTransactionManagerLookup( createTransactionManagerLookup(properties) ); 123 124 boolean flushBeforeCompletion = PropertiesHelper.getBoolean(Environment.FLUSH_BEFORE_COMPLETION, properties); 125 log.info("Automatic flush during beforeCompletion(): " + enabledDisabled(flushBeforeCompletion) ); 126 settings.setFlushBeforeCompletionEnabled(flushBeforeCompletion); 127 128 boolean autoCloseSession = PropertiesHelper.getBoolean(Environment.AUTO_CLOSE_SESSION, properties); 129 log.info("Automatic session close at end of transaction: " + enabledDisabled(autoCloseSession) ); 130 settings.setAutoCloseSessionEnabled(autoCloseSession); 131 132 134 int batchSize = PropertiesHelper.getInt(Environment.STATEMENT_BATCH_SIZE, properties, 0); 135 if ( !metaSupportsBatchUpdates ) batchSize = 0; 136 if (batchSize>0) log.info("JDBC batch size: " + batchSize); 137 settings.setJdbcBatchSize(batchSize); 138 boolean jdbcBatchVersionedData = PropertiesHelper.getBoolean(Environment.BATCH_VERSIONED_DATA, properties, false); 139 if (batchSize>0) log.info("JDBC batch updates for versioned data: " + enabledDisabled(jdbcBatchVersionedData) ); 140 settings.setJdbcBatchVersionedData(jdbcBatchVersionedData); 141 settings.setBatcherFactory( createBatcherFactory(properties, batchSize) ); 142 143 boolean useScrollableResultSets = PropertiesHelper.getBoolean(Environment.USE_SCROLLABLE_RESULTSET, properties, metaSupportsScrollable); 144 log.info("Scrollable result sets: " + enabledDisabled(useScrollableResultSets) ); 145 settings.setScrollableResultSetsEnabled(useScrollableResultSets); 146 147 boolean wrapResultSets = PropertiesHelper.getBoolean(Environment.WRAP_RESULT_SETS, properties, false); 148 log.debug( "Wrap result sets: " + enabledDisabled(wrapResultSets) ); 149 settings.setWrapResultSetsEnabled(wrapResultSets); 150 151 boolean useGetGeneratedKeys = PropertiesHelper.getBoolean(Environment.USE_GET_GENERATED_KEYS, properties, metaSupportsGetGeneratedKeys); 152 log.info("JDBC3 getGeneratedKeys(): " + enabledDisabled(useGetGeneratedKeys) ); 153 settings.setGetGeneratedKeysEnabled(useGetGeneratedKeys); 154 155 Integer statementFetchSize = PropertiesHelper.getInteger(Environment.STATEMENT_FETCH_SIZE, properties); 156 if (statementFetchSize!=null) log.info("JDBC result set fetch size: " + statementFetchSize); 157 settings.setJdbcFetchSize(statementFetchSize); 158 159 String releaseModeName = properties.getProperty( Environment.RELEASE_CONNECTIONS ); 160 log.info( "Connection release mode: " + releaseModeName ); 161 ConnectionReleaseMode releaseMode; 162 if ( "auto".equals(releaseModeName) ) { 163 releaseMode = transactionFactory.getDefaultReleaseMode(); 164 } 165 else { 166 releaseMode = ConnectionReleaseMode.parse( releaseModeName ); 167 if ( releaseMode == ConnectionReleaseMode.AFTER_STATEMENT && !connections.supportsAggressiveRelease() ) { 168 log.warn( "Overriding release mode as connection provider does not support 'after_statement'" ); 169 releaseMode = ConnectionReleaseMode.AFTER_TRANSACTION; 170 } 171 } 172 settings.setConnectionReleaseMode( releaseMode ); 173 174 176 String defaultSchema = properties.getProperty(Environment.DEFAULT_SCHEMA); 177 String defaultCatalog = properties.getProperty(Environment.DEFAULT_CATALOG); 178 if (defaultSchema!=null) log.info("Default schema: " + defaultSchema); 179 if (defaultCatalog!=null) log.info("Default catalog: " + defaultCatalog); 180 settings.setDefaultSchemaName(defaultSchema); 181 settings.setDefaultCatalogName(defaultCatalog); 182 183 Integer maxFetchDepth = PropertiesHelper.getInteger(Environment.MAX_FETCH_DEPTH, properties); 184 if (maxFetchDepth!=null) log.info("Maximum outer join fetch depth: " + maxFetchDepth); 185 settings.setMaximumFetchDepth(maxFetchDepth); 186 int batchFetchSize = PropertiesHelper.getInt(Environment.DEFAULT_BATCH_FETCH_SIZE, properties, 1); 187 log.info("Default batch fetch size: " + batchFetchSize); 188 settings.setDefaultBatchFetchSize(batchFetchSize); 189 190 boolean comments = PropertiesHelper.getBoolean(Environment.USE_SQL_COMMENTS, properties); 191 log.info( "Generate SQL with comments: " + enabledDisabled(comments) ); 192 settings.setCommentsEnabled(comments); 193 194 boolean orderUpdates = PropertiesHelper.getBoolean(Environment.ORDER_UPDATES, properties); 195 log.info( "Order SQL updates by primary key: " + enabledDisabled(orderUpdates) ); 196 settings.setOrderUpdatesEnabled(orderUpdates); 197 198 200 settings.setQueryTranslatorFactory( createQueryTranslatorFactory(properties) ); 201 202 Map querySubstitutions = PropertiesHelper.toMap(Environment.QUERY_SUBSTITUTIONS, " ,=;:\n\t\r\f", properties); 203 log.info("Query language substitutions: " + querySubstitutions); 204 settings.setQuerySubstitutions(querySubstitutions); 205 206 208 boolean useSecondLevelCache = PropertiesHelper.getBoolean(Environment.USE_SECOND_LEVEL_CACHE, properties, true); 209 log.info( "Second-level cache: " + enabledDisabled(useSecondLevelCache) ); 210 settings.setSecondLevelCacheEnabled(useSecondLevelCache); 211 212 boolean useQueryCache = PropertiesHelper.getBoolean(Environment.USE_QUERY_CACHE, properties); 213 log.info( "Query cache: " + enabledDisabled(useQueryCache) ); 214 settings.setQueryCacheEnabled(useQueryCache); 215 216 if ( useSecondLevelCache || useQueryCache ) { 217 settings.setCacheProvider( createCacheProvider( properties ) ); 220 } 221 else { 222 settings.setCacheProvider( new NoCacheProvider() ); 223 } 224 225 boolean useMinimalPuts = PropertiesHelper.getBoolean( 226 Environment.USE_MINIMAL_PUTS, properties, settings.getCacheProvider().isMinimalPutsEnabledByDefault() 227 ); 228 log.info( "Optimize cache for minimal puts: " + enabledDisabled(useMinimalPuts) ); 229 settings.setMinimalPutsEnabled(useMinimalPuts); 230 231 String prefix = properties.getProperty(Environment.CACHE_REGION_PREFIX); 232 if ( StringHelper.isEmpty(prefix) ) prefix=null; 233 if (prefix!=null) log.info("Cache region prefix: "+ prefix); 234 settings.setCacheRegionPrefix(prefix); 235 236 boolean useStructuredCacheEntries = PropertiesHelper.getBoolean(Environment.USE_STRUCTURED_CACHE, properties, false); 237 log.info( "Structured second-level cache entries: " + enabledDisabled(useStructuredCacheEntries) ); 238 settings.setStructuredCacheEntriesEnabled(useStructuredCacheEntries); 239 240 if (useQueryCache) settings.setQueryCacheFactory( createQueryCacheFactory(properties) ); 241 242 244 SQLExceptionConverter sqlExceptionConverter; 245 try { 246 sqlExceptionConverter = SQLExceptionConverterFactory.buildSQLExceptionConverter( dialect, properties ); 247 } 248 catch(HibernateException e) { 249 log.warn("Error building SQLExceptionConverter; using minimal converter"); 250 sqlExceptionConverter = SQLExceptionConverterFactory.buildMinimalSQLExceptionConverter(); 251 } 252 settings.setSQLExceptionConverter(sqlExceptionConverter); 253 254 256 boolean showSql = PropertiesHelper.getBoolean(Environment.SHOW_SQL, properties); 257 if (showSql) log.info("Echoing all SQL to stdout"); 258 settings.setShowSqlEnabled(showSql); 259 260 boolean useStatistics = PropertiesHelper.getBoolean(Environment.GENERATE_STATISTICS, properties); 261 log.info( "Statistics: " + enabledDisabled(useStatistics) ); 262 settings.setStatisticsEnabled(useStatistics); 263 264 boolean useIdentifierRollback = PropertiesHelper.getBoolean(Environment.USE_IDENTIFIER_ROLLBACK, properties); 265 log.info( "Deleted entity synthetic identifier rollback: " + enabledDisabled(useIdentifierRollback) ); 266 settings.setIdentifierRollbackEnabled(useIdentifierRollback); 267 268 270 String autoSchemaExport = properties.getProperty(Environment.HBM2DDL_AUTO); 271 if ( "update".equals(autoSchemaExport) ) settings.setAutoUpdateSchema(true); 272 if ( "create".equals(autoSchemaExport) ) settings.setAutoCreateSchema(true); 273 if ( "create-drop".equals(autoSchemaExport) ) { 274 settings.setAutoCreateSchema(true); 275 settings.setAutoDropSchema(true); 276 } 277 278 EntityMode defaultEntityMode = EntityMode.parse( properties.getProperty( Environment.DEFAULT_ENTITY_MODE ) ); 279 log.info( "Default entity-mode: " + defaultEntityMode ); 280 settings.setDefaultEntityMode( defaultEntityMode ); 281 282 return settings; 283 284 } 285 286 private int getDatabaseMajorVersion(DatabaseMetaData meta) { 287 try { 288 Method gdbmvMethod = DatabaseMetaData .class.getMethod("getDatabaseMajorVersion", null); 289 return ( (Integer ) gdbmvMethod.invoke(meta, null) ).intValue(); 290 } 291 catch (NoSuchMethodException nsme) { 292 return 0; 293 } 294 catch (Throwable t) { 295 log.debug("could not get database version from JDBC metadata"); 296 return 0; 297 } 298 } 299 300 private static final String enabledDisabled(boolean value) { 301 return value ? "enabled" : "disabled"; 302 } 303 304 protected QueryCacheFactory createQueryCacheFactory(Properties properties) { 305 String queryCacheFactoryClassName = PropertiesHelper.getString( 306 Environment.QUERY_CACHE_FACTORY, properties, "org.hibernate.cache.StandardQueryCacheFactory" 307 ); 308 log.info("Query cache factory: " + queryCacheFactoryClassName); 309 try { 310 return (QueryCacheFactory) ReflectHelper.classForName(queryCacheFactoryClassName).newInstance(); 311 } 312 catch (Exception cnfe) { 313 throw new HibernateException("could not instantiate QueryCacheFactory: " + queryCacheFactoryClassName, cnfe); 314 } 315 } 316 317 protected CacheProvider createCacheProvider(Properties properties) { 318 String cacheClassName = PropertiesHelper.getString( 319 Environment.CACHE_PROVIDER, properties, "org.hibernate.cache.EhCacheProvider" 320 ); 321 log.info("Cache provider: " + cacheClassName); 322 try { 323 return (CacheProvider) ReflectHelper.classForName(cacheClassName).newInstance(); 324 } 325 catch (Exception cnfe) { 326 throw new HibernateException("could not instantiate CacheProvider: " + cacheClassName, cnfe); 327 } 328 } 329 330 protected QueryTranslatorFactory createQueryTranslatorFactory(Properties properties) { 331 String className = PropertiesHelper.getString( 332 Environment.QUERY_TRANSLATOR, properties, "org.hibernate.hql.ast.ASTQueryTranslatorFactory" 333 ); 334 log.info("Query translator: " + className); 335 try { 336 return (QueryTranslatorFactory) ReflectHelper.classForName(className).newInstance(); 337 } 338 catch (Exception cnfe) { 339 throw new HibernateException("could not instantiate QueryTranslatorFactory: " + className, cnfe); 340 } 341 } 342 343 protected BatcherFactory createBatcherFactory(Properties properties, int batchSize) { 344 String batcherClass = properties.getProperty(Environment.BATCH_STRATEGY); 345 if (batcherClass==null) { 346 return batchSize==0 ? 347 (BatcherFactory) new NonBatchingBatcherFactory() : 348 (BatcherFactory) new BatchingBatcherFactory(); 349 } 350 else { 351 log.info("Batcher factory: " + batcherClass); 352 try { 353 return (BatcherFactory) ReflectHelper.classForName(batcherClass).newInstance(); 354 } 355 catch (Exception cnfe) { 356 throw new HibernateException("could not instantiate BatcherFactory: " + batcherClass, cnfe); 357 } 358 } 359 } 360 361 protected ConnectionProvider createConnectionProvider(Properties properties) { 362 return ConnectionProviderFactory.newConnectionProvider(properties); 363 } 364 365 protected TransactionFactory createTransactionFactory(Properties properties) { 366 return TransactionFactoryFactory.buildTransactionFactory(properties); 367 } 368 369 protected TransactionManagerLookup createTransactionManagerLookup(Properties properties) { 370 return TransactionManagerLookupFactory.getTransactionManagerLookup(properties); 371 } 372 373 private Dialect determineDialect(Properties props, String databaseName, int databaseMajorVersion) { 374 return DialectFactory.buildDialect( props, databaseName, databaseMajorVersion ); 375 } 376 377 private static final Properties DIALECTS = new Properties (); 378 static { 379 DIALECTS.put( "HSQL Database Engine", "org.hibernate.dialect.HSQLDialect" ); 380 DIALECTS.put( "DB2/NT", "org.hibernate.dialect.DB2Dialect" ); 381 DIALECTS.put( "MySQL", "org.hibernate.dialect.MySQLDialect" ); 382 DIALECTS.put( "Oracle", "org.hibernate.dialect.Oracle9Dialect" ); 383 DIALECTS.put( "PostgreSQL", "org.hibernate.dialect.PostgreSQLDialect" ); 384 DIALECTS.put( "Microsoft SQL Server Database", "org.hibernate.dialect.SQLServerDialect" ); 385 DIALECTS.put( "Sybase SQL Server", "org.hibernate.dialect.SybaseDialect" ); 386 } 388 389 } 390 | Popular Tags |