0

我创建了一个基本的 Spring MVC / JPA / Hibernate 应用程序。我正在尝试保存一个 UserProfile 实体以测试我是否可以真正持久保存它,但没有保存任何内容,也没有引发异常。

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

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

  • 没有任何内容写入服务器日志,并且日志级别为 INFO。
  • Mysql 查询日志中没有出现任何内容(我知道查询日志有效)
  • entityManager 被正确注入。
  • 数据源已正确启动,因为当我输入错误的凭据时,我得到了 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);
}

主应用程序-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>

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

持久性.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"/>

不知何故,这个设置没有向 Mysql 发送 SQL,但也没有抛出异常,所以我不知道发生了什么。希望你能帮忙:)

4

2 回答 2

2

我认为您在服务中缺少交易传播。标记 readonly=false 只是将会话设置为自动刷新。但是设置适当的事务传播将确保开始事务和提交/回滚。

删除 mode="aspectj" 后它已经开始工作,因为我认为是因为根据 spring doc

默认模式“代理”将使用 Spring 的 AOP 框架处理要代理的注释 bean(遵循代理语义,如上所述,仅适用于通过代理传入的方法调用)。替代模式“aspectj”将改为使用 Spring 的 AspectJ 事务方面编织受影响的类(修改目标类字节码以应用于任何类型的方法调用)。AspectJ 编织需要在类路径上使用 spring-aspects.jar 并 启用加载时编织(或编译时编织)。(有关如何设置加载时编织的详细信息,请参阅标题为第 6.8.4.5 节“弹簧配置”的部分。)

可能你还没有配置加载时间编织

于 2012-07-18T05:59:06.190 回答
0

好,我知道了。首先我以为我在这里找到了答案

声明式事务 (@Transactional) 在 Spring 中不适用于 @Repository

但经过更多测试后,我发现它不是

<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
于 2012-07-18T22:36:05.623 回答