【问题标题】:Mapping one DB column to two seperate fields using JPA使用 JPA 将一个 DB 列映射到两个单独的字段
【发布时间】:2015-01-21 07:36:20
【问题描述】:

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

【问题讨论】:

  • 和同事讨论后发现其实是元模型出错了。

标签: java jpa eclipselink


【解决方案1】:

JPA 中没有 @ReadOnly。

但是,您可以通过@Column 对字段设置“可插入”/“可更新”属性以有效地执行相同操作。

【讨论】:

  • 我的错,@ReadOnly 来自 EclipseLink,编辑了问题以反映这一点
【解决方案2】:

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

如果您希望在一个类中拥有两个(或更多)属性,但在外部数据库表上只连接一列,这将非常有用。例如:员工可能有家庭电话号码、手机号码和工作电话号码。所有都映射到类中的不同属性,但在数据库中有一个电话号码和 id 的表,以及一个标识符列,比如带有“H”或“W”或“C”的 VARCHAR(1)。真正的例子是......

表格:

电话号码

PHONENUMBER_ID, ACTUAL_NUMBER

员工
身份证
家庭号码 VARCHAR(12), 手机号码 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;
}

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

【讨论】:

    猜你喜欢
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多