Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hibernate LocalSessionFactoryBean schemaUpdate incompatible with automatic dialect detection [SPR-7936] #12591

Closed
spring-projects-issues opened this issue Feb 3, 2011 · 3 comments
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Feb 3, 2011

James Roper opened SPR-7936 and commented

Hibernate is able to automatically detect the dialect if none is configured. However, if none is configured on LocalSessionFactoryBean, and schemaUpdate is set to true, then the following exception is thrown:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.springframework.orm.hibernate3.HibernateSystemException: The dialect was not set. Set the property hibernate.dialect.; nested exception is org.hibernate.HibernateException: The dialect was not set. Set the property hibernate.dialect.
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1338)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
	at java.security.AccessController.doPrivileged(Native Method)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:168)
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:435)
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:409)
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:537)
	at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:180)
	at org.springframework.beans.factory.annotation.InjectionMetadata.injectFields(InjectionMetadata.java:105)
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessAfterInstantiation(CommonAnnotationBeanPostProcessor.java:289)
	... 40 more
Caused by: org.springframework.orm.hibernate3.HibernateSystemException: The dialect was not set. Set the property hibernate.dialect.; nested exception is org.hibernate.HibernateException: The dialect was not set. Set the property hibernate.dialect.
	at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:676)
	at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
	at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424)
	at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:339)
	at org.springframework.orm.hibernate3.LocalSessionFactoryBean.updateDatabaseSchema(LocalSessionFactoryBean.java:953)
	at org.springframework.orm.hibernate3.LocalSessionFactoryBean.afterSessionFactoryCreation(LocalSessionFactoryBean.java:843)
	at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:213)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
	... 55 more
Caused by: org.hibernate.HibernateException: The dialect was not set. Set the property hibernate.dialect.
	at org.hibernate.dialect.Dialect.instantiateDialect(Dialect.java:305)
	at org.hibernate.dialect.Dialect.getDialect(Dialect.java:283)
	at org.hibernate.dialect.Dialect.getDialect(Dialect.java:298)
	at org.springframework.orm.hibernate3.LocalSessionFactoryBean$3.doInHibernate(LocalSessionFactoryBean.java:957)
	at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
	... 61 more

The following implementation of updateDatabaseSchema() fixes the problem:

public void updateDatabaseSchema() throws DataAccessException
{
    logger.info("Updating database schema for Hibernate SessionFactory");
    SessionFactory sessionFactory = getSessionFactory();
    final Dialect dialect = ((SessionFactoryImplementor)sessionFactory).getDialect();
    HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory);
    hibernateTemplate.setFlushMode(HibernateTemplate.FLUSH_NEVER);
    hibernateTemplate.execute(
        new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException
            {
                Connection con = session.connection();
                DatabaseMetadata metadata = new DatabaseMetadata(con, dialect);
                String[] sql = getConfiguration().generateSchemaUpdateScript(dialect, metadata);
                executeSchemaScript(con, sql);
                return null;
            }
        }
    );
}

Affects: 3.0.5

Issue Links:

Referenced from: commits f5768fe, 3bb01ee

@spring-projects-issues
Copy link
Collaborator Author

Chris Beams commented

Thanks, James! Your suggestion above works well. I'm resolving this issue now, but note that the code is not yet merged into trunk (it's on this branch at github: https://github.com/cbeams/spring-framework/tree/SPR-8066). It will of course be merged by the time we release 3.1 M2, and probably much sooner. You can watch the 'Builds' tab below to see when a snapshot build exists that includes the fix (actually, our Jira<->Bamboo integration is down at the moment, but I've just requested it be fixed for cases just such as this one). You can still subscribe to the RSS feed, though, and when it's back up you should be notified.

@spring-projects-issues
Copy link
Collaborator Author

André Schäfer commented

This fix is not merged into any release, yet.

@spring-projects-issues
Copy link
Collaborator Author

Chris Beams commented

Good catch, André! This change actually was implemented in the 3.1 timeline, but inadvertently backed out in commit 3bb01ee. It's back in now.

commit 045c97f75e231b99ebeaab48b72ccb9e1e07004b
Author: Chris Beams <cbeams@vmware.com>
Date:   Fri Mar 9 11:20:52 2012 +0200

    Support automatic Hibernate dialect detection
    
    Use the preferred SessionFactoryImplementor#getDialect call as
    opposed to the previous Dialect#getDialect approach which required
    explicitly setting the 'hibernate.dialect' property.
    
    Issue: SPR-7396

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

1 participant