我正在开发一个必须从数据库元模型文件生成JPA实体的代码生成器。这些模型来自家庭酿造的建模系统,用于生成JPA实体以外的模型。
在这些模型中,某些字段将映射回同一数据库列。但似乎JPA不太喜欢这样。当我尝试运行生成的代码时,我得到了
Exception [EclipseLink-48] (Eclipse Persistence Services - 2.6.0.v20140809-296a69f): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [FACT_INVENT_TRANS_HIST_DM.TRANSACTION_ID]. Only one may be defined as writable, all others must be specified read-only.
Mapping: org.eclipse.persistence.mappings.DirectToFieldMapping[TransactionIdKey-->FACT_INVENT_TRANS_HIST_DM.TRANSACTION_ID]
Descriptor: RelationalDescriptor(InventTransHistFactDM --> [DatabaseTable(FACT_INVENT_TRANS_HIST_DM)])
由于我无法更改模型,因此左边的选项是将其中一个字段设为只读。并且生成的JPA实体仅用于从数据库读取数据,它不会用于写入数据。有没有办法将某些字段标记为只读或告诉EclipseLink这些实体是只读的,因此它不必担心多重可写映射。
我尝试在所有实体中使用EclipseLink的@ReadOnly注释,但它没有帮助解决这个问题。
答案 0 :(得分:2)
JPA中没有@ReadOnly。
但是有属性"可插入" /"可更新"您可以通过@Column对字段进行设置,以便有效地执行相同操作。
答案 1 :(得分:1)
这个问题可能已经有6年了,但是今天仍然存在,所以我想谈谈另一个选择:
public class Foobar {
@OneToOne
@JoinColumn(name="SELF_COLUMN_FOO", referencedColumnName = "FOREIGN_COLUMN_TO_JOIN")
public Foo foo;
@OneToOne
@JoinColumn(name="SELF_COLUMN_BAR", referencedColumnName = "FOREIGN_COLUMN_TO_JOIN")
public Bar bar;
}
这可以用于SELF_COLUMN显然是Foobar表中的相关列,而FOREIGN_COLUMN_TO_JOIN将是您希望加入的另一个表中的单键的情况。
这在您希望在单个类中具有两个(或多个)属性,但仅要在外部DB表上联接的一列的情况下很有用。例如:员工可能有家庭电话号码,手机号码和工作电话号码。所有这些都映射到该类中的不同属性,但是在数据库上只有一个电话号码和ID表,以及一个标识符列,例如带有'H'或'W'或'C'的VARCHAR(1)。真正的例子就是……
表格:
电话号码
PHONENUMBER_ID, ACTUAL_NUMBER
员工
ID
HOMENUMBER VARCHAR(12),
CELLNUMBER VARCHAR(12),
WORKNUMBER VARCHAR(12)
public class Employee {
@OneToOne
@JoinColumn(name="HOMENUMBER", referencedColumnName = "PHONENUMBER_ID")
public Phone homeNum;
@OneToOne
@JoinColumn(name="CELLNUMBER", referencedColumnName = "PHONENUMBER_ID")
public Phone cellNum;
@OneToOne
@JoinColumn(name="WORKNUMBER", referencedColumnName = "PHONENUMBER_ID")
public Phone workNum;
}
如您所见,这将需要在实体表上包含多个列,但允许您多次引用外键,而不会抛出上面显示的“存在多个可写映射...”。这不是一个完美的解决方案,但对遇到相同问题的人很有帮助。