java – JPA @Id和insertable = false,updatable = false抛出异常

我正在使用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].

当我删除可插入或可更新的关键字时,它可以工作.我知道有很多解决方案如何使用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,?)
bind => [2 parameters bound]|#]

这很好,因为CASE_ID不是insert命令的一部分.

由于注释ID,因此无法更新CASE_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之一).

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


应用场景 C端用户提交工单、工单创建完成之后、会发布一条工单创建完成的消息事件(异步消息)、MQ消费者收到消息之后、会通知各处理器处理该消息、各处理器处理完后都会发布一条将该工单写入搜索引擎的消息、最终该工单出现在搜索引擎、被工单处理人检索和处理。 事故异常体现 1、异常体现 从工单的流转记录发现、
线程类,设置有一个公共资源 package cn.org.chris.concurrent; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @Descrip
Java中的数字(带有0前缀和字符串)
在Java 9中使用JLink的目的是什么?
Java Stream API Filter(过滤器)
在Java中找到正数和负数数组元素的数量
Java 9中JShell中的不同启动脚本是什么?
使用Java的位填充错误检测技术
java中string是什么
如何使用Java中的JSON-lib API将Map转换为JSON对象?
Java菜单驱动程序以检查数字类型
使用Junit的Maven项目 - 检查银行账号
JAVA编程基础
在Java中使用throw、catch和instanceof来处理异常
在Java中,将数组分割为基于给定查询的子数组后,找到子数组的最大子数组和
如何在Java中从给定的字符串中删除HTML标签?
在PHP中,IntlChar getBlockCode()函数的翻译如下:
如何在Android中实现按下返回键再次退出的功能?
如何使用Java中的流式API解析JSON字符串?
Java中的模式类