У меня есть устаревшая база данных с составным первичным ключом в таблице project. (BaseEntity содержит общие свойства для lastModifiedDate и lastModifiedBy)
@Entity
@IdClass(ProjectPk.class)
public class Project extends BaseEntity {
@Id
@GeneratedValue(strategy=GenerationType.TABLE, generator = "nextProjectId")
@TableGenerator(
name = "nextProjectId",
table = "projectId",
pkColumnName = "proj_Id",
pkColumnValue = "proj_id"
)
private Long projId;
@Id
private int version;
//other properties, getters and setters omitted for clarity
}
класс ПК
public class ProjectPk implements java.io.Serializable {
private int projId;
private int version;
//both constructoirs, equals, hashcode, getters and setters omitted for clarity
}
drop table if exists project;
CREATE TABLE project
(
proj_id bigint,
version int,
-- other columns omitted for clarity
PRIMARY KEY (`proj_id`, `version`)
) ENGINE=InnoDB;
drop table if exists project_id;
CREATE TABLE project_id
(
proj_id bigint
) ENGINE=InnoDB;
Table: project_id
Columns:
proj_id bigint
...
Table: project
Columns:
proj_id bigint PK
version int PK
...
во время сборки maven я получаю ошибку проверки
Schema-validation: wrong column type encountered in column [proj_id] in table [project_id]; found [bigint (Types#BIGINT)], but expecting [varchar(255) (Types#VARCHAR)]Что я сделал не так, чтобы ожидался спящий режим [varchar(255) (Types#VARCHAR)]?
Это проект SpringBoot 2.6.6 с базой данных MySql.




Я вижу следующие проблемы с вашим кодом:
Project.projId (длинный тип) и ProjectPk.projId (тип int).project_id.Вы можете увидеть рабочий пример ниже.
Предположим, что у вас есть следующие таблицы:
CREATE TABLE test_project
(
proj_id bigint,
version int,
title VARCHAR(50),
PRIMARY KEY (proj_id, version)
);
create table table_identifier (
table_name varchar(255) not null,
product_id bigint,
primary key (table_name)
);
insert into table_identifier values ('test_project', 20);
и следующее отображение:
@Entity
@Table(name = "test_project")
@IdClass(ProjectPk.class)
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "nextProjectId")
@TableGenerator(
name = "nextProjectId",
table = "table_identifier",
pkColumnName = "table_name",
valueColumnName = "product_id",
allocationSize = 5
)
@Column(name = "proj_id")
private Long projId;
@Id
private int version;
// other fields, getters, setters ...
}
вы сможете сохранить объект, как показано ниже:
Project project = new Project();
project.setVersion(1);
// ...
entityManager.persist(project);
Я понял! Я неправильно истолковал значение pkColumnName = "proj_Id". Позвольте мне попробовать поиграть с ним.
См. эту часть документации по спящему режиму. По умолчанию таблица использования гибернации hibernate_sequences
Я думаю, что невозможно иметь table_identifier без столбца table_name, потому что спящий режим использует эту таблицу для хранения текущего значения последовательности для каждой таблицы, использующей стратегию GenerationType.TABLE.
Спасибо, мне действительно нужно убедить администратора базы данных изменить таблицу последовательностей, созданную 20 лет назад ))).
Благодарю за ваш ответ. Возможно ли иметь table_identifier без столбца «table_name varchar (255) not null»? К сожалению, в устаревшей таблице базы данных нет этого столбца. Возможно, проблема в том, что Hibernate ожидает этот столбец по дизайну (т.е. предполагается наличие нескольких строк для каждой таблицы), но в устаревшей базе данных нет столбца идентификатора таблицы. Я предполагаю, что тот, кто проектировал макет БД, имел в виду что-то вроде «сгенерированной последовательности БД».