java - JPA 与 Hibernate 5 : programmatically create EntityManagerFactory

标签 java hibernate jpa hibernate-entitymanager hibernate-5.x

这个问题特别是关于以编程方式创建由 Hibernate 5 支持的 JPA EntityManagerFactory,这意味着没有配置 xml 文件不使用 Spring。此外,这个问题特别是关于创建 EntityManagerFactory with a Hibernate Interceptor

我知道如何按照我想要的方式创建一个 Hibernate SessionFactory,但我不想要一个 Hibernate SessionFactory,我想要一个 JPA EntityManagerFactory 由 Hibernate SessionFactory 支持。给定一个 EntityManagerFactory 有一种方法可以获取底层的 SessionFactory,但是如果你有一个 SessionFactory 而你想要的只是一个 EntityManagerFactory 包装器,看来你运气不好。

在 Hibernate 版本 4.2.2 中,Ejb3Configuration 已被弃用,但似乎没有其他方法以编程方式创建 EntityManagerFactory,所以我正在做这样的事情:

@SuppressWarnings( "deprecation" )
EntityManagerFactory buildEntityManagerFactory(
        UnmodifiableMap<String,String> properties,
        UnmodifiableCollection<Class<?>> annotatedClasses, 
        Interceptor interceptor )
{
    Ejb3Configuration cfg = new Ejb3Configuration();
    for( Binding<String,String> binding : properties )
        cfg.setProperty( binding.key, binding.value );
    for( Class<?> annotatedClass : annotatedClasses )
        cfg.addAnnotatedClass( annotatedClass );
    cfg.setInterceptor( interceptor );
    return cfg.buildEntityManagerFactory();
}

随着 Hibernate 4.3.0 Ejb3Configuration 被移除,所以我不得不利用这个 hack:

EntityManagerFactory buildEntityManagerFactory(
        UnmodifiableMap<String,String> properties,
        UnmodifiableCollection<Class<?>> annotatedClasses,
        Interceptor interceptor )
{
    Configuration cfg = new Configuration();
    for( Binding<String,String> binding : properties )
        cfg.setProperty( binding.key, binding.value );
    for( Class<?> annotatedClass : annotatedClasses )
        cfg.addAnnotatedClass( annotatedClass );
    cfg.setInterceptor( interceptor );
    StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder();
    ssrb.applySettings( cfg.getProperties() ); //??? why again?
    ServiceRegistry serviceRegistry = ssrb.build();
    return new EntityManagerFactoryImpl( PersistenceUnitTransactionType.RESOURCE_LOCAL, /**/
            /*discardOnClose=*/true, /*sessionInterceptorClass=*/null, /**/
            cfg, serviceRegistry, null );
}

(这是一个 hack,因为我正在实例化 EntityManagerFactoryImpl,它在包 org.hibernate.jpa.internal 中。)

现在,在 Hibernate 5 中,他们更改了 EntityManagerFactoryImpl 的构造函数,因此上面的代码不起作用。我可能会浪费几个小时来弄清楚如何进行设置以便我可以调用该构造函数,但我确信在几个 Hibernate 版本之后,它也将不再有效。

所以,这是我的问题:

有谁知道实现这个功能的好方法

EntityManagerFactory buildEntityManagerFactory( 
        UnmodifiableMap<String,String> properties,
        UnmodifiableCollection<Class<?>> annotatedClasses, 
        Interceptor interceptor )

以便创建 Hibernate EntityManagerFactory 以编程方式,这意味着没有配置 xml 文件不使用 Spring使用 Hibernate 拦截器 ?

有个老问题:Hibernate create JPA EntityManagerFactory with out persistence.xml但它对旧版本的 Hibernate 有一个答案,这个问题已经预料到了。那不行,因为我希望它与 Hibernate 5 一起工作,并且理想情况下,以一种不使用任何已弃用或内部的方式工作,以便有机会在很长一段时间内工作。

最佳答案

最简单的方法是传递一个 org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor 引用,这是对“持久性单元”信息的抽象。在正常的 JPA 引导中,Hibernate 会在 persistence.xml(JPA 称之为“SE 引导”)或 javax.persistence.spi.PersistenceUnitInfo(对于JPA 称之为“EE Bootstrap ”。

但它是一种抽象是有原因的:)您可以创建自己的并传递您希望 Hibernate 使用的内容。预期的工作方式是从 org.hibernate.jpa.boot.spi.Bootstrap 开始,例如:

EntityManagerFactory emf = Bootstrap.getEntityManagerFactoryBuilder(
        new CustomPersistenceUnitDescriptor(),
        Collections.emptyMap()
).build();

...

class CustomPersistenceUnitDescriptor implements PersistenceUnitDescriptor {
    @Override
    public Properties getProperties() {
        final Properties properties = new Properties();
        properties.put( AvailableSettngs.INTERCEPTOR, new MyInterceptor( ... );
        return properties;
    }

    ...
}

关于java - JPA 与 Hibernate 5 : programmatically create EntityManagerFactory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32696237/

相关文章:

java - JPA 1.0 错误 : The name is not a recognized entity or identifier. 已知实体名称:[]

java - 获取要加载的类所需的类列表

Java 无法识别的选项 : -xvf

java - JPA/Hibernate native 查询无法识别参数

java - 我需要在 JoinColumn 中写什么?

java - 复合键 hibernate

java - Liquibase 未针对 Spring Boot/MySQL 应用程序执行

java - 在应用程序中使用多个版本的 jar 会导致问题吗?

java - 在生产者/消费者模式中使用多个生产者和消费者对java中的字符串进行排序有什么好处?

java - 尝试将数据库连接从 MySQL 更改为 Oracle 但出现错误