为什么我需要在Spring应用程序上下文中定义Hibernate-JPA供应商适配器?

CFL*_*eff 14 spring hibernate database-connection

我花了几天时间试图为我的Spring/JPA(Hibernate)集成测试找到一个有效的数据库连接,排除神秘的"没有发现数据库上下文"错误,我终于让它工作了,但我不明白我为什么要这样做做我做的.

请注意我的LocalContainerEntityManagerFacotryBean如何引用HibernateJpaVendorAdapter.

applicationContext.xml中

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="myEMF">
    <property name="persistenceXmlLocation" value="file:src/test/resources/META-INF/persistence.xml" />
    <property name="persistenceUnitName" value="myPU" />
    <property name="jpaVendorAdapter" ref="hibernateJpaAdapter" />
</bean>

<bean id="hibernateJpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="showSql" value="true" />
</bean>
Run Code Online (Sandbox Code Playgroud)

为什么我用这个HibernateJpaVendorAdapter时,我的持久性单元已经配置了对Hibernate,如下图所示?

persistence.xml中

<persistence-unit name="myPU" transaction-type="RESOURCE_LOCAL">
    <class>com.blah.blah.Class1</class>
    <class>com.blah.blah.Class2</class>
    <class>com.blah.blah.Class3</class> 
    <properties>
        <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
        <property name="hibernate.connection.url" value="jdbc:mysql://127.0.0.1?zeroDateTimeBehavior=convertToNull"/>
        <property name="hibernate.connection.username" value="uname"/>
        <property name="hibernate.connection.password" value="pwd"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />

        <property name="hibernate.hbm2ddl.auto" value="update" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.ejb.event.post-insert"
        value="org.hibernate.ejb.event.EJB3PostInsertEventListener,org.hibernate.envers.event.AuditEventListener" />
        <property name="hibernate.ejb.event.post-update"
        value="org.hibernate.ejb.event.EJB3PostUpdateEventListener,org.hibernate.envers.event.AuditEventListener" />
        <property name="hibernate.ejb.event.post-delete"
        value="org.hibernate.ejb.event.EJB3PostDeleteEventListener,org.hibernate.envers.event.AuditEventListener" />
        <property name="hibernate.ejb.event.pre-collection-update"
        value="org.hibernate.envers.event.AuditEventListener" />
        <property name="hibernate.ejb.event.pre-collection-remove"
        value="org.hibernate.envers.event.AuditEventListener" />
        <property name="hibernate.ejb.event.post-collection-recreate"
        value="org.hibernate.envers.event.AuditEventListener" />
        </properties>
</persistence-unit>
Run Code Online (Sandbox Code Playgroud)

它似乎有效,但我这样做对吗?我可以用另一种/更好的方式做到吗?

CFL*_*eff 17

我刚刚在coderanch.com上的帖子中找到了我的问题的答案.

看起来我可以绕过JpaVendorAdapter的使用,如果我只是在persistence.xml中的持久性单元定义中指定JPA提供程序,如下所示:

<persistence-unit name="myPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
            .
            .
            .
Run Code Online (Sandbox Code Playgroud)


Man*_*uPK 5

首先,我不知道为什么要使用它,但我知道它不是必须使用它

来自API Docs,

为所需的JPA提供程序指定JpaVendorAdapter实现(如果有).这将初始化给定提供程序的适当默认值,例如持久性提供程序类和JpaDialect,除非在此FactoryBean中进行了本地重写.

我理解它的方式是我们指定hibernate配置的方式的替代方案.我没有使用它,也没有在Spring API文档中找到它.它不是强制性的,让它初始化为默认.

jpaVendorAdapter在他们的JIRA中,在春天甚至有一些问题.另外还有一个问题SO 这里.