2010-02-24 12 views
5

Có vẻ như đối tượng org.hibernate.cfg.Configuration có thể được sử dụng để thực hiện xác thực theo chương trình, bằng cách gọi phương thức validateSchema. Tuy nhiên, phương thức này cần phương ngữ và đối tượng cơ sở dữ liệuMetadata. Tôi đang sử dụng Spring và tôi có thể giữ một đối tượng AnnotationSessionFactoryBean từ ngữ cảnh mùa xuân. Cho đến nay tôi có đoạn mã sau:Làm cách nào để xác thực lược đồ cơ sở dữ liệu theo lập trình trong chế độ ngủ đông với các chú thích?

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); 

Tôi có đi đúng hướng không? Phân cấp ConnectionHelper không hiển thị trong gói nên tôi không thể lấy đối tượng kết nối theo cách đó, để xây dựng cơ sở dữ liệuMetadata. Làm thế nào tôi có thể thực hiện điều này?

EDIT: Tôi nghĩ rằng tôi đã thực hiện một số tiến bộ. Có một lớp SchemaValidator. Mã bây giờ trông như thế này:

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

Howerver, bây giờ tôi đang nhận được lỗi sau:

org.hibernate.HibernateException: Không DataSource địa phương tìm thấy cho cấu hình - bất động sản 'dataSource' phải được thiết lập trên LocalSessionFactoryBean

Trả lời

4

Cuối cùng, khi sử dụng Spring, điều này không đơn giản. Tôi cố gắng làm điều đó kéo dài tuổi AnnotationSessionFactoryBean như thế này:

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; 
     } 
    }); 

} 
} 
1

Tôi đã tìm thấy một giải pháp đơn giản cho cách gọi xác nhận bản đồ ngủ đông mà làm việc cho tôi: LocalSessionFactoryBean.validateDatabaseSchema() (mà hiệu quả làm điều tương tự như mã trong câu trả lời của Dan ở trên)

@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(); 
    } 
}