问题描述
|
我有两个持久性类:User.java,Role.java,它们在hibernate.cfg.xml中声明。我正在用弹簧。 applicationContext.xml具有:
<bean id=\"transactionManager\" class=\"org.springframework.orm.hibernate3.HibernateTransactionManager\">
<property name=\"sessionFactory\" ref=\"sessionFactory\"/>
</bean>
<bean id=\"dataSource\" class=\"info.ems.datasource.DataSourceFactory\">
<property name=\"driverClassName\" value=\"${database.driver}\"/>
<property name=\"url\" value=\"${database.url}\"/>
<property name=\"username\" value=\"${database.username}\"/>
<property name=\"password\" value=\"${database.password}\"/>
<property name=\"validationQuery\" value=\"${database.validationQuery}\"/>
<property name=\"dataSourceJndiName\" value=\"${database.datasource.jndiname}\"/>
</bean>
<bean id=\"sessionFactory\" class=\"org.springframework.orm.hibernate3.LocalSessionfactorybean\">
<property name=\"dataSource\" ref=\"dataSource\"/>
<property name=\"configLocation\">
<value>/WEB-INF/hibernate.cfg.xml</value>
</property>
<property name=\"configurationClass\">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name=\"hibernateProperties\">
<props>
<prop key=\"hibernate.dialect\">${hibernate.dialect}</prop>
<prop key=\"hibernate.show_sql\">${hibernate.show_sql}</prop>
</props>
</property>
</bean>
<bean id=\"dao\" class=\"info.ems.hibernate.HibernateEMSDao\" init-method=\"createSchema\">
<property name=\"hibernateTemplate\">
<bean class=\"org.springframework.orm.hibernate3.HibernateTemplate\">
<property name=\"sessionFactory\" ref=\"sessionFactory\"/>
<property name=\"flushMode\">
<bean id=\"org.springframework.orm.hibernate3.HibernateAccessor.FLUSH_COMMIT\" class=\"org.springframework.beans.factory.config.FieldRetrievingfactorybean\"/>
</property>
</bean>
</property>
<property name=\"schemaHelper\">
<bean class=\"info.ems.hibernate.SchemaHelper\">
<property name=\"driverClassName\" value=\"${database.driver}\"/>
<property name=\"url\" value=\"${database.url}\"/>
<property name=\"username\" value=\"${database.username}\"/>
<property name=\"password\" value=\"${database.password}\"/>
<property name=\"hibernateDialect\" value=\"${hibernate.dialect}\"/>
<property name=\"dataSourceJndiName\" value=\"${database.datasource.jndiname}\"/>
</bean>
</property>
</bean>
DataSourceFactory.java:
public class DataSourceFactory implements factorybean,disposableBean {
/** The logger. */
private final Logger logger = LoggerFactory.getLogger(getClass());
/** The driver class name. */
private String driverClassName;
/** The url. */
private String url;
/** The username. */
private String username;
/** The password. */
private String password;
/** The validation query. */
private String validationQuery;
/** The data source jndi name. */
private String dataSourceJndiName;
/** The data source. */
private DataSource dataSource;
/**
* Sets the driver class name.
*
* @param driverClassName
* the new driver class name
*/
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
/**
* Sets the url.
*
* @param url
* the new url
*/
public void setUrl(String url) {
this.url = url;
}
/**
* Sets the username.
*
* @param username
* the new username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* Sets the password.
*
* @param password
* the new password
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Sets the validation query.
*
* @param validationQuery
* the new validation query
*/
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
/**
* Sets the data source jndi name.
*
* @param dataSourceJndiName
* the new data source jndi name
*/
public void setDataSourceJndiName(String dataSourceJndiName) {
this.dataSourceJndiName = dataSourceJndiName;
}
/*
* (non-Javadoc)
*
* @see org.springframework.beans.factory.factorybean#getobject()
*/
@Override
public Object getobject() throws Exception {
if (StringUtils.hasText(dataSourceJndiName)) {
logger.info(\"JNDI datasource requested,looking up datasource from JNDI name: \'\" + dataSourceJndiName + \"\'.\");
Jndiobjectfactorybean jndiobjectfactorybean = new Jndiobjectfactorybean();
jndiobjectfactorybean.setJndiName(dataSourceJndiName);
jndiobjectfactorybean.setResourceRef(true);
try {
jndiobjectfactorybean.afterPropertiesSet();
} catch (Exception e) {
logger.error(\"datasource init from JNDI Failed : \" + e);
logger.error(\"Aborting application startup.\");
throw new RuntimeException(e);
}
dataSource = (DataSource) jndiobjectfactorybean.getobject();
} else if (url.startsWith(\"jdbc:hsqldb:file\")) {
logger.info(\"Embedded HsqlDB mode detected,switching on spring single connection data source.\");
SingleConnectionDataSource singleConnectionDataSource = new SingleConnectionDataSource();
singleConnectionDataSource.setUrl(url);
singleConnectionDataSource.setDriverClassName(driverClassName);
singleConnectionDataSource.setUsername(username);
singleConnectionDataSource.setPassword(password);
singleConnectionDataSource.setSuppressClose(true);
dataSource = singleConnectionDataSource;
} else {
logger.info(\"Not using embedded HsqlDB or JNDI datasource,switching on Apache DBCP data source connection pooling.\");
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setUrl(url);
basicDataSource.setDriverClassName(driverClassName);
basicDataSource.setUsername(username);
basicDataSource.setPassword(password);
basicDataSource.setValidationQuery(validationQuery);
basicDataSource.setTestOnBorrow(false);
basicDataSource.setTestWhileIdle(true);
basicDataSource.setTimeBetweenevictionRunsMillis(600000);
dataSource = basicDataSource;
}
return dataSource;
}
/*
* (non-Javadoc)
*
* @see org.springframework.beans.factory.factorybean#getobjectType()
*/
@Override
public Class<?> getobjectType() {
return DataSource.class;
}
/*
* (non-Javadoc)
*
* @see org.springframework.beans.factory.factorybean#isSingleton()
*/
@Override
public boolean isSingleton() {
return true;
}
/*
* (non-Javadoc)
*
* @see org.springframework.beans.factory.disposableBean#destroy()
*/
@Override
public void destroy() throws Exception {
if (dataSource instanceof SingleConnectionDataSource) {
logger.info(\"Attempting to shut down embedded HsqlDB database.\");
Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement();
statement.executeUpdate(\"SHUTDOWN\");
statement.close();
connection.close();
logger.info(\"Embedded HsqlDB database shut down successfully.\");
} else if (dataSource instanceof BasicDataSource) {
logger.info(\"Attempting to close Apache DBCP data source.\");
((BasicDataSource) dataSource).close();
logger.info(\"Apache DBCP data source closed successfully.\");
} else {
logger.info(\"Context shutting down for JNDI datasource.\");
}
}
}
HibernateEMSDao.java:
public class HibernateEMSDao extends HibernateDaoSupport implements EMSDao {
private final Logger logger = LoggerFactory.getLogger(getClass());
private SchemaHelper schemaHelper;
public void setSchemaHelper(SchemaHelper schemaHelper) {
this.schemaHelper = schemaHelper;
}
public void storeUser(User user) {
getHibernateTemplate().merge(user);
}
public void createSchema() {
try {
getHibernateTemplate().find(\"from User user where user.id = 1\");
} catch (Exception e) {
logger.warn(\"expected database schema does not exist,will create. Error is: \" + e.getMessage());
schemaHelper.createSchema();
User admin = new User();
admin.setUsername(\"admin\");
admin.setName(\"Admin\");
admin.setEmail(\"admin\");
admin.setPassword(\"21232f297a57a5a743894a0e4a801fc3\");
logger.info(\"inserting default admin user into database\");
storeUser(admin);
logger.info(\"schema creation complete\");
return;
}
logger.info(\"database schema exists,normal startup\");
}
}
SchemaHelper.java:
public class SchemaHelper {
private final Logger logger = LoggerFactory.getLogger(getClass());
private String driverClassName;
private String url;
private String username;
private String password;
private String hibernateDialect;
private String dataSourceJndiName;
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public void setHibernateDialect(String hibernateDialect) {
this.hibernateDialect = hibernateDialect;
}
public void setUrl(String url) {
this.url = url;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setDataSourceJndiName(String dataSourceJndiName) {
this.dataSourceJndiName = dataSourceJndiName;
}
/**
* create tables using the given Hibernate configuration
*/
public void createSchema() {
AnnotationConfiguration configuration = new AnnotationConfiguration();
if (StringUtils.hasText(\"dataSourceJndiName\")) {
configuration.setProperty(\"hibernate.connection.datasource\",dataSourceJndiName);
} else {
configuration.setProperty(\"hibernate.connection.driver_class\",driverClassName);
configuration.setProperty(\"hibernate.connection.url\",url);
configuration.setProperty(\"hibernate.connection.username\",username);
configuration.setProperty(\"hibernate.connection.password\",password);
}
configuration.setProperty(\"hibernate.dialect\",hibernateDialect);
configuration.addAnnotatedClass(User.class);
configuration.addAnnotatedClass(Role.class);
logger.info(\"begin database schema creation =========================\");
new SchemaUpdate(configuration).execute(true,true);
logger.info(\"end database schema creation ===========================\");
}
}
和hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<mapping class=\"info.ems.models.User\" />
<mapping class=\"info.ems.models.Role\" />
</session-factory>
</hibernate-configuration>
如您在HibernateEMSDao.java中所看到的,我试图查找是否存在预期的数据库模式,否则将通过SchemaHelper.java创建数据库模式。但不幸的是,它不起作用。我正在例外:
13:26:04,225 INFO [STDOUT] 2011-05-29 13:26:04,225 [ScannerThread] INFO [info.ems.datasource.DataSourceFactory] - Embedded HsqlDB mode detected,switching on spring single connection data source.
13:26:05,063 INFO [STDOUT] 2011-05-29 13:26:05,063 [ScannerThread] WARN [org.hibernate.util.JDBCExceptionReporter] - sql Error: -22,sqlState: S0002
13:26:05,063 [ScannerThread] ERROR [org.hibernate.util.JDBCExceptionReporter] - Table not found in statement [select user0_.USER_ID as USER1_0_,user0_.USERNAME as USERNAME0_,user0_.PASSWORD as PASSWORD0_,user0_.NAME as NAME0_,user0_.EMAIL as EMAIL0_,user0_.LOCKED as LOCKED0_ from USER user0_ where user0_.USER_ID=1]
13:26:05,064 INFO [STDOUT] 2011-05-29 13:26:05,064 [ScannerThread] WARN [info.ems.hibernate.HibernateEMSDao] - expected database schema does not exist,will create. Error is: Could not execute query; nested exception is org.hibernate.exception.sqlGrammarException: Could not execute query
13:26:05,065 INFO [STDOUT] 2011-05-29 13:26:05,065 [ScannerThread] INFO [info.ems.hibernate.SchemaHelper] - begin database schema creation =========================
13:26:05,072 INFO [STDOUT] 2011-05-29 13:26:05,071 [ScannerThread] FATAL [org.hibernate.connection.DatasourceConnectionProvider] - Could not find datasource:
java.lang.classCastException: org.jnp.interfaces.NamingContext cannot be cast to javax.sql.DataSource
我做错了什么,任何信息对我都非常有帮助。
谢谢并恭祝安康。
解决方法
我认为(我可能错了; D)该异常确切地说明了正在发生的事情。
您定义:
<bean id=\"dataSource\" class=\"info.ems.datasource.DataSourceFactory\">
这不是数据源,然后将其传递给:
<bean id=\"sessionFactory\" class=\"org.springframework.orm.hibernate3.LocalSessionFactoryBean\">
<property name=\"dataSource\" ref=\"dataSource\"/>
上课的地方。