Spring JPA doesn't store entity

I created a basic Spring MVC / JPA / Hibernate app. I am trying to save a UserProfile entity to test if I can actualy persist it, but nothing gets saved and no exception is thrown either.

In the controller method I create a simple UserProfile (which is an @Entity) and I am sending that to a service method. The UserProfileServiceImpl class is annotated with @Service and the addUserProfile(UserProfile profile) method is annotated with @Transactional.

In the service method, all I do is call a DAO method (class annotated with @Repository). In the DAO method all I do is call entityManager.persist(object), with object being the user profile object.

  • Nothing gets written to the server log and the log level is at INFO.
  • Nothing appears in the Mysql query log (and I know the query log works)
  • The entityManager gets properly injected.
  • The datasource is properly initiated, because when I enter faulty credentials I get SQLExceptions.

I hope you can tell me what's wrong. I'll post some of my code and config files below.

The service method:

// The service method gets called from the controller. 
// Its class is annotated with @Service

@Transactional(readOnly = false)
public void addUserProfile(UserProfile userProfile) {
    userProfileDao.save(userProfile);
}

The Dao method:

// The save(T object) method is in the GenericDaoJpa class, which is the superclass
// of the UserProfileDaoJPA class that is referenced from the service.
// I have established that the entityManager is there and the object is a
// UserProfile. The @Repository annotation is on the child class UserProfileDaoJpa.

public void save(T object) {
    entityManager.persist(object);
}

Main application-context.xml

<context:property-placeholder location="classpath*:**/*.properties"/>
<import resource="spring-jpa.xml"/>

The application-context-web.xml file

<mvc:annotation-driven />
<context:component-scan base-package="nl.codebasesoftware.produx" />

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"/>
    <property name="suffix" value=".jsp"/>
</bean>

spring-jpa.xml

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${db.driverClassName}"
      p:url="${db.url}" p:username="${db.username}" p:password="${db.password}"/>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
      p:dataSource-ref="dataSource"/>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
      p:entityManagerFactory-ref="entityManagerFactory"/>

<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>

<bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"/>

persistence.xml

<persistence-unit name="mysqlPersistenceUnit" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
        <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
    </properties>
</persistence-unit>

<!-- Needed to properly process @PersistenceContext -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

Somehow no SQL is sent to Mysql with this setup, but no exception is thrown either, so I have no idea what's going on. Hope you can help :)

Answers


i think you are missing transaction propagation at service. marking readonly=false just set session to auto flush. but setting up proper transaction propogation will make sure start of trnasaction and commit/rollback.

after removing mode="aspectj" it has started working because i think because of as per spring doc

The default mode "proxy" will process annotated beans to be proxied using Spring's AOP framework (following proxy semantics, as discussed above, applying to method calls coming in through the proxy only). The alternative mode "aspectj" will instead weave the affected classes with Spring's AspectJ transaction aspect (modifying the target class byte code in order to apply to any kind of method call). AspectJ weaving requires spring-aspects.jar on the classpath as well as load-time weaving (or compile-time weaving) enabled. (See the section entitled Section 6.8.4.5, “Spring configuration” for details on how to set up load-time weaving.)

and probably you have not configured load time weaving


Ok, I got it. First I thought I found the answer here

Declarative transactions (@Transactional) doesn't work with @Repository in Spring

But after some more testing I found it was not the location of

<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>

but its contents.

After removing the mode="aspectj" attribute it started working! If anyone would like to comment why that is, please do.

Let me share my full setup with you. This is for Spring 3.1 with Hibernate 4. NOTE: for 'brevity' I only posted the contents of the configuration files, and omitted the outer tags <beans> and <persistence> and the namespace declarations. I removed spring-jpa.xml altogether and moved its contents into application-context.xml.

Contents of web.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

<display-name>My Spring MVC web application</display-name>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:**/application-context.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>produxDispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:**/application-context-web.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>produxDispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
</web-app> 

Contents of application-context.xml:

<!-- main setup -->
<context:property-placeholder location="classpath*:**/*.properties"/>
<context:annotation-config/>
<context:component-scan base-package="nl.codebasesoftware.produx.domain" />
<context:component-scan base-package="nl.codebasesoftware.produx.service" />
<context:component-scan base-package="nl.codebasesoftware.produx.dao" />
<!-- Data and JPA setup -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${db.driverClassName}"
      p:url="${db.url}" p:username="${db.username}" p:password="${db.password}"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory"/>
<tx:annotation-driven  transaction-manager="transactionManager"/>
<bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"/>

Contents of application-context-web.xml:

<mvc:annotation-driven />

<context:component-scan base-package="nl.codebasesoftware.produx.controller" />

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"/>
    <property name="suffix" value=".jsp"/>
</bean>

Contents of webapps/META-INF/persistence.xml

<persistence-unit name="mysqlPersistenceUnit" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
        <!-- <property name="hibernate.hbm2ddl.auto" value="create-drop"/>  -->
    </properties>
</persistence-unit>

<!-- Needed to properly process @PersistenceContext which injects the entity manager -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

Contents of environment.properties:

db.url=jdbc:mysql://localhost:3306/yourDatabaseName
db.driverClassName=com.mysql.jdbc.Driver
db.username=yourUsername
db.password=yourPassword

Need Your Help

Is there an opensource java library to interface to an image scanner?

java image image-processing image-scanner

I would like to make a tool to capture images from an scanner, is there an opensource java library to control / interface with a scanner? (I found JTwain but is about EUR 3000)