Hello friends,
Im working through an upgrade from Hibernate 5.5 + Spring Boot 2.7 to Hibernate 6.4 and Spring Boot 3.2. I use the Hibernate SchemaExport tool to generate my database schema, and its been very helpful when dealing with all the needed migrations between 5.5 and 6.4. I also use Hibernate Envers to create an unique audit table for each audited entity. I’ve been using this pattern across multiple services successfully for years. However I’ve run into a bit of a roadbump with the migration. For some reason, the schema that the SchemaExport tool generates for Hibernate 6 changes the primary key composition of the audit tables.
I’ve carefully read through all the relevant Hibernate migration guides but can’t find anything that explains one odd behavior I’m seeing. I can’t pinpoint if its a problem with Hibernate Envers, Hibernate SchemaExport, or some combination of the two. I’d really, really rather not do a primary key migration on every single audit table in every single database I own, so I would really appreciate some guidance here.
Consider a fairly simple Entity class named TagEntity.java
@Entity
@Table(name = "tag", uniqueConstraints = {
@UniqueConstraint(name = "UK_tag_name", columnNames = {"name"})
})
@Audited
@Getter
@Setter
@ToString
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true)
public class TagEntity {
@Id
@GeneratedValue
@UuidGenerator
private UUID id;
@Basic
@Column(name = "name", length = 132, nullable = false)
@NotBlank(message = "{tag.name.required}")
@EqualsAndHashCode.Include
private String name;
@Basic
@Column(name = "description")
private String description;
}
In Hibernate 5 and 6, the SchemaExport tool generates the same schema for the tag table
Note: While I’m trying to upgrade from 5.5 to 6.4.4.Final, in order to narrow down any possible causes I generated all below schemas using these specific versions:
Hibernate 5.6.15.Final (same behavior as 5.5) & Hibernate 6.0.2.Final (same behavior as 6.4.4.Final)
create table tag (
id CHAR(36) not null,
date_created datetime not null default CURRENT_TIMESTAMP,
last_updated datetime not null default CURRENT_TIMESTAMP,
version bigint not null,
description varchar(255),
name varchar(132) not null,
primary key (id)
) engine=InnoDB;
However, Hibernate 5 and 6 differ in how the SchemaExport tool generates the tag audit table, with the one change being the primary key
Hibernate 5
create table tag_aud (
id CHAR(36) not null,
REV bigint not null,
REVTYPE tinyint,
REVEND bigint,
REVEND_TSTMP datetime(6),
description varchar(255),
description_MOD bit,
name varchar(132),
name_MOD bit,
primary key (id, REV)
) engine=InnoDB;
Hibernate 6
create table tag_aud (
id CHAR(36) not null,
REV bigint not null,
REVTYPE tinyint,
REVEND bigint,
REVEND_TSTMP datetime(6),
description varchar(255),
description_MOD bit,
name varchar(132),
name_MOD bit,
primary key (REV, id)
) engine=InnoDB;
And its not just the tag table, this is happening with every audit table in our database.
Another example, with a more complex key
Hibernate 5
create table available_part_component_aud (
REV bigint not null,
available_part_id CHAR(36) not null,
component_id CHAR(36) not null,
REVTYPE tinyint,
REVEND bigint,
REVEND_TSTMP datetime(6),
primary key (REV, available_part_id, component_id)
) engine=InnoDB;
Hibernate 6
create table available_part_component_aud (
REV bigint not null,
available_part_id CHAR(36) not null,
component_id CHAR(36) not null,
REVTYPE tinyint,
REVEND bigint,
REVEND_TSTMP datetime(6),
primary key (available_part_id, REV, component_id)
) engine=InnoDB;
Of course theres a bit more code behind the scenes than what is presented here (for example setting UUID type to CHAR in Hibernate 6 config), I’ve tried to distill down the fundamentals for appropriate presentation on a public forum. When encountering this behavior, nothing about the codebase has changed besides upgrading our dependencies to SB3 + Hibernate 6. If anyone can recommend a way to return to the previous key generation behavior, that would be great. Thanks for reading!