Spring容器配置中的JPA提供者与方言与供应商

Posted

技术标签:

【中文标题】Spring容器配置中的JPA提供者与方言与供应商【英文标题】:JPA provider vs. dialect vs. vendor in the Spring contaniner configuration 【发布时间】:2013-09-10 01:41:21 【问题描述】:

spring配置文件示例:

<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory"ref="entityManagerFactory"/>
    <property name="jpaDialect"ref="jpaDialect"/>
</bean>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
....
</bean>

和persistence.xml jpa 文件:

<persistence-unit name="EmployeeService">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
</persistence-unit>

如您所见,jpa 提供者相关信息设置了 3 次。在事务管理器 bean、实体管理器工厂 bean 和持久化单元配置中:

<property name="jpaDialect"ref="jpaDialect"/>
...
<property name="jpaVendorAdapter">
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
...
<provider>org.hibernate.ejb.HibernatePersistence</provider>

但实际上在我的项目中,我只配置了带有提供程序的持久性单元。它奏效了。

所以我的问题是提供者、方言和供应商选项之间有什么区别? 我必须设置所有这些,还是可以跳过其中一些? 例如,我可以设置为 EntityMangerFactory - Hibernate 的供应商、事务管理器 - Eclipse 中的方言以及持久性单元配置中的提供者 - 其他东西,例如 TopLink。

我不清楚。请解释一下。

【问题讨论】:

【参考方案1】:

会尝试逐行向你解释:

<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>

//Should ideally be 
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
此 bean 定义了您将要使用的 jpaDialect。 JpaDialect 是一个接口,它封装了标准 JPA 1.0 不提供的某些功能,例如对底层 JDBC 连接的访问​​。此策略主要用于 JPA 提供程序的独立使用;当使用 JTA 事务运行时,它的大部分功能都无关紧要。 还允许为 Spring 提供的可移植但功能更强大的 EntityManager 和 EntityManagerFactory 子接口提供增值方法。 由于您将类提供为class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/&gt;,这允许Spring 将特定于供应商的行为插入到Spring 的EntityManagerFactory 创建者中,并且它充当所有供应商特定属性的单一配置点。这是一个自定义实现春天自己的JpaVendorAdapter

对于您声明的第二个 bean:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory"ref="entityManagerFactory"/>
    <property name="jpaDialect"ref="jpaDialect"/>
</bean>
您告诉“Spring”配置一个transactionManager,其属性为entityManagerFactoryjpaDialect。由于这些属性必须特定于hibernate,因此这些属性是根据设置的。 entityManagerFactoryjpaDialect 现在专门设置为 hibernate(或供应商)。

至于第三颗豆

<property name="jpaDialect"ref="jpaDialect"/>
...
<property name="jpaVendorAdapter">
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
...
<provider>org.hibernate.ejb.HibernatePersistence</provider>

&lt;provider&gt; 告诉 spring 使用 hibernate 提供程序,而 org.hibernate.ejb.HibernatePersistence 类是 Hibernate EJB3 持久性提供程序实现。

简而言之,你需要配置这些,以便告诉 spring 应该使用哪个 ORM 的功能。

您的应用程序使用仅配置持久性和提供程序的原因是因为供应商适配器通过JpaVendorAdapter 中的getPersistenceProvider 自动传递提供的持久性,即HibernatePersistence

修改文档以了解这些类是如何相互关联的。

编辑:正如@TheKojuEffect 所指出的,理想情况下,第一个bean 应该采用以下形式:

<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>

谢谢。错过了vendorAdapter

你可以参考:

HibernateJpaDialect HibernateVendorAdapter HibernatePersistence

希望对您有所帮助。 :)

【讨论】:

很好的解释,但我认为您的回答有误。在第一个 bean jpaDialect 中,我认为您的意思是 jpaVendorAdapter。如果你纠正你的答案会更好。 感谢您的回复。我查看了 HibernateJpaVendorAdapter 并找到了 getJpaDialect() 和 getPersistenceProvider() 方法。我认为仅使用 HibernateJpaVendorAdapter 配置实体管理器工厂是正确的。并且可以从适配器类接收 jpa dialect 和 jpa provider 就足够了。

以上是关于Spring容器配置中的JPA提供者与方言与供应商的主要内容,如果未能解决你的问题,请参考以下文章

sqlite数据库方言配置

将 Spring Data JPA 与 GCP Spanner 集成

Spring Boot / JPA / Hibernate,如何根据 Spring 配置文件切换数据库供应商?

将 Spring Security 与 JPA 结合使用

Jpa Join 查询与来自两个表的数据,org.hibernate.MappingException:没有 JDBC 类型的方言映射:2002

springboot与springmvc的区别是啥?