I spent days and days trying to get a working database connection for my Spring/JPA(Hibernate) integration tests, troubleshooting mysterious "No Database Context Found" errors, and I finally got it working, but I don't understand why I had to do what I did.
Note how my LocalContainerEntityManagerFacotryBean references a HibernateJpaVendorAdapter.
<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>
Why did I have to use this HibernateJpaVendorAdapter when my persistence unit is already configured for Hibernate as shown below?
<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>
It seems to work, but am I doing this right? Could I have done it another/better way?
Spring Data JPA is really a set of dependencies that makes it easier to work with a JPA provider. Hibernate is one of several JPA providers. This means you can use Spring Data JPA without using Hibernate (if you really wanted to).
It is the default JPA vendor that comes with spring-data-jpa. Although Hibernate is database agnostic, we can specify the current database dialect to let it generate better SQL queries for that database. The ddl-auto property is used to automatically create the tables based on the entity classes in the application.
What Is the Difference Between Hibernate and Spring Data JPA? Hibernate is a JPA implementation, while Spring Data JPA is a JPA Data Access Abstraction. Spring Data offers a solution to GenericDao custom implementations. It can also generate JPA queries on your behalf through method name conventions.
Exposes Hibernate's persistence provider and Hibernate's Session as extended EntityManager interface, and adapts AbstractJpaVendorAdapter 's common configuration settings. Also supports the detection of annotated packages (through SmartPersistenceUnitInfo.
I just found the answer to my question in a post on coderanch.com.
Looks like I can circumvent the use of a JpaVendorAdapter if I just specify the JPA provider inside the persistence unit definition in persistence.xml like this:
<persistence-unit name="myPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
.
.
.
First of all I am not sure why to use it but I do know that it is not mandatory to use it
From the API Docs,
Specify the JpaVendorAdapter implementation for the desired JPA provider, if any. This will initialize appropriate defaults for the given provider, such as persistence provider class and JpaDialect, unless locally overridden in this FactoryBean.
The way I understand it, is an alternative to the way we specify the hibernate configurations. I did not use it, nor did I find it on Spring API docs. It is not mandatory, let it be initialized to the default value.
There are even some issues in spring with jpaVendorAdapter
told in their JIRA.
Also there is an SO question here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With