16

我在我的应用程序中使用 JPA。在其中一张表中,我没有使用主键(我知道这是一个糟糕的设计)。

现在生成的实体如下所述:

@Entity
@Table(name="INTI_SCHEME_TOKEN")
public class IntiSchemeToken implements Serializable {
    private static final long serialVersionUID = 1L;

    @Column(name="CREATED_BY")
    private String createdBy;

    @Temporal( TemporalType.DATE)
    @Column(name="CREATED_ON")
    private Date createdOn;

    @Column(name="SCH_ID")
    private BigDecimal schId;

    @Column(name="TOKEN_ID")
    private BigDecimal tokenId;

    public IntiSchemeToken() {
    }

    public String getCreatedBy() {
        return this.createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    public Date getCreatedOn() {
        return this.createdOn;
    }

    public void setCreatedOn(Date createdOn) {
        this.createdOn = createdOn;
    }

    public BigDecimal getSchId() {
        return this.schId;
    }

    public void setSchId(BigDecimal schId) {
        this.schId = schId;
    }

    public BigDecimal getTokenId() {
        return this.tokenId;
    }

    public void setTokenId(BigDecimal tokenId) {
        this.tokenId = tokenId;
    }



} 

这里在我的项目中,eclipse IDE在这个类上显示错误标记(红色十字),错误是“实体没有定义主键属性”。

谁能告诉我,如何创建没有主键的实体?

谢谢。

4

8 回答 8

21

你不能。一个实体必须有一个唯一的、不可变的 ID。它不必定义为数据库中的主键,但字段或字段集必须唯一标识行,并且其值可能不会改变。

因此,如果您的实体中的一个字段或您的实体中的一组字段满足这些条件,请将其(或它们)设为实体的 ID。例如,如果用户无法在同一天创建两个实例,则可以将 [createdOn, createdBy] 设为实体的 ID。

当然,这是一个糟糕的解决方案,您应该真正更改架构并在实体中添加一个自动生成的单列 ID。

于 2012-11-02T07:44:04.273 回答
8

如果您的主键(PK)是在实体类中继承的托管超类,那么您必须在 persistence.xml 文件中包含映射的超类名称。

查看错误报告: https ://bugs.eclipse.org/bugs/show_bug.cgi?id=361042

于 2015-05-03T09:08:22.327 回答
6

如果你需要定义一个没有主键的类,那么你应该将该类标记为一个 Embeddable 类。否则,您应该为您定义的所有实体提供主键。

于 2012-11-03T03:28:50.177 回答
4

您可以关闭(更改)已添加的验证。

转到工作区首选项“Java Persistence->JPA->Errors/Warnings”下一个“类型”并将“实体没有主键”更改为“警告”。

于 2015-05-05T06:54:05.303 回答
1

除了http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#No_Primary_KeyROWID之外,您还可以使用Oracle中的一些内置列:

但要小心:

实体框架不适用于所有类型的数据(例如用于分析而不是用于查询的统计数据)。

于 2013-12-06T14:08:13.923 回答
0

没有 Hibernate 的另一种解决方案

如果 - 您的表上没有 PK - 存在可能是 PK 的列的逻辑组合(如果您可以使用某种 rowid,则没有必要) - 但有些列是 NULLable 所以你真的不能由于数据库限制而创建 PK - 并且您无法修改表结构(会破坏旧代码中没有明确列出的列的插入/选择语句)

那么您可以尝试以下技巧 - 在数据库中使用具有连接逻辑键列('A='||a||'B='||'C='c..)或 rowid 值的虚拟列创建视图 -通过此视图创建您的 JPA 实体类 - 使用 @Id 注释标记虚拟列

就是这样。更新/删除数据操作也是可能的(不是插入),但如果虚拟键列不是由 rowid 组成的,我不会使用它们(以避免数据库表的全扫描搜索)

PS 在链接的问题中部分描述了相同的想法。

于 2014-10-24T12:24:33.820 回答
0

您需要创建主键,如果没有找到任何符合条件的字段,则创建自动增量 ID。

CREATE TABLE fin_home_loan (
  ID int NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (ID));
于 2015-12-02T19:32:54.797 回答
0

只需添加假 id 字段。在 Postgres 中:

@Id
@Column(name="ctid")
String id;

在甲骨文中:

@Id
@Column(name="ROWID")
String rowid;
于 2021-10-18T12:37:25.597 回答