我的最后一行代码输出“role111”(从数据库获取的数据),但是在代码执行后,我在数据库中有“role11”,那么为什么我有“role11”而没有“role111”呢?在会话关闭之前,role
处于持久化状态,所以它应该与数据库中的行连接并与之一致。也许持久状态仅适用于事务内部,并且由于一级高速缓存的原因,最后一行代码打印角色111。
@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|名称
1|角色11
3条答案
按热度按时间8i9zcol21#
Hibernate在后台使用事务性写入。Hibernate会话存储更新操作,直到发生导致刷新的事件(如COMMIT),此时将执行操作,无论Hibernate认为最有意义的顺序是什么(与它们在代码中出现的顺序相反),这会导致在数据库中处理JDBC更新。
将角色名称设置为role11之后的提交会刷新更新,从而成功保存该名称。由于在角色名称更改为role111之后没有COMMIT,因此不会导致运行更新操作。
您可以通过设置刷新模式来更改提示运行更新的内容。如果不这样做,Hibernate的默认设置是在提交时刷新,除非Hibernate被用作JPA提供程序,在这种情况下,当运行查询时,它也会刷新。
bweufnob2#
数据尚未提交到数据库。您需要再次调用Commit()来编写它(我假设)。此外,有时JPA会在发出一批查询之前缓冲数据。如果是这种情况,它将保持并等待更多数据,然后才需要在突发中执行这些数据。如果您想控制这个过程,可以在最后一次调用之后调用
session.flush()
。kcrjzv8t3#
您在问题标题中假设数据是从数据库加载的,这是不正确的。数据是从Hibernate管理的当前上下文加载的,这意味着您将看到内存中的数据,这并不意味着它已经在数据库中提交或甚至更新了。