001
014
015 package com.liferay.portal.spring.hibernate;
016
017 import com.liferay.portal.dao.orm.hibernate.DB2Dialect;
018 import com.liferay.portal.dao.orm.hibernate.SQLServer2005Dialect;
019 import com.liferay.portal.dao.orm.hibernate.SQLServer2008Dialect;
020 import com.liferay.portal.kernel.dao.jdbc.DataAccess;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.util.GetterUtil;
024 import com.liferay.portal.kernel.util.StringBundler;
025 import com.liferay.portal.kernel.util.StringPool;
026
027 import java.sql.Connection;
028 import java.sql.DatabaseMetaData;
029
030 import java.util.Map;
031 import java.util.Properties;
032 import java.util.concurrent.ConcurrentHashMap;
033
034 import javax.sql.DataSource;
035
036 import org.hibernate.dialect.DB2400Dialect;
037 import org.hibernate.dialect.Dialect;
038 import org.hibernate.dialect.Oracle10gDialect;
039 import org.hibernate.dialect.SybaseASE15Dialect;
040 import org.hibernate.dialect.resolver.DialectFactory;
041
042
045 public class DialectDetector {
046
047 public static Dialect getDialect(DataSource dataSource) {
048 String dialectKey = null;
049 Dialect dialect = null;
050
051 Connection connection = null;
052
053 try {
054 connection = dataSource.getConnection();
055
056 DatabaseMetaData databaseMetaData = connection.getMetaData();
057
058 String dbName = databaseMetaData.getDatabaseProductName();
059 int dbMajorVersion = databaseMetaData.getDatabaseMajorVersion();
060
061 dialectKey = dbName.concat(StringPool.COLON).concat(
062 String.valueOf(dbMajorVersion));
063
064 dialect = _dialects.get(dialectKey);
065
066 if (dialect != null) {
067 return dialect;
068 }
069
070 if (_log.isInfoEnabled()) {
071 _log.info(
072 "Determine dialect for " + dbName + " " + dbMajorVersion);
073 }
074
075 if (dbName.startsWith("HSQL")) {
076 if (_log.isWarnEnabled()) {
077 StringBundler sb = new StringBundler(6);
078
079 sb.append("Liferay is configured to use Hypersonic as ");
080 sb.append("its database. Do NOT use Hypersonic in ");
081 sb.append("production. Hypersonic is an embedded ");
082 sb.append("database useful for development and demo'ing ");
083 sb.append("purposes. The database settings can be ");
084 sb.append("changed in portal-ext.properties.");
085
086 _log.warn(sb.toString());
087 }
088 }
089
090 if (dbName.equals("ASE") && (dbMajorVersion == 15)) {
091 dialect = new SybaseASE15Dialect();
092 }
093 else if (dbName.startsWith("DB2") && (dbMajorVersion >= 9)) {
094 dialect = new DB2Dialect();
095 }
096 else if (dbName.startsWith("Microsoft") && (dbMajorVersion == 9)) {
097 dialect = new SQLServer2005Dialect();
098 }
099 else if (dbName.startsWith("Microsoft") && (dbMajorVersion == 10)) {
100 dialect = new SQLServer2008Dialect();
101 }
102 else if (dbName.startsWith("Oracle") && (dbMajorVersion >= 10)) {
103 dialect = new Oracle10gDialect();
104 }
105 else {
106 dialect = DialectFactory.buildDialect(
107 new Properties(), connection);
108 }
109 }
110 catch (Exception e) {
111 String msg = GetterUtil.getString(e.getMessage());
112
113 if (msg.contains("explicitly set for database: DB2")) {
114 dialect = new DB2400Dialect();
115
116 if (_log.isWarnEnabled()) {
117 _log.warn(
118 "DB2400Dialect was dynamically chosen as the " +
119 "Hibernate dialect for DB2. This can be " +
120 "overriden in portal.properties");
121 }
122 }
123 else {
124 _log.error(e, e);
125 }
126 }
127 finally {
128 DataAccess.cleanUp(connection);
129 }
130
131 if (dialect == null) {
132 throw new RuntimeException("No dialect found");
133 }
134 else if (dialectKey != null) {
135 if (_log.isInfoEnabled()) {
136 _log.info("Found dialect " + dialect.getClass().getName());
137 }
138
139 _dialects.put(dialectKey, dialect);
140 }
141
142 return dialect;
143 }
144
145 private static Log _log = LogFactoryUtil.getLog(DialectDetector.class);
146
147 private static Map<String, Dialect> _dialects =
148 new ConcurrentHashMap<String, Dialect>();
149
150 }