#hibernate #key #parent-child #composite
#переход в спящий режим #Клавиша #родитель-потомок #составная
Вопрос:
Похожая тема уже была рассмотрена, но без проблемы наличия составного ключа в таблице. По сути, я пытаюсь получить иерархическое дерево из одной таблицы, которая имеет следующую структуру:
- Четыре столбца, представляющие составной ключ
- Столбец, содержащий родительский идентификатор
- Другие столбцы
Моя цель — сопоставить один класс с этой таблицей, используя аннотации hibernate, а затем построить из него свое иерархическое дерево:
@Entity
@Table(name = "Enti")
public class DevUnit {
/** The valuable fields from the Enti table */
// Primary Key (PK) Object
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(name = "stazione", column = @Column(name="IdStazione")),
@AttributeOverride(name = "categoria", column = @Column(name="IdCategoria")),
@AttributeOverride(name = "tipoente", column = @Column(name="IdTipoEnte")),
@AttributeOverride(name = "ente", column = @Column(name="IdEnte"))
})
private EnteDBPK EnteDBPK;
@OneToMany
@JoinColumn(name = "parentId")
private List<DevUnit> children = new ArrayList<DevUnit>();
@ManyToOne(targetEntity = DevUnit.class, optional=true, fetch=FetchType.LAZY)
@JoinColumn(name = "parenId",insertable=false,updatable=false)
private DevUnit parent = null;
// Getters and setters...
}
EnteDBPK — это мой составной ключ, определенный как:
@Embeddable
public class EnteDBPK implements Serializable {
private static final long serialVersionUID = 2960251547408481498L;
/** Fields representing the composite primary key*/
private long stazione;
private long categoria;
private long tipoente;
private long ente;
public EnteDBPK(){}
public EnteDBPK(long stazione, long categoria, long tipoente, long ente){
this.stazione = stazione;
this.categoria = categoria;
this.tipoente = tipoente;
this.ente = ente;
}
// Getters and setters, equals and hashcode overrides...
}
Ассоциации, вероятно, определены неправильно, поскольку я получаю эту ошибку при попытке ее запуска:
org.hibernate.AnnotationException: A Foreign key refering package.DevUnit from package.DevUnit has the wrong number of column. should be 4
Я уверен, что мне чего-то не хватает в обеих ассоциациях, но мне нужна ваша помощь, чтобы понять проблему и найти ее решение.
Спасибо за вашу помощь.
Антонио
Ответ №1:
Если составной ключ DevUnit
состоит из 4 столбцов, внешний ключ, который ссылается на него, также должен состоять из 4 столбцов:
@OneToMany(mappedBy = "parent")
private List<DevUnit> children = new ArrayList<DevUnit>();
@ManyToOne(optional=true, fetch=FetchType.LAZY)
@JoinColumns({
@JoinColumn(name = "parentIdStazione", referencedColumnName = "IdStazione"),
@JoinColumn(name = "parentIdCategoria", referencedColumnName = "IdCategoria"),
@JoinColumn(name = "parentIdTipoEnte", referencedColumnName = "IdTipoEnte"),
@JoinColumn(name = "parentIdEnte", referencedColumnName = "IdEnte")
})
private DevUnit parent = null;
На самом деле вы можете опустить @JoinColumns
здесь, если имена по умолчанию подходят.
Также обратите внимание, что ваш подход к отображению двунаправленной связи «один ко многим» / «многие к одному» (с «одной» стороной, являющейся стороной-владельцем) не рекомендуется документацией Hibernate, поэтому я использовал другой подход во фрагменте выше, см. 2.2.5.3.1.1. Двунаправленный.
Комментарии:
1. Спасибо за вашу помощь. Я попробовал ваш код, но получаю следующую ошибку: Вызвано: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Неизвестный столбец ‘devunit0_.parentIdCategoria’ в ‘списке полей’. Что-то не так, что я там делаю? Еще раз спасибо.
2. @Antonio: Если вы не создаете схему с помощью Гибернации, имена столбцов в аннотациях должны совпадать с именами столбцов в схеме.
3. Вы правы, вчера я был немного сбит с толку 🙂 Спасибо за вашу помощь. У меня есть еще один вопрос, если вы не возражаете: с помощью запроса в режиме гибернации типа «ИЗ DevUnit» я получаю список всех объектов в таблице Enti, у каждого из которых правильно установлены ссылки на родительский и дочерний блоки. Мой вопрос: есть ли способ автоматически создавать древовидную структуру (например, единый корень со своими дочерними элементами) с использованием hibernate? В настоящее время я делаю это вручную, потому что для целей presentatin мне нужно иметь рекурсивную структуру, но мне было интересно, может ли hibernate справиться с этим напрямую.
4. @Antonio: Нет, нет способов сделать это автоматически.
5. Спасибо за ваш ответ, мне придется придерживаться моего текущего подхода.