I wrote a simple entity named "User" and another one called "Company". User entity has company inside with @ManyToOne(fetch = LAZY) mapping. When I create the session object and call get() method Hibernate executes select query and after it update, why?
User entity:
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString
@Builder
@Entity
@Table(name = "users")
public class User2 {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@Column(unique = true)
private String username;
@Embedded
@EqualsAndHashCode.Exclude
private PersonalInfo personalInfo;
@Enumerated(STRING)
@EqualsAndHashCode.Exclude
private Role role;
@Type(JsonType.class)
@EqualsAndHashCode.Exclude
private String info;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "company_id")
@EqualsAndHashCode.Exclude
@ToString.Exclude
private Company company;
}
Company entity:
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString
@Builder
@Entity
public class Company {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
private String name;
}
Main:
public class HibernateEntityMappingRunner {
public static void main(String[] args) {
try (SessionFactory sessionFactory = buildSessionFactory();
Session session = sessionFactory.openSession()
) {
session.beginTransaction();
User2 user2 = session.get(User2.class, 2);
session.getTransaction().commit();
}
}
}
Hibernate console log:
Hibernate:
select
u1_0.id,
u1_0.company_id,
u1_0.info,
u1_0.birth_date,
u1_0.firstname,
u1_0.lastname,
u1_0.role,
u1_0.username
from
users u1_0
where
u1_0.id=?
Hibernate:
update
users
set
company_id=?,
info=?,
birth_date=?,
firstname=?,
lastname=?,
role=?,
username=?
where
id=?
CodePudding user response:
It happens when I use dubug. I think somehow debug mode does some magic evaluating entities, therefore, it triggers hibernate processes and forces it to execute some sql. If somebody knows how this can be fixed so debug will act just like usual run mode, answer me please.
CodePudding user response:
See https://hibernate.org/community/contribute/intellij-idea/#debugging for details. The problem is that some of your toString()
implementations (which the IntelliJ debugger invokes) access state of uninitialized entity/collection proxies, which will cause lazy initialization and hence a select query. If you have pending flushes (insert/update/delete) which affect one of the tables that are about to be selected from, Hibernate forcefully executes pending flushes.
By changing your toString()
implementations or changing how IntelliJ shows objects in the debugger, you can avoid this.