1

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]
Genku
  • 31
  • 8
  • Why do you have the JPA/Hibernate related classes in a different module than the JPA/Hibernate related configuration? – Jens Schauder Nov 26 '21 at 07:12
  • @JensSchauder In the other module I just have the XML config and no JPA or Hibernate classes per se. As I understand it is to link to JPA config in the business module to the Datasource of JEE in the tomcat/front module. – Genku Nov 26 '21 at 08:23
  • Have you solved this yet ? – overheated Mar 18 '23 at 11:53

0 Answers0