gpt4 book ai didi

java - JPA @Id and insertable = false, updatable = false 抛出异常

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:28:28 25 4
gpt4 key购买 nike

我正在使用 Oracle 数据库,我有序列和触发器用于在插入之前生成和存储 ID。

CREATE SEQUENCE CASE_SEQ START WITH 1001 INCREMENT BY 1 NOMAXVALUE; 

CREATE OR REPLACE TRIGGER CASE_TR_SEQ
BEFORE INSERT ON CASE FOR EACH ROW
BEGIN
SELECT CASE_SEQ.NEXTVAL INTO :NEW.CASE_ID FROM DUAL;
END;
/

然后我有一个具有属性的简单实体:

@Id
@Column(name = "CASE_ID", insertable = false, updatable = false)
private Long caseId;

...当我尝试构建项目时,我得到:

Exception [EclipseLink-46] (Eclipse Persistence Services - 2.3.2.v20111125-r10461):
org.eclipse.persistence.exceptions.DescriptorException
Exception Description: There should be one non-read-only mapping defined for the
primary key field [CASE.CASE_ID].

当我删除 insertable 或 updatable 关键字时,它就可以工作了。我知道有很多解决方案如何使用 JPA 生成 ID,JPA 也可以使用(调用)oracle 序列来设置(生成的)ID。但我试着理解为什么我的解决方案是错误的。为什么我不能将这两个关键字与@Id 注释一起使用?我的想法是:我想禁止通过JPA插入或更新caseId。

1) 什么是正确的解决方案?我应该只使用@Id:

@Id
@Column(name = "CASE_ID")
private Long caseId;

或者更好(更安全)也定义 insertable=false:

@Id
@Column(name = "CASE_ID", insertable = false)
private Long caseId;

2) 我知道 @Id 的 updatable=false 没有意义(更新主键没有意义,但可以通过原始 sql 实现),但它是什么意思(你有一些有用的例子吗):

@Id
@Column(name = "CASE_ID", updatable = false)
private Long caseId;

编辑 2012-04-13

我做了一些测试:

实体

@Id
@Column(name = "CASE_ID")
private Long caseId;

JPA 日志

INSERT INTO CASE (CASE_ID, CASE_DATE, INFO) VALUES (?, ?, ?)
bind => [3 parameters bound]|#]

所以这是不安全的,因为 JPA 会尝试存储 CASE_ID(然后通过触发器将其替换为来自 Oracle 序列的 ID)。

实体

@Id
@Column(name = "CASE_ID", insertable = false)
private Long caseId;

创建方法

public void createCase(final Case caseData) {
caseData.setCaseId(-1001L);
em.persist(caseData);
}

JPA 日志

INSERT INTO CASE (CASE_DATE, INFO) VALUES (?, ?)
bind => [2 parameters bound]|#]

很好,因为 CASE_ID 不是插入命令的一部分。

并且无法更新 CASE_ID,因为注释 ID:

public void update() {
Case update = em.find(Case.class, 1023L);
update.setCaseId(1028L);
}

Exception [EclipseLink-7251] (Eclipse Persistence Services - 2.3.2.v20111125-r10461):
org.eclipse.persistence.exceptions.ValidationException
Exception Description: The attribute [caseId] of class
[com.wordpress.kamiluv.jsfprototype.model.entity.Case] is mapped to a primary
key column in the database. Updates are not allowed.

所以现在最后一个版本看起来是最安全的,对吧?

最佳答案

您当前使用 JPA 注释表示您有一个无法以任何方式插入或更新的 @Id 列。您必须能够在插入或更新之前设置 id,但 JPA 不知道该怎么做。如果您不想在代码中设置 id,则需要在 @Id 上使用 @GeneratedValue 注释来告诉 JPA 使用什么策略(其中之一:TABLE、SEQUENCE、IDENTITY、AUTO)。

关于java - JPA @Id and insertable = false, updatable = false 抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10128092/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com