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

Mapping one DB column to two seperate fields using JPA

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

JPA中没有@ReadOnly。

但是,您可以通过 @Column 针对字段设置属性 "insertable"/"updatable" 以有效地执行相同的操作。

这个问题可能已经有将近 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 table 中的相关列,而 FOREIGN_COLUMN_TO_JOIN 将是您希望的另一个 table 中的单键加入。

如果您希望在单个 class 中有两个(或更多)属性,但只有一列连接到外部数据库 table,这将很有用。例如:一名员工可能有家庭 phone 号码、手机号码和工作 phone 号码。所有都映射到 class 中的不同属性,但在数据库中有一个 table 的 phone 数字和 id,以及一个标识符列,比如 VARCHAR(1) 和 'H' 或 'W' 或 'C'。那么真实的例子就是...

表:

电话号码

PHONENUMBER_ID, ACTUAL_NUMBER

员工
编号
HOMENUMBER VARCHAR(12), CELLNUMBER VARCHAR(12), 工作号 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;
}

如您所见,这需要实体的 table 上有多个列,但允许您多次引用外键而不会抛出上面显示的 'Multiple writable mappings exist...'。不是一个完美的解决方案,但对遇到同样问题的人有帮助。