基于休眠注释类创建数据库模式

| 我有两个持久性类: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 INFO  [STDOUT] 2011-05-29 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\"/>
上课的地方。     

要回复问题请先登录注册