Ну, посмотрим
У вас есть аннотация @AssociationOverride, в которой API написано:
Эта аннотация используется для переопределения сопоставления свойства или поля «многие-к-одному» или «один-к-одному» для отношения сущности.
И
Может применяться к объекту, который расширяет сопоставленный суперкласс для переопределения сопоставления «многие к одному» или «один к одному», определенного сопоставленным суперклассом
Я не видел ни @ManyToOne, ни @OnoToOne в вашем вопросе. Итак, с вашим вопросом что-то не так.
Но я видел следующий журнал в вашей StackTrace
Внешний ключ, ссылающийся на Reporting from Reporting, имеет неправильный номер столбца. должно быть 2
У вас есть составной первичный ключ , определенный аннотацией @EmbeddedId, который имеет два свойства (fileName и xmlContent)
Теперь давайте посмотрим ваши @ CollectionOfElements
@CollectionOfElements(fetch=FetchType.EAGER)
@JoinTable(name="t_reports",
// Your mistake goes here
joinColumns=@JoinColumn(name="log_report"))
@Fetch(FetchMode.SELECT)
private List<ReportingFile> reports;
Его внешний ключ просто содержит одно свойство , тогда как ваш первичный ключ Compound содержит два свойства . Оба должны совпадать . Это объясняет, почему вы видите это красивое сообщение
Внешний ключ, ссылающийся на Reporting from Reporting, имеет неправильный номер столбца. должно быть 2
Ваше правильное отображение должно выглядеть следующим образом
@CollectionOfElements(fetch=FetchType.EAGER)
@JoinTable(name="t_reports",
joinColumns={
// The number of columns defined by our Compound primary key (2)
// must match the number of columns defined by its Foreign key (2)
@JoinColumn(name="file_name", referencedColumnName="file_name"),
@JoinColumn(name="xml_content", referencedColumnName="xml_content")})
@Fetch(FetchMode.SELECT)
private List<ReportingFile> reports;
И еще: я не знаю, поддерживает ли ваша целевая база данных Clob в качестве первичного ключа. Так что имейте это в виду.
Добавлено к оригинальному ответу согласно вашему ответу
1º Первый сценарий ( без @CollectionOfElements)
@Entity
public class Reporting {
// You said you just want a single fileName as primary key
@Id
@Column(name="file_name", nullable=false)
private String fileName;
// You said you still want to have the whole ReportingFile object
@Embedded
private ReportingFile reportingFile;
@Embeddable
public static class ReportingFile implements Serializable {
// You must set up insertable=false, updatable=false
@Column(name="file_name", insertable=false, updatable=false)
private String fileName;
@Column(name="xml_content")
private Clob xmlContent;
}
}
Имейте в виду следующее: Hibernate не позволяет определять два свойства, в которых оба столбца имеют общий столбец . Из-за этого я должен определить inserttable = false, updatable = false в свойстве fileName.
И когда я делаю следующее
Reporting reporting = new Reporting();
reporting.setFileName("home.pdf");
ReportingFile reportingFile = new ReportingFile();
// It will not persisted because of insertable=false, updatable=false
reportingFile.setFileName("home.pdf");
reportingFile.setXmlContent(someClobObject);
session.save(reporting); // It works
2º Первый сценарий ( с @CollectionOfElements)
@Entity
public class Reporting {
// You said you just want a single fileName as primary key
@Id
@Column(name="file_name", nullable=false)
private String fileName;
// You said you still want to have the whole ReportingFile object
@Embedded
private ReportingFile reportingFile;
@CollectionOfElements(fetch=FetchType.EAGER)
@JoinTable(
name="t_reports",
joinColumns=@JoinColumn(name="file_name", referencedColumnName="file_name", insertable=false, updatable=false))
private List<ReportingFile> reports;
@Embeddable
public static class ReportingFile implements Serializable {
// You must set up insertable=false, updatable=false
@Column(name="file_name", insertable=false, updatable=false)
private String fileName;
@Column(name="xml_content")
private Clob xmlContent;
}
}
И когда я делаю следующее
Reporting reporting = new Reporting();
reporting.setFileName("home.pdf");
ReportingFile reportingFile = new ReportingFile();
// It will not persisted because of insertable=false, updatable=false
reportingFile.setFileName("home.pdf");
reportingFile.setXmlContent(someClobObject);
reporting.getReports().add(reportingFile);
session.save(reporting); // It does not work
Hibernate будет жаловаться
повторный столбец в сопоставлении для коллекции: столбец отчетов: имя_файла
Итак, если у вас есть @CollectionOfElements, который использует внешний ключ, он не будет работать должным образом . Но вы можете сделать обходной путь
@Entity
public class Reporting {
// You said you just want a single fileName as primary key
@Id
@Column(name="file_name", nullable=false)
private String fileName;
// You said you still want to have the whole ReportingFile object
@Embedded
private ReportingFile reportingFile;
// Your workaround goes here
@CollectionOfElements(fetch=FetchType.EAGER)
@JoinTable(
name="t_reports",
joinColumns=@JoinColumn(name="file_name", referencedColumnName="file_name"))
private List<Clob> xmlContents;
@Transient
public List<ReportingFile> getReports() {
List<ReportingFile> reports = new ArrayList<ReportingFile>();
for(Clob xmlContent: getXmlContents())
reports.add(new ReportingFile(getFileName(), xmlContent));
return reports;
}
@Embeddable
public static class ReportingFile implements Serializable {
// required no-arg constructor
public ReportingFile() {}
public ReportingFile(String fileName, Clob xmlContent) {
this.fileName = fileName;
this.xmlContent = xmlContent;
}
// You must set up insertable=false, updatable=false
@Column(name="file_name", insertable=false, updatable=false)
private String fileName;
@Column(name="xml_content")
private Clob xmlContent;
}
}
Обратите внимание, что вы можете определить класс @Embeddable как статический при использовании внутри вашего собственного класса.