22

Spring 4 と Hibernate 4 では、Reflection を使用して、次のコードを使用して現在の環境から Hibernate 構成オブジェクトを取得できました。

@Autowired LocalContainerEntityManagerFactoryBean lcemfb;

EntityManagerFactoryImpl emf = (EntityManagerFactoryImpl) lcemfb.getNativeEntityManagerFactory();
SessionFactoryImpl sf = emf.getSessionFactory();
SessionFactoryServiceRegistryImpl serviceRegistry = (SessionFactoryServiceRegistryImpl) sf.getServiceRegistry();
Configuration cfg = null;

try {
    Field field = SessionFactoryServiceRegistryImpl.class.getDeclaredField("configuration");
    field.setAccessible(true);
    cfg = (Configuration) field.get(serviceRegistry);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
    e.printStackTrace();
}

SchemaUpdate update = new SchemaUpdate(serviceRegistry, cfg);

Hibernate 5 ではMetadataImplementor、これらのオブジェクトのいずれからも利用できないように見える some を使用する必要があります。と一緒に使ってみましMetadataSourcesserviceRegistry。しかし、それは間違った種類のServiceRegistry.

これを機能させる他の方法はありますか?

4

4 に答える 4

10

この問題の基本的な考え方は次のとおりです。

org.hibernate.integrator.spi.Integrator必要なデータを何らかのホルダーに格納する実装。実装をサービスとして登録し、必要な場所で使用します。

ここで見つけることができる作業例https://github.com/valery-barysok/spring4-hibernate5-stackoverflow-34612019


org.hibernate.integrator.api.integrator.Integratorクラスを作成

import hello.HibernateInfoHolder;
import org.hibernate.boot.Metadata;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;

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

META-INF/services/org.hibernate.integrator.spi.Integratorファイルを作成

org.hibernate.integrator.api.integrator.Integrator

import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        new SchemaExport((MetadataImplementor) HibernateInfoHolder.getMetadata()).create(true, true);
        new SchemaUpdate(HibernateInfoHolder.getServiceRegistry(), (MetadataImplementor) HibernateInfoHolder.getMetadata()).execute(true, true);
    }
}
于 2016-01-10T02:29:03.153 に答える
1

Take a look on this one:

public class EntityMetaData implements SessionFactoryBuilderFactory {

    private static final ThreadLocal<MetadataImplementor> meta = new ThreadLocal<>();

    @Override
    public SessionFactoryBuilder getSessionFactoryBuilder(MetadataImplementor metadata, SessionFactoryBuilderImplementor defaultBuilder) {
        meta.set(metadata);
        return defaultBuilder;
    }

    public static MetadataImplementor getMeta() {
        return meta.get();
    }
}

Take a look on This Thread which seems to answer your needs

于 2016-01-07T21:14:15.690 に答える