java - Spring Data JPA 与事务

标签 java spring hibernate jpa spring-transactions

我正在使用 Spring Data JPA 和事务来开发一个应用程序。虽然我使用的 Spring 版本 (4.0.0) 可以使用 JavaConfig,但我更喜欢坚持使用 XML。

我有这个配置:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:jpa="http://www.springframework.org/schema/data/jpa"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">

<jpa:repositories base-package="repo"/>
<context:component-scan base-package="service" />
<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost/staffing?transformedBitIsBoolean=true"/>
    <property name="username" value="root"/>
    <property name="password" value="vivupdip1`"/>
</bean>

<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="showSql" value="true"/>
    <property name="generateDdl" value="true"/>
    <property name="database" value="MYSQL"/>
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
    <property name="packagesToScan" value="model"/>
    <property name="jpaPropertyMap">
        <map>
            <entry key="hibernate.hbm2ddl.auto" value="validate"/>
            <entry key="hibernate.format_sql" value="true" />
        </map>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

</beans>

我的单个(到目前为止)存储库是这样的:

package repo;

import org.springframework.data.jpa.repository.JpaRepository;
import model.Volunteer;

public interface VolunteerRepo extends JpaRepository<Volunteer, Integer> {
}

我在 service 包中还有一个 Service 接口(interface):

public interface VolunteerService {
  public List<Volunteer> findAll();
}

以及实现:

@Service
@Transactional
public class VolunteerServiceImpl implements VolunteerService {

    @Autowired VolunteerRepo repo;

    public List<Volunteer> findAll() {
      return repo.findAll();
    }

}

controller 包中的 Controller 调用:

@RestController
public class VolunteerController {

  @Autowired VolunteerService vs;

  @RequestMapping(value = "/volunteers")
  List<Volunteer> getVolunteers() {
    return vs.findAll();
  }
}

Volunteer 域对象非常复杂,并且与各种其他域对象相关。

当我在浏览器中发出正确的请求时,出现以下异常:

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: model.Volunteer.volunteerSessions, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->model.Volunteer["sessions"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: model.Volunteer.volunteerSessions, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->model.Volunteer["sessions"])
据我所知,这是在提示没有 session ,(我认为)可以通过正确配置事务来解决这个问题。但是,我配置交易的尝试似乎不正确,但我无法找出原因。

最佳答案

您的错误消息指出没有可用的 session ,其前面是:

Could not write JSON

这告诉您在尝试将对象序列化为 JSON 时访问了代理。这发生在您的 RestController 中,它确实不是事务性的,因此没有 session 绑定(bind),这就是延迟加载失败的原因。

可能的解决方案是:

  • 添加 DAO 层,并在从 VolunteerServiceImpl 返回时将数据库对象转换为简单的 java POJO
  • 您可以尝试将 Controller 注释为@Transactional
  • 如果您知道由于要在 JSON 响应中返回而始终需要该“志愿者”数据,则可能需要考虑关闭延迟加载

关于java - Spring Data JPA 与事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35463168/

相关文章:

java - quartz spring集成调度,是否可以动态设置cron触发器

java - 每次测试后重新加载 Spring 应用程序上下文

java - Hibernate 应用程序作为 Azure 中的 WebJob "Could not open connection"异常

java - 您建议如何过滤包含在巨大列表中定义的冒犯性词语的评论

java - 如果我将 CSS 文件夹放入 WEB-INF 文件夹中,我的 CSS 不会显示

Spring Boot JPA 过滤器按连接表

java - 使用 toJson() 返回 bean 的一部分

java - 使用嵌入式 Jetty 作为应用程序服务器时内存阻塞

java - Java 中的数字文字是否允许使用下划线?

java - 如何解码包含 DIFFGR 的 XML 代码