Jpa 应该为主键字段定义一个非只读映射

Jpa 应该为主键字段定义一个非只读映射,jpa,mapping,eclipselink,Jpa,Mapping,Eclipselink,嗨,我有以下代码(使用eclipselink 2.6): 传输: @Entity public class Transmission { @Column(name="TRANSMISSION_ID") @Id private Long id; @Column(name="TRANSMISSION_CONTENT") private String content; .... } @Embeddable public class HeaderP

嗨,我有以下代码(使用eclipselink 2.6):

传输:

@Entity    
public class Transmission {     

    @Column(name="TRANSMISSION_ID")
    @Id private Long id;

    @Column(name="TRANSMISSION_CONTENT")
    private String content;
....
}
@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;
    ...
}
@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;        
    ....
}
@Entity
public class VoucherHeader extends Header {
    // a bunch of additional fields
    ....
    ....    
}
@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;
    ....
    ....
}
@Entity
public class VoucherRecordTypeA extends Record<VoucherHeader> {
    // a bunch of additional column-mapped fields
    ...
}
HeaderPk:

@Entity    
public class Transmission {     

    @Column(name="TRANSMISSION_ID")
    @Id private Long id;

    @Column(name="TRANSMISSION_CONTENT")
    private String content;
....
}
@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;
    ...
}
@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;        
    ....
}
@Entity
public class VoucherHeader extends Header {
    // a bunch of additional fields
    ....
    ....    
}
@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;
    ....
    ....
}
@Entity
public class VoucherRecordTypeA extends Record<VoucherHeader> {
    // a bunch of additional column-mapped fields
    ...
}
标题:

@Entity    
public class Transmission {     

    @Column(name="TRANSMISSION_ID")
    @Id private Long id;

    @Column(name="TRANSMISSION_CONTENT")
    private String content;
....
}
@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;
    ...
}
@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;        
    ....
}
@Entity
public class VoucherHeader extends Header {
    // a bunch of additional fields
    ....
    ....    
}
@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;
    ....
    ....
}
@Entity
public class VoucherRecordTypeA extends Record<VoucherHeader> {
    // a bunch of additional column-mapped fields
    ...
}
VoucherHeader:

@Entity    
public class Transmission {     

    @Column(name="TRANSMISSION_ID")
    @Id private Long id;

    @Column(name="TRANSMISSION_CONTENT")
    private String content;
....
}
@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;
    ...
}
@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;        
    ....
}
@Entity
public class VoucherHeader extends Header {
    // a bunch of additional fields
    ....
    ....    
}
@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;
    ....
    ....
}
@Entity
public class VoucherRecordTypeA extends Record<VoucherHeader> {
    // a bunch of additional column-mapped fields
    ...
}
RecordPk:

@Entity    
public class Transmission {     

    @Column(name="TRANSMISSION_ID")
    @Id private Long id;

    @Column(name="TRANSMISSION_CONTENT")
    private String content;
....
}
@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;
    ...
}
@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;        
    ....
}
@Entity
public class VoucherHeader extends Header {
    // a bunch of additional fields
    ....
    ....    
}
@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;
    ....
    ....
}
@Entity
public class VoucherRecordTypeA extends Record<VoucherHeader> {
    // a bunch of additional column-mapped fields
    ...
}
记录:

@Entity    
public class Transmission {     

    @Column(name="TRANSMISSION_ID")
    @Id private Long id;

    @Column(name="TRANSMISSION_CONTENT")
    private String content;
....
}
@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;
    ...
}
@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;        
    ....
}
@Entity
public class VoucherHeader extends Header {
    // a bunch of additional fields
    ....
    ....    
}
@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;
    ....
    ....
}
@Entity
public class VoucherRecordTypeA extends Record<VoucherHeader> {
    // a bunch of additional column-mapped fields
    ...
}
但理想的解决方案是让VoucherRecordTypeA扩展记录,因为还有其他几个类类似于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.邮箱\u ID]定义非只读映射…表VoucherRecordTypeA的列FK_MAILBOX_ID不是MAILBOX_ID…MAILBOX_ID是VoucherHeader表中引用的列。

如果列的名称和@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;
....
....
}
但是,这是不可接受的,因为实际列名与引用的列名不同。正如我在最初的帖子中所说的,如果我在@JoinColumn注释中将RecordPk和关系映射移动到VoucherRecordTypeA中,并使用正确的列名,这就不是问题。我继续尝试这个解决方案,它没有给我错误

@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,并添加了各个字段。代码的其余部分与原始帖子中的代码相同。EclipseLink不再抱怨了

这是我的分析:这个问题只发生在用@MappedSuperclass注释的类上。只要列名和引用的列名相同,在@MappedSuperclass中使用带有嵌套id的派生EmbeddedId以及关系上的@JoinColumn就可以工作。如果它们不一样,它就会破裂。但是,如果在用@Entity注释的类上使用相同的设置,则不会发生这种情况。遵循文章中的代码可能会更好地理解

我的分析正确吗?这是虫子吗


编辑:我忘了提到……在记录中,您需要删除@MapsId(“headerPk”),因为headerPk不再嵌入到RecordPk中。

很难判断出哪里出了问题。您可以尝试删除映射中的泛型,看看这是否会使issue@Chris我删除了泛型,但同样的错误。见我编辑的帖子。