Hibernate 5和Spring - 使用SchemaExport生成DDL

10

在 Hibernate 4 - Spring 4 的设置中,可以使用 SchemaExport 对象来生成 DDL:

LocalSessionFactoryBean sfb = (LocalSessionFactoryBean) context.getBean("&sessionFactory");
SchemaExport schema = new SchemaExport(sfb.getConfiguration());  

但是Hibernate 5用SchemaExport(MetadataImplementator metadataImplementator)代替了SchemaExport(Configuration configuration)构造函数。

然而,MetadataImplementatororg.springframework.orm.hibernate5.LocalSessionFactoryBeanorg.springframework.orm.hibernate5.LocalSessionFactoryBuilder中不容易获得。

我像这样进行了修改:

MetadataSources metadataSources = (MetadataSources) FieldUtils.readField(configuration, "metadataSources", true);


Metadata metadata = metadataSources
    .getMetadataBuilder(configuration.getStandardServiceRegistryBuilder().build())
    .applyPhysicalNamingStrategy(new MyPhysicialNamingStrategy())
    .applyImplicitNamingStrategy(ImplicitNamingStrategyJpaCompliantImpl.INSTANCE)
    .build();

MetadataImplementor metadataImpl = (MetadataImplementor) metadata;
SchemaExport schema = new SchemaExport(metadataImplementor);

但是有一个更好的方法会很好,同时,验证器注释(@NotNull,@Size)没有用于DDL生成,我不知道这是Hibernate 5中的错误还是设置错误。

我正在使用hibernate 5.0.0.CR4和spring 4.2.0.RELEASE

2个回答

2
你需要实现org.hibernate.integrator.spi.Integrator接口,该接口可将所需数据存储到某个容器中。
工作示例可在此处找到:https://github.com/valery-barysok/spring4-hibernate5-stackoverflow-34612019 请将其注册为服务,方法是在META-INF/services/org.hibernate.integrator.spi.Integrator文件中注册。
public class Integrator implements org.hibernate.integrator.spi.Integrator {

    @Override
    public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
        HibernateInfoHolder.setMetadata(metadata);
        HibernateInfoHolder.setSessionFactory(sessionFactory);
        HibernateInfoHolder.setServiceRegistry(serviceRegistry);
    }

    @Override
    public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
    }
}

使用它
    new SchemaExport((MetadataImplementor) HibernateInfoHolder.getMetadata()).create(true, true);
    new SchemaUpdate(HibernateInfoHolder.getServiceRegistry(), (MetadataImplementor) HibernateInfoHolder.getMetadata()).execute(true, true);

你可以在这里找到更多信息使用Hibernate 5和Spring 4进行编程SchemaExport / SchemaUpdate

Java持久性API有“配置优于约定”原则,但验证API仅用于验证目的。 验证不是绝对的,您可以在同一字段上放置不同的验证规则。

例如,如果你有

@Size(max = 50)
@NotNull(groups = DefaultGroup.class)
@Null(groups = SecondGroup.class)
private String shortTitle;

如果它被解释为

@Size(max = 50)
@NotNull(groups = DefaultGroup.class)
@Null(groups = SecondGroup.class)
@Column(length = 255, nullable = true)
private String shortTitle;

在这里查看更多详细信息 为什么Hibernate工具的hbm2ddl生成不考虑Bean验证注释?


2

对于Hibernate 5.2.7(在我的情况下),我编写了一种基于包扫描的方法来导出模式,如下:

static void exportSchema(
        DataSource dataSource,
        Class<? extends Dialect> dialect,
        String... packagesToScan) {

    StandardServiceRegistryBuilder registryBuilder = new StandardServiceRegistryBuilder()
            .applySetting(DATASOURCE, dataSource)
            .applySetting(DIALECT, dialect); // dialect could be omitted
    MetadataSources metadataSources = new MetadataSources(registryBuilder.build());

    PathMatchingResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver();
    new LocalSessionFactoryBuilder(null, resourceLoader, metadataSources)
            .scanPackages(packagesToScan);

    Metadata metadata = metadataSources.buildMetadata();

    new SchemaExport()
            .setFormat(true)
            .create(EnumSet.of(STDOUT, DATABASE), metadata);
}

抱歉,你说“方言”可以省略,但实际上我正在尝试做完全相同的事情,但是当我没有设置方言时,我会收到错误信息 org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set。你有什么建议为什么会发生这种情况吗? - Luca
很遗憾,我现在无法回答它在哪些情况下起作用。也许这取决于dataSource... - Timofey Gorshkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接