java - 在 Spring 中,服务层总是必须是事务性的吗?

标签 java spring spring-boot jpa transactional

我在 spring 中有一个非常简单的应用程序,包括 1 个数据库表模型类、1 个 jpa 存储库类 1 服务和 1 个 Controller 类。

我的服务类别是:

@Transactional
@Service
public class SomeService {

    private ServiceRepository serviceRepository;

    @Autowired
    public serviceService(ServiceRepository serviceRepository) {
        this.serviceRepository = serviceRepository;
    }


    public void getServiceById(Long id) {
        Model model = serviceRepository.getOne(id);
        return....
    }

}

它正在使用 @Transactional 注释。但如果我删除它,我会得到

org.hibernate.LazyInitializationException: could not initialize proxy

如果我不需要任何事务性方法或类怎么办,为什么我必须将其设为事务性?

最佳答案

发生此异常的原因是您尝试访问事务中尚未加载的对象。

当您离开事务时,您无法再从数据库加载对象。但该交易不是强制性的。

我认为您的对象具有惰性加载的 OneToMany/ManyToMany 关系。由于您的服务不是事务性的,因此与数据库的连接已关闭,您无法再访问对象。

您有 2 个选择:

  • 将“Eager fetch”设置为您的对象(您的对象始终会加载)。
  • 使您的服务具有事务性(对象将按需加载)。

激活延迟加载(默认选项)时,您应该注意性能问题。如果与使用相关,这实际上取决于您的业务逻辑,但最好尽量不要对数据库进行多次访问。

您还可以检查实体图以进行高级自定义: https://www.baeldung.com/jpa-entity-graph

此外,在开发时,启用 hibernate SQL 跟踪以查看后台发生的情况:https://www.mkyong.com/hibernate/hibernate-display-generated-sql-to-console-show_sql-format_sql-and-use_sql_comments/

关于java - 在 Spring 中,服务层总是必须是事务性的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56060206/

相关文章:

集成测试期间未由 gradle 替换的 spring boot 值

mysql - 为独立的 Spring Boot 应用程序设置 MySQL 数据库以在另一个设备中使用

java - 如何发布没有源的 JAR?

java - Firebase实时数据库使用Childeventlistener分页

java - Spring - thymeleaf : Exception processing template

java - 托管一个基于java的服务器

java - Spring 启动 : need to be informed/notified when Web-Server is Up

java - org.hibernate.hql.internal.ast.QuerySyntaxException : unexpected token

java - MP3:一种以毫秒为单位获取任何给定字节位置的位置的方法?

java - 是否可以向 JavaFX 添加媒体查询?