处于持久状态的对象没有保存到数据库,但已成功从中加载

object in persistent state don't saved to the database, but successfully loaded from it

我的最后一行代码输出“role111”(从数据库中获取数据),但是执行代码后我在数据库中有“role11”,那么为什么我有“role11”而不是“role111”?在会话关闭之前 role 处于持久状态,因此它应该与数据库中的行连接并与之保持一致。也许持久状态仅适用于事务内部,最后一行代码由于一级缓存而打印 role111。

@Entity
@Table(name = "roles")
public class Role
{
    @Id
    @Column(name = "id")
    private int id;
    
    @Column(name = "name")
    private String name;
    
    public Role()
    {
    }
    
    public int getId()
    {
        return id;
    }
    
    public void setId(int id)
    {
        this.id = id;
    }
    
    public String getName()
    {
        return name;
    }
    
    public void setName(String name)
    {
        this.name = name;
    }
}
Role role = new Role();
role.setId(1);
role.setName("role1");
        
SessionFactory sessionFactory = new Configuration().configure().addAnnotatedClass(Role.class).buildSessionFactory();
try (Session session = sessionFactory.openSession())
{
    session.beginTransaction();
    session.save(role);
    role.setName("role11");
    System.out.println(session.get(Role.class, 1).getName()); // prints role11
    session.getTransaction().commit();
    role.setName("role111");
    System.out.println(session.get(Role.class, 1).getName()); // prints role111
}

这是我的数据库

id name
1 role11

数据还没有提交到数据库。您需要再次调用 commit() 来编写它(我假设)。 此外,有时 JPA 会在发出一批查询之前缓冲数据。如果是这种情况,它会等待更多数据,然后再有必要以突发方式执行它们。如果要控制进程,可以在最后一次调用后调用session.flush()

你在问题标题中假设数据是从数据库加载的是不正确的。数据是从 Hibernate 管理的当前上下文中加载的,这意味着您将看到内存中的数据,这并不意味着它已经在数据库中提交或更新。

Hibernate 使用事务后写。 hibernate 会话存储更新操作直到提交发生,此时操作将以 Hibernate 认为最有意义的任何顺序执行(与它们在您的代码中出现的顺序相反),这会导致 jdbc 更新以在数据库中处理。

将角色名称设置为 role11 之后的提交会刷新更新,因此名称已成功保存。由于在角色名称更改为 role111 之后没有提交,因此不会导致更新操作 运行.

您可以通过设置刷新模式将提示更新的内容更改为 运行。如果不这样做,Hibernate 的默认设置是在提交时刷新,除非 Hibernate 被用作 JPA 提供程序,在这种情况下,它也会在查询为 运行.

时刷新