如何理解@Transactional with setter in Java?

How to understand @Transactional with setters in Java?

在 Java Spring 的教程之后,我试图了解 @Transactional 如何与 setter 一起工作,以及其他 question/sources,我可以'找不到初学者友好的解释。

假设我有一个带有 getter 和 setters:

的用户实体
@Entity
@Table
public class User {
    // Id set up
    private Long id;
    private String name;
    private String email;
    private String password;

    // Other constructors, setters and getters

    public void setName(String name) {
        this.name = name;
    }
}

在 UserService 中我有一个 getUserName 方法:

@Service
public class UserService {
    private final UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional
    public void getUserName(Long id) {
        User user = userRepository.findById(id).orElse(null);

        user.setName("new user name"); // Why will this update db?     
    }
}

注解@Transactional后,setter函数确实更新了db,这是spring更新数据的方式吗?有人可以用通俗易懂的术语解释一下,事务性如何在幕后与 setter 一起工作吗?

编辑: 没有 @Transactional,setter 函数不会更新数据库,但在 为了改变数据库,必须调用 userRepository.save(user)。从 the video 开始,讲师简单地说事务将为我们处理 jpql,并使用 setters 和它一起更新数据库。

资源更新:

找到一篇非常好的文章来深入挖掘:应用程序设计与 Hibernate(https://khuevu.github.io/application-design-with-hibernate.html),希望这对您有所帮助。

Spring 在后台使用 Hibernate 作为 ORM。 当您调用 userRepository.findById 时,会在后台调用 Hibernate 实体管理器,它会从数据库中检索实体,同时生成此 entity manageable(您可以单独阅读有关 Hibernate 管理的实体)。 什么意思,简单来说,Hibernate在其内部结构中'remembers'引用了这个实体,在so-calledsession中。实际上,它 'remembers' 在单个事务期间(在最基本的情况下)从数据库中检索的所有实体(甚至是通过查询获得的实体列表)。

当你创建一些方法 @Transactional 时,默认情况下 Hibernate sessionflushed 当这样的方法完成时。 session.flush() 在后台调用。

一旦 session gets flushed,Hibernate 就会将对这些 managed entities 所做的所有更改推送回数据库。

这就是为什么您的更改会在方法完成后进入数据库,而无需任何其他调用。

要深入了解该主题,您可以阅读有关 Hibernate managed entitiessession flush moderepository.save(), repository.saveAndFlush() in Spring Data.

的更多信息

首先,负责更新实体的是底层 JPA 提供程序(假设它是 Hibernate),而不是 Spring。 Spring 仅提供与 Hibernate 的集成支持。

要更新从数据库加载的实体,通常需要确保按顺序执行以下操作。

  1. 开始数据库事务

  2. 使用 EntityManager 加载你想要的实体 update.The 加载的实体据说由这个 EntityManager 管理,这样它将跟踪所有对其状态所做的更改并将生成必要的更新 SQL 以自动更新 (4) 中的该实体。

  3. 对实体的状态进行一些更改。您可以通过任何方式来实现它,例如调用它的任何方法,而不仅仅是限制通过 setter

    调用它
  4. 刷新 EntityManager。然后它将生成更新 SQL 并发送到数据库。

  5. 提交数据库事务

另请注意以下事项:

  • Spring 提供了 @Transactional,这是一种声明式的方式来执行 (1) 和 (5),方法是将其注解到方法中。
  • 默认情况下,Hibernate 会在执行 (5) 之前自动调用 (4),这样您就不需要显式调用 (4)。
  • Spring 数据 JPA 存储库在内部使用 EntityManager 加载用户。因此存储库中的用户 return 将由这个 EntityManager 管理。

所以简而言之,@Transactional 是更新实体所必需的。并且更新实体与 setter 无关,因为它只关心实体最后是否有状态更改,您可以在不使用 setter.

的情况下完成