I seem to have stumbled on a weird issue when migrating a project from hibernate 5 to 6.
The same code on both produces different queries and consequently different results. Hibernate 6 produces an extra “delete” query that deletes the record right after insertion, while hibernate 5 does not.
Hibernate 5 produced queries:
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into "user" (name, surname, id) values (?, ?, ?)
Hibernate: select count(*) as col_0_0_ from "user" user0_
// User count: 1
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into device (name, id) values (?, ?)
Hibernate: select count(*) as col_0_0_ from device device0_
// Device count: 1
Hibernate: select user0_.id as id1_2_, user0_.name as name2_2_, user0_.surname as surname3_2_ from "user" user0_ where user0_.name=?
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into provisioning_info (device_id, user_id, id) values (?, ?, ?)
Hibernate: select count(*) as col_0_0_ from provisioning_info provisioni0_
// ProvisioningInfo count: 1
Hibernate 6 produced queries:
Hibernate: select user_seq.nextval from dual
Hibernate: insert into "user" (name, surname, id) values (?, ?, ?)
Hibernate: select count(*) from "user" u1_0
// User count: 1
Hibernate: select device_seq.nextval from dual
Hibernate: insert into device (name, id) values (?, ?)
Hibernate: select count(*) from device d1_0
// Device count: 1
Hibernate: select u1_0.id,u1_0.name,u1_0.surname from "user" u1_0 where u1_0.name=?
Hibernate: select provisioning_info_seq.nextval from dual
Hibernate: insert into provisioning_info (device_id, user_id, id) values (?, ?, ?)
Hibernate: delete from provisioning_info where user_id=?
Hibernate: select count(*) from provisioning_info p1_0
// ProvisioningInfo count: 0
Now, why does hibernate 6 produce an extra query delete from provisioning_info where user_id=?
?
Are we using hibernate incorrectly? What can I do to make it work on hibernate 6?
Models:
@Entity
@Table(name = "\"user\"")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String surname;
@OneToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "provisioning_info",
joinColumns = @JoinColumn(name = "user_id", nullable = false, updatable = false),
inverseJoinColumns = @JoinColumn(name = "device_id", nullable = false, updatable = false)
)
private Set<Device> devices;
// Omitted getters and setters
}
@Entity
@Table(name = "device")
public class Device {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
// Omitted getters and setters
}
@Entity
@Table(name = "provisioning_info")
public class ProvisioningInfo {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@ManyToOne
@JoinColumn(name = "device_id")
private Device device;
// Omitted getters and setters
}
Repositories:
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByName(String name);
}
public interface DeviceRepository extends JpaRepository<Device, Long> {
Optional<Device> findByName(String name);
}
public interface ProvisioningInfoRepository extends JpaRepository<ProvisioningInfo, Long> {
}
Test code:
@Transactional
public void test() {
User user = new User();
user.setName("name");
user.setSurname("surname");
userRepository.save(user);
System.out.println("User count: " + userRepository.count());
Device device = new Device();
device.setName("device");
deviceRepository.save(device);
System.out.println("Device count: " + deviceRepository.count());
user = userRepository.findByName(user.getName()).orElseThrow();
device = deviceRepository.findById(device.getId()).orElseThrow();
ProvisioningInfo pi = new ProvisioningInfo();
pi.setUser(user);
pi.setDevice(device);
provisioningInfoRepository.save(pi);
System.out.println("ProvisioningInfo count: " + provisioningInfoRepository.count());
}
Database creation sql (Oracle):
create sequence hibernate_sequence start with 1 increment by 1;
create table device (id number(19,0) not null, name varchar2(255), primary key (id));
create table provisioning_info (id number(19,0) not null, device_id number(19,0) not null, user_id number(19,0) not null, primary key (user_id, device_id));
create table "user" (id number(19,0) not null, name varchar2(255), surname varchar2(255), primary key (id));
alter table provisioning_info add constraint FKaa9goxi73eawrckas10a5u3r8 foreign key (device_id) references device;
alter table provisioning_info add constraint FKht6iwjjedykqjupratrdgpf6d foreign key (user_id) references "user";
Thank you in advance.