Hibernate Unidirectional OneToMany не работает с составным идентификатором
Я два дня стучал головой о клавиатуре, пытаясь понять это...
Немного предыстории: у нас есть модель данных, настроенная на базе кода Perl, которая запускает прямые нативные операторы SQL в базу данных через ODBC. По определенным причинам мы решили переписать код на Java... Я подумал, что было бы неплохо использовать Hibernate для определения всех отображений. Мы не хотим редактировать модель данных.
Для простоты я могу выразить проблему только с частью нашей модели данных. У нас есть сущности "Job","JobDatabase" и "JobTable".
У Job есть PK из job_name. База данных имеет PK имя_объекта, имя. Таблица имеет PK имя_обработки, имя_базы_данных src, имя. Как и следовало ожидать, Job имеет отношение OneToMany с JobDatabase, а Database имеет OneToMany с JobTable.
Для целей этого теста я начинаю с пустых таблиц и пытаюсь создать пример данных. Я могу вставить Job и JobDatabase, но когда я пытаюсь вставить JobTable, Hibernate выдает ошибку. Или, точнее, именно на это он жалуется. Он не начинает выполнять мой код, потому что обнаруживает ошибку сопоставления. Однако, если я удалю связь между JobDatabase и JobTable, он вставит все записи Job и JobDatabase правильно, без ошибок.
Примеры классов (все поля имеют геттеры / сеттеры... есть также много других полей):
@Entity
@Table(name="Job")
public class Job implements Serializable {
@Id
@Column(name="job_name",nullable = false)
private String jobName;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "job_name", referencedColumnName = "job_name")
private Set<JobDatabase> databases;
}
@Entity
@Table(name="JobDatabase")
public class JobDatabase implements Serializable {
@Id
@Column(name="job_name",nullable = false)
private String jobName;
@Id
@Column(name="name",nullable = false)
private String name;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumns({
@JoinColumn(name = "job_name", referencedColumnName = "job_name"),
@JoinColumn(name = "name", referencedColumnName = "src_database_name")
})
private Set<JobTable> tables;
}
@Entity
@Table(name="JobTable")
public class JobTable implements Serializable{
@Id
@Column(name="job_name",nullable = false)
private String jobName;
@Id
@Column(name="src_database_name",nullable = false)
private String srcDatabaseName;
@Id
@Column(name="name",nullable = false)
private String name;
}
Ошибка:
Exception in thread "main" org.hibernate.MappingException: Unable to find column with logical name: src_database_name in JobDatabase
Я продолжаю получать эту ошибку. Я не понимаю, почему он ищет указанный столбец в сущности, "владеющей" отображением. src_database_name действительно существует только в JobTable - его называют "name" в JobDatabase. JobTable также имеет поле "имя", но оно относится к имени таблицы.
1 ответ
Вам нужно иметь столбец src_database_name в вашей таблице JobDatabase. Или вы можете изменить src_database_name на другое имя столбца.
Для составного ключа ссылка на столбец должна присутствовать в исходной таблице.