您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

带有Hibernate 5和Spring 4的程序化SchemaExport / SchemaUpdate

带有Hibernate 5和Spring 4的程序化SchemaExport / SchemaUpdate

我想加总Aviad的答案,以按照OP的要求完成它。

为了获得MetadataImplementor的实例,解决方法是通过Java的ServiceLoader工具注册SessionFactoryBuilderFactory的实例。然后,在引导hibernate模式时,MetadataImplementor会使用其自身的实例调用注册服务的getSessionFactoryBuilder方法代码参考如下:

因此,最终要获得MetadataImplementor的实例,必须实现SessionFactoryBuilderFactory并注册,以便ServiceLoader可以识别此服务:

    public class MetadataProvider implements SessionFactoryBuilderFactory {

        private static MetadataImplementor Metadata;

        @Override
        public SessionFactoryBuilder getSessionFactoryBuilder(MetadataImplementor Metadata, SessionFactoryBuilderImplementor defaultBuilder) {
            this.Metadata = Metadata;
            return defaultBuilder; //Just return the one provided in the argument itself. All we care about is the Metadata :)
        }

        public static MetadataImplementor getMetadata() {
            return Metadata;
        }
    }

为了注册以上内容,请在以下路径中创建简单的文本文件(假设它是一个maven项目,最终我们需要在类路径中提供“ Meta-INF”文件夹):

src/main/resources/Meta-INF/services/org.hibernate.boot.spi.SessionFactoryBuilderFactory

文本文件内容应为一行(如果需要注册多个实例,甚至可以为多行),说明SessionFactoryBuilderFactory实现的完全限定的类路径。例如,对于上述类,如果您的程序包名称为“ com.yourcompany.prj”,则文件内容应为以下内容

com.yourcompany.prj.MetadataProvider

就是这样,如果您运行应用程序,spring应用程序或独立的hibernate模式,则在启动hibernate模式后,将通过静态方法获得一个MetadataImplementor实例。

无法通过Spring注入它。我研究了Hibernate的源代码,并且元数据对象没有存储在SessionFactory中的任何位置(这是我们从Spring获得的)。因此,不可能注入它。但是,如果您希望使用Spring的方式,则有两种选择:

LocalSessionfactorybean-> MetadataSources-> MetadataBuilder

LocalSessionfactorybean是您在Spring中配置的,并且具有MetadataSources对象。MetadataSources创建MetadataBuilder,后者又创建MetadataImplementor。以上所有操作均不存储任何内容,它们只是动态创建对象并返回。如果要使用MetaData实例,则应扩展和修改上述类,以便它们在返回之前存储相应对象的本地副本。这样,您可以引用MetadataImplementor。但是除非确实需要,否则我不会真正推荐这样做,因为API可能会随着时间而变化。

        EntityManagerFactoryImpl emf=(EntityManagerFactoryImpl)lcemfb.getNativeEntityManagerFactory();
    SessionFactoryImpl sf=emf.getSessionFactory();
    StandardServiceRegistry serviceRegistry = sf.getSessionFactoryOptions().getServiceRegistry();
    MetadataSources MetadataSources = new MetadataSources(new BootstrapServiceRegistryBuilder().build());
    Metadata Metadata = MetadataSources.buildMetadata(serviceRegistry);
    SchemaUpdate update=new SchemaUpdate(serviceRegistry,Metadata); //To create SchemaUpdate

    // You can either create SchemaExport from the above details, or you can get the existing one as follows:
    try {
        Field field = SessionFactoryImpl.class.getDeclaredField("schemaExport");
        field.setAccessible(true);
        SchemaExport schemaExport = (SchemaExport) field.get(serviceRegistry);
    } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | illegalaccessexception e) {
        e.printStackTrace();
    }
Java 2022/1/1 18:13:33 有808人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶