我有一个无法更改的旧架构。我正在使用基类来实现常见功能,它包含一个嵌入式对象。有一个字段通常映射在嵌入对象中,该字段只需要在一个(很多)子类的持久性ID中。我创建了一个包含它的新id类,但后来我得到了该字段映射两次的错误。下面是一些简化的示例代码,以保持读者的理智:
@MappedSuperclass
class BaseClass {
@Embedded
private Data data;
}
@Entity
class SubClass extends BaseClass {
@EmbeddedId
private SubClassId id;
}
@Embeddable
class Data {
private int location;
private String name;
}
@Embeddable
class SubClassId {
private int thingy;
private int location;
}
我试过@AttributeOverride,但我只能重命名该字段。我试图将它设置为updatable = false,insertable = false但在@AttributeOverride注释中使用时似乎不起作用。请参阅下面的答案以解决此问题。
我意识到我可以更改基类但我真的不想拆分嵌入对象来分离共享字段,因为它会使周围的代码更复杂并且需要一些丑陋的包装代码。我也可以为这个角落案例重新设计整个系统,但我真的不愿意。
我正在使用Hibernate作为我的JPA提供程序。
答案 0 :(得分:5)
我发现原因是AttributeOverride不起作用。注释类时,必须在名称字段中包含嵌入对象的标识符。我这样做了:
@Entity
@AttributeOverride(name = "location", column = @Column(name = "location", insertable = false, updatable = false)
class SubClass extends BaseClass {
当需要这样时:
@Entity
@AttributeOverride(name = "data.location", column = @Column(name = "location", insertable = false, updatable = false)
class SubClass extends BaseClass {
奇怪的是,更改@ Column的名称字段确实适用于第一个版本,但是可插入和可更新字段被忽略。我不知道这是否是JPA规范中的错误或微妙。
无论如何,这确实解决了如何使字段只读,但它没有回答原始问题:是否可以从映射的超类瞬态中创建一个字段?