Issue
My last line of code outputs "role111" (data fetched from database), but after code gets executed I have "role11" in database, so why I have "role11" but not "role111"? Before session get closed role
are in the persistent state so it should be connected with row in database and be consistent with it. Maybe a persistent state applicable only inside transaction and last line of code prints role111 due to first level cache.
@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
}
Here is my database
id | name |
---|---|
1 | role11 |
Solution
Hibernate uses transactional write behind. The hibernate session stores update actions until a commit occurs, at which time the actions get executed, in whatever order Hibernate thinks makes the most sense (as opposed to the order in which they occur in your code), which causes the jdbc updates to process in the database.
The commit following setting the role name to role11 causes the updates to be flushed so the name is saved successfully. Since you don't have a commit following the point where the role name changes to role111, nothing causes the update actions to be run.
You can change what prompts the updates to run by setting the flush mode. If you don't, the default for Hibernate is to flush on commit, unless Hibernate is being used as a JPA provider, in which case it also flushes when a query is run.
Answered By - Nathan Hughes