使用JPA将一个DB列映射到两个单独的字段

时间:2015-01-21 07:36:20

标签: java jpa eclipselink

我正在开发一个必须从数据库元模型文件生成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注释,但它没有帮助解决这个问题。

2 个答案:

答案 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;
}

如您所见,这将需要在实体表上包含多个列,但允许您多次引用外键,而不会抛出上面显示的“存在多个可写映射...”。这不是一个完美的解决方案,但对遇到相同问题的人很有帮助。