好的,我们等着瞧
您有一个@AssociationOverride注释,其API指出:
此批注用于 覆盖 实体关系的属性或字段 的多对一或一对一 映射。
和
它可以应用于 扩展映射超类的实体, 以覆盖该映射超类定义的多对一或一对一映射
我没有在您的问题中没有看到@ManyToOne和@OnoToOne。因此,您的问题出了点问题。
但是我已经在您的StackTrace中看到以下日志
从报表引用报表的外键列号错误。应该是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;
它的外键仅包含 一个属性, 而您的复合主键包含 两个属性 。 两者必须匹配 。它解释了为什么您看到此好消息
从报表引用报表的外键列号错误。应该是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)
@Entitypublic 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 不允许您定义两个属性,它们都共享同一列 。因此,我必须在fileName属性中定义insertable =
false,updatable = false。
当我执行以下操作时
Reporting reporting = new Reporting();reporting.setFileName("home.pdf");ReportingFile reportingFile = new ReportingFile();// It will not persisted because of insertable=false, updatable=falsereportingFile.setFileName("home.pdf");reportingFile.setXmlContent(someClobObject);session.save(reporting); // It works2º 第一种情况( 带有 @CollectionOfElements)
@Entitypublic 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=falsereportingFile.setFileName("home.pdf");reportingFile.setXmlContent(someClobObject);reporting.getReports().add(reportingFile);session.save(reporting); // It does not workhibernate会抱怨
映射中用于收集的重复列:报告列:file_name
因此,当您有一个@CollectionOfElements共享一个外键时, 它将无法按预期工作 。但是您可以采取解决方法
@Entitypublic 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类定义为静态类。



