Spring JPA不存储实体

时间:2012-07-17 19:27:25

标签: mysql spring jpa annotations persistence

我创建了一个基本的Spring MVC / JPA / Hibernate应用程序。我试图保存一个UserProfile实体来测试我是否可以实际持久化它,但没有任何东西得到保存,也没有抛出异常。

在控制器方法中,我创建了一个简单的UserProfile(它是一个@Entity),我将它发送给服务方法。 UserProfileServiceImpl类使用@Service注释,addUserProfile(UserProfile profile)方法使用@Transactional注释。

在服务方法中,我所做的只是调用DAO方法(使用@Repository注释的类)。在DAO方法中,我所做的只是调用entityManager.persist(object),object是用户配置文件对象。

  • 没有任何内容写入服务器日志,日志级别为INFO。
  • Mysql查询日志中没有任何内容(我知道查询日志有效)
  • 实体管理器被正确注入。
  • 数据源已正确启动,因为当我输入有缺陷的凭据时,我会收到SQLExceptions。

我希望你能告诉我什么是错的。我将在下面发布一些代码和配置文件。

服务方法:

// 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 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);
}

主要application-context.xml

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

application-context-web.xml文件

<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>

弹簧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"/>

不知何故没有SQL通过此设置发送到Mysql,但也没有抛出任何异常,因此我不知道发生了什么。希望你能帮忙:)。

2 个答案:

答案 0 :(得分:2)

我认为您缺少服务中的事务传播。标记readonly = false只是将会话设置为自动刷新。但是设置正确的事务传播将确保启动trnasaction和commit / rollback。

删除mode =“aspectj”后,它已经开始工作,因为我认为因为按照春季文档

  

默认模式“proxy”将处理要注释的带注释的bean   使用Spring的AOP框架(遵循代理语义,如上所述)   上面,仅适用于通过代理进入的方法调用)。该   替代模式“aspectj”将编织受影响的类   使用Spring的AspectJ事务方面​​(修改目标类)   字节码,以便应用于任何类型的方法调用)。 AspectJ的   编织需要类路径上的spring-aspects.jar以及   加载时编织(或编译时编织)已启用。 (见章节   题为“如何配置”的第6.8.4.5节“弹簧配置”   设置加载时编织。)

可能您尚未配置load time weaving

答案 1 :(得分:0)

好的,我明白了。首先,我以为我找到了答案

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

但经过一些测试后,我发现它不是

的位置

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

但其内容。

删除mode="aspectj"属性后,它开始工作了!如果有人想评论为什么会这样,请做。

让我与您分享我的完整设置。这适用于带有Hibernate 4的Spring 3.1。注意:对于'简洁',我只发布了配置文件的内容,并省略了外部标记<beans><persistence>以及命名空间声明。我完全删除了spring-jpa.xml,并将其内容移动到application-context.xml。

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> 

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"/>

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>

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"/>

environment.properties的内容:

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