I have an application that is made of 2 maven modules :
- a module containing entities and business logic
- a module with front-end and controllers
Here I am working only in the first module, containing entities. They are marked with @Entity from javax.persistance.
This is NOT a spring-boot projet, this is a spring mvc project only, it's a WAR hosted on a Tomcat. I want to add auditing with Spring Data JPA
Disclaimer : I understand very little about JPA and Hibernate.
I add the configuration in my project like this :
@Configuration
@EnableJpaRepositories(basePackages = {
"com.myproject.entities"
})
@EnableJpaAuditing(auditorAwareRef = "aware")
class JpaAuditConfig {
//helps to aware the application's current auditor.
//this is some kind of user mostly.
@Bean
public AuditorAware<String> aware() {
return () -> Optional.of("Administrator");
}
//The beans are configured here
}
I get this error :
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaAuditingHandler': Cannot resolve reference to bean 'jpaMappingContext' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: JPA metamodel must not be empty!
when I run Tomcat.
the configuration of the project is in the other maven module (the one with front-end and controllers), in a XML file, interesting parts are these :
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/the_datasource"/>
<property name="resourceRef">
<value>true</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:/hibernate/hibernate.cfg.xml"/>
<property name="packagesToScan">
<list>
<value>com.myproject.project</value>
</list>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
and in the hibernate configuration file :
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.datasource">java:comp/env/jdbc/the_datasource</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">false</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>
<property name="jadira.usertype.autoRegisterUserTypes">true</property>
</session-factory>
</hibernate-configuration>
the datasource per se in configured in the Tomcat context file as a
It all works well but I want to add auditing with Spring Data JPA and I have followed this :
https://examples.javacodegeeks.com/spring-data-jpa-auditing-example/
though I didn't use spring-boot-starters because my project is not spring boot.
Thx for your help
EDIT : I got it working by putting a "persistence.xml" file inside META-INF folder :
<persistence-unit name="SalesDB">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:comp/env/jdbc/the_datasource</jta-data-source>
<properties>
<!--<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>-->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.EJB3NamingStrategy"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
And my configuration is this one :
@Configuration
@EnableJpaRepositories(basePackages = {
"com.myproject.project.metier.domain.entities"
})
@EnableTransactionManagement
@EnableJpaAuditing(auditorAwareRef = "jpaAuditorProvider")
public class JpaConfig {
@Bean
public LocalEntityManagerFactoryBean entityManagerFactory() {
LocalEntityManagerFactoryBean factoryBean = new LocalEntityManagerFactoryBean();
factoryBean.setPersistenceUnitName("SalesDB");
return factoryBean;
}
@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
@Bean
public SessionFactory sessionFactory(EntityManagerFactory entityManagerFactory) {
/*HibernateJpaSessionFactoryBean hibernateJpaSessionFactoryBean = new HibernateJpaSessionFactoryBean();
hibernateJpaSessionFactoryBean.setEntityManagerFactory(entityManagerFactory);
return hibernateJpaSessionFactoryBean.getObject();*/
return entityManagerFactory.unwrap(SessionFactory.class);
}
@Bean
public AuditorAware<String> jpaAuditorProvider() {
return new UsernameAuditorAware();
}
}
But now I get this error :
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is java.lang.NullPointerException
at org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:544) ~[spring-orm-4.3.25.RELEASE.jar:4.3.25.RELEASE]