应该为主键字段定义一个 non-read-only 映射
There should be one non-read-only mapping defined for the primary key field
您好,我有以下代码(使用 eclipselink 2.6):
传输:
@Entity
public class Transmission {
@Column(name="TRANSMISSION_ID")
@Id private Long id;
@Column(name="TRANSMISSION_CONTENT")
private String content;
....
}
HeaderPk:
@Embeddable
public class HeaderPk {
// this is a foreign key to "TRANSMISSION_ID" in Transmission
@Column(name="FK_TRANSMISSION_ID")
private Long transmissionId;
@Column(name="MAILBOX_ID")
private String mailboxId;
@Column(name="TRANSMISSION_TIME")
private Time transmissionTime;
...
}
Header:
@MappedSuperclass
public abstract class Header {
@EmbeddedId
private HeaderPk id = new HeaderPk();
@MapsId("transmissionId")
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="FK_TRANSMISSION_ID", referencedColumnName="TRANSMISSION_ID")
private Transmission transmission;
....
}
代金券Header:
@Entity
public class VoucherHeader extends Header {
// a bunch of additional fields
....
....
}
记录Pk:
@Embeddable
public class RecordPk {
@Column(name="RECORD_NUMBER")
private Integer recordNumber;
@Embedded
private HeaderPk headerPk;
...
...
}
记录:
@MappedSuperclass
public abstract class Record<T> {
@EmbeddedId
private RecordPk id;
@MapsId("headerPk")
@ManyToOne
@JoinColumns({
@JoinColumn(name="FK_TRANSMISSION_ID", referencedColumnName="FK_TRANSMISSION_ID"),
@JoinColumn(name="FK_MAILBOX_ID", referencedColumnName="MAILBOX_ID"),
@JoinColumn(name="FK_TRANSMISSION_TIME", referencedColumnName="TRANSMISSION_TIME")
})
private T header;
....
....
}
VoucherRecordTypeA:
@Entity
public class VoucherRecordTypeA extends Record<VoucherHeader> {
// a bunch of additional column-mapped fields
...
}
尝试 运行 程序时出现以下错误:
应该为主键字段 [VoucherRecordTypeA.MAILBOX_ID] 定义一个 non-read-only 映射...我知道它抱怨有超过 writable 映射字段但我无法弄清楚如何解决这个问题。
如果我将 VoucherRecordTypeA 修改为这个,错误就会消失...
@Entity
public class VoucherRecordTypeA {
@EmbeddedId
private RecordPk id;
@MapsId("headerPk")
@ManyToOne
@JoinColumns({
@JoinColumn(name="FK_TRANSMISSION_ID", referencedColumnName="FK_TRANSMISSION_ID"),
@JoinColumn(name="FK_MAILBOX_ID", referencedColumnName="MAILBOX_ID"),
@JoinColumn(name="FK_TRANSMISSION_TIME", referencedColumnName="TRANSMISSION_TIME")
})
private VoucherHeader header;
// a bunch of additional column-mapped fields
...
}
但理想的解决方案是让 VoucherRecordTypeA 扩展 Record<...>,因为还有其他几个 类 类似于 VoucherRecordTypeA。如有任何帮助,我们将不胜感激。
编辑
尝试了以下
@MappedSuperclass
public abstract class Record {
@EmbeddedId
private RecordPk id;
@MapsId("headerPk")
@ManyToOne
@JoinColumns({
@JoinColumn(name="FK_TRANSMISSION_ID", referencedColumnName="FK_TRANSMISSION_ID"),
@JoinColumn(name="FK_MAILBOX_ID", referencedColumnName="MAILBOX_ID"),
@JoinColumn(name="FK_TRANSMISSION_TIME", referencedColumnName="TRANSMISSION_TIME")
})
private VoucherHeader header;
....
....
}
同样的错误。我注意到它在抱怨应该为 [VoucherRecordTypeA.MAILBOX_ID] 定义 non-read-only 映射...table VoucherRecordTypeA 具有列 FK_MAILBOX_ID 不是 MAILBOX_ID...MAILBOX_ID 是凭证中引用的列Header table.
如果列名和@JoinColumn 中引用的列相同,EclipseLink 似乎不会报错。所以这没有错误:
@MappedSuperclass
public abstract class Record {
@EmbeddedId
private RecordPk id;
@MapsId("headerPk")
@ManyToOne
@JoinColumns({
@JoinColumn(name="FK_TRANSMISSION_ID", referencedColumnName="FK_TRANSMISSION_ID"),
@JoinColumn(name="MAILBOX_ID", referencedColumnName="MAILBOX_ID"),
@JoinColumn(name="TRANSMISSION_TIME", referencedColumnName="TRANSMISSION_TIME")
})
private VoucherHeader header;
....
....
}
但是这是不可接受的,因为实际的列名与引用的列名不同。就像我在原来的 post 中所说的那样,如果我将 RecordPk 和关系映射移动到 VoucherRecordTypeA 中并在 @JoinColumn 注释中使用正确的列名,这不是问题。我继续尝试这个解决方案,它没有给我任何错误。
@Embeddable
public class RecordPk {
@Column(name="RECORD_NUMBER")
private Integer recordNumber;
@Column(name="FK_TRANSMISSION_ID", insertable=false, updatable=false)
private Long transmissionId;
@Column(name="FK_MAILBOX_ID", insertable=false, updatable=false)
private String mailboxId;
@Column(name="FK_TRANSMISSION_TIME", insertable=false, updatable=false)
private Time transmissionTime;
...
...
}
所以基本上我从 RecordPk 中删除了嵌入的 HeaderPk 并添加了各个字段。其余代码与原始代码相同 post。 EclipseLink 不再抱怨了。
这是我的分析:这个问题只发生在用 @MappedSuperclass 注释的 class 上。只要列名和引用的列名相同,在 @MappedSuperclass 中使用带有嵌套 ID 的派生 EmbeddedId 以及关系上的 @JoinColumn 将起作用。如果它们不相同,它就会中断。但是,当您在使用 @Entity 注释的 class 上进行相同设置时,不会发生这种情况。遵循 post 中的代码可能会更好地理解。
我的分析正确吗?这是一个错误吗?
编辑: 我忘了提...在记录中你需要删除 @MapsId("headerPk")因为 headerPk 不再嵌入到 RecordPk 中。
您好,我有以下代码(使用 eclipselink 2.6):
传输:
@Entity
public class Transmission {
@Column(name="TRANSMISSION_ID")
@Id private Long id;
@Column(name="TRANSMISSION_CONTENT")
private String content;
....
}
HeaderPk:
@Embeddable
public class HeaderPk {
// this is a foreign key to "TRANSMISSION_ID" in Transmission
@Column(name="FK_TRANSMISSION_ID")
private Long transmissionId;
@Column(name="MAILBOX_ID")
private String mailboxId;
@Column(name="TRANSMISSION_TIME")
private Time transmissionTime;
...
}
Header:
@MappedSuperclass
public abstract class Header {
@EmbeddedId
private HeaderPk id = new HeaderPk();
@MapsId("transmissionId")
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="FK_TRANSMISSION_ID", referencedColumnName="TRANSMISSION_ID")
private Transmission transmission;
....
}
代金券Header:
@Entity
public class VoucherHeader extends Header {
// a bunch of additional fields
....
....
}
记录Pk:
@Embeddable
public class RecordPk {
@Column(name="RECORD_NUMBER")
private Integer recordNumber;
@Embedded
private HeaderPk headerPk;
...
...
}
记录:
@MappedSuperclass
public abstract class Record<T> {
@EmbeddedId
private RecordPk id;
@MapsId("headerPk")
@ManyToOne
@JoinColumns({
@JoinColumn(name="FK_TRANSMISSION_ID", referencedColumnName="FK_TRANSMISSION_ID"),
@JoinColumn(name="FK_MAILBOX_ID", referencedColumnName="MAILBOX_ID"),
@JoinColumn(name="FK_TRANSMISSION_TIME", referencedColumnName="TRANSMISSION_TIME")
})
private T header;
....
....
}
VoucherRecordTypeA:
@Entity
public class VoucherRecordTypeA extends Record<VoucherHeader> {
// a bunch of additional column-mapped fields
...
}
尝试 运行 程序时出现以下错误: 应该为主键字段 [VoucherRecordTypeA.MAILBOX_ID] 定义一个 non-read-only 映射...我知道它抱怨有超过 writable 映射字段但我无法弄清楚如何解决这个问题。
如果我将 VoucherRecordTypeA 修改为这个,错误就会消失...
@Entity
public class VoucherRecordTypeA {
@EmbeddedId
private RecordPk id;
@MapsId("headerPk")
@ManyToOne
@JoinColumns({
@JoinColumn(name="FK_TRANSMISSION_ID", referencedColumnName="FK_TRANSMISSION_ID"),
@JoinColumn(name="FK_MAILBOX_ID", referencedColumnName="MAILBOX_ID"),
@JoinColumn(name="FK_TRANSMISSION_TIME", referencedColumnName="TRANSMISSION_TIME")
})
private VoucherHeader header;
// a bunch of additional column-mapped fields
...
}
但理想的解决方案是让 VoucherRecordTypeA 扩展 Record<...>,因为还有其他几个 类 类似于 VoucherRecordTypeA。如有任何帮助,我们将不胜感激。
编辑 尝试了以下
@MappedSuperclass
public abstract class Record {
@EmbeddedId
private RecordPk id;
@MapsId("headerPk")
@ManyToOne
@JoinColumns({
@JoinColumn(name="FK_TRANSMISSION_ID", referencedColumnName="FK_TRANSMISSION_ID"),
@JoinColumn(name="FK_MAILBOX_ID", referencedColumnName="MAILBOX_ID"),
@JoinColumn(name="FK_TRANSMISSION_TIME", referencedColumnName="TRANSMISSION_TIME")
})
private VoucherHeader header;
....
....
}
同样的错误。我注意到它在抱怨应该为 [VoucherRecordTypeA.MAILBOX_ID] 定义 non-read-only 映射...table VoucherRecordTypeA 具有列 FK_MAILBOX_ID 不是 MAILBOX_ID...MAILBOX_ID 是凭证中引用的列Header table.
如果列名和@JoinColumn 中引用的列相同,EclipseLink 似乎不会报错。所以这没有错误:
@MappedSuperclass
public abstract class Record {
@EmbeddedId
private RecordPk id;
@MapsId("headerPk")
@ManyToOne
@JoinColumns({
@JoinColumn(name="FK_TRANSMISSION_ID", referencedColumnName="FK_TRANSMISSION_ID"),
@JoinColumn(name="MAILBOX_ID", referencedColumnName="MAILBOX_ID"),
@JoinColumn(name="TRANSMISSION_TIME", referencedColumnName="TRANSMISSION_TIME")
})
private VoucherHeader header;
....
....
}
但是这是不可接受的,因为实际的列名与引用的列名不同。就像我在原来的 post 中所说的那样,如果我将 RecordPk 和关系映射移动到 VoucherRecordTypeA 中并在 @JoinColumn 注释中使用正确的列名,这不是问题。我继续尝试这个解决方案,它没有给我任何错误。
@Embeddable
public class RecordPk {
@Column(name="RECORD_NUMBER")
private Integer recordNumber;
@Column(name="FK_TRANSMISSION_ID", insertable=false, updatable=false)
private Long transmissionId;
@Column(name="FK_MAILBOX_ID", insertable=false, updatable=false)
private String mailboxId;
@Column(name="FK_TRANSMISSION_TIME", insertable=false, updatable=false)
private Time transmissionTime;
...
...
}
所以基本上我从 RecordPk 中删除了嵌入的 HeaderPk 并添加了各个字段。其余代码与原始代码相同 post。 EclipseLink 不再抱怨了。
这是我的分析:这个问题只发生在用 @MappedSuperclass 注释的 class 上。只要列名和引用的列名相同,在 @MappedSuperclass 中使用带有嵌套 ID 的派生 EmbeddedId 以及关系上的 @JoinColumn 将起作用。如果它们不相同,它就会中断。但是,当您在使用 @Entity 注释的 class 上进行相同设置时,不会发生这种情况。遵循 post 中的代码可能会更好地理解。
我的分析正确吗?这是一个错误吗?
编辑: 我忘了提...在记录中你需要删除 @MapsId("headerPk")因为 headerPk 不再嵌入到 RecordPk 中。