How to validate database schema programmatically in hibernate with annotations?

僤鯓⒐⒋嵵緔 提交于 2019-12-29 06:25:18

问题


It seems that org.hibernate.cfg.Configuration object can be used to perform validation programmatically, by calling the validateSchema method. However, this method needs dialect and databaseMetadata objects. I am using Spring and I can get a hold of AnnotationSessionFactoryBean object from spring context. So far I have the following code:

    AnnotationSessionFactoryBean factory = null;
    factory = (AnnotationSessionFactoryBean) context.getBean("AnnotationSessionFactory");
    Configuration configuration = factory.getConfiguration();

    //the following line does not work, ConnectionHelper hierarchy is not visible outside the package
    ConnectionHelper connectionHelper =  
   new ManagedConnectionProviderConnectionHelper(factory.getHibernateProperties());

    Dialect dialect = Dialect.getDialect(factory.getHibernateProperties());
    Connection connection = null;
    DatabaseMetadata databaseMetadata = null;
    try {
        databaseMetadata = new DatabaseMetadata(connection, dialect);
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    configuration.validateSchema(dialect, databaseMetadata);

Am I on the right track? ConnectionHelper hierarchy is not visible out of the package so I can’t obtain the connection object that way, in order to construct databaseMetadata. How can I implement this?

EDIT: I think I have made some progress. There is a SchemaValidator class. The code now looks like this:

AnnotationSessionFactoryBean factory = context.getBean("&AnnotationSessionFactory");
Configuration configuration = factory.getConfiguration();       
SchemaValidator validator = new SchemaValidator(configuration);
validator.validate();       

Howerver, now I am getting the following error:

org.hibernate.HibernateException: No local DataSource found for configuration - 'dataSource' property must be set on LocalSessionFactoryBean


回答1:


In the end, when using Spring this is not that simple. I managed to do it extending the AnnotationSessionFactoryBean like this:

public class SchemaValidatingAnnotationSessionFactoryBean extends
    AnnotationSessionFactoryBean {

public void validateDatabaseSchema() throws DataAccessException {
    logger.info("Validating database schema for Hibernate SessionFactory");
    HibernateTemplate hibernateTemplate = new HibernateTemplate(
            getSessionFactory());
    hibernateTemplate.setFlushMode(HibernateTemplate.FLUSH_NEVER);
    hibernateTemplate.execute(new HibernateCallback() {
        public Object doInHibernate(Session session)
                throws HibernateException, SQLException {
            Connection con = session.connection();
            Dialect dialect = Dialect.getDialect(getConfiguration()
                    .getProperties());
            DatabaseMetadata metadata = new DatabaseMetadata(con, dialect);
            Configuration configuration = getConfiguration();
            configuration.validateSchema(dialect, metadata);
            return null;
        }
    });

}
}



回答2:


I have found a simpler solution for invoking hibernate mapping validation that works for me : LocalSessionFactoryBean.validateDatabaseSchema() (which effectively does the same thing as the code in Dan's answer above)

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/some-test-context.xml" })
public class TestMapping {

    @Autowired
    ApplicationContext context; 

    @Test
    public void validateSchema() {
        AnnotationSessionFactoryBean factory = (AnnotationSessionFactoryBean)context
                .getBean("&mySessionFactory");
        factory.validateDatabaseSchema(); 
    }
}


来源:https://stackoverflow.com/questions/2327423/how-to-validate-database-schema-programmatically-in-hibernate-with-annotations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!