Java – JPA @ ID and insertable = false, updatable = false throw exception

I'm using Oracle database. I have sequences and triggers to generate and store IDS before insertion

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;
/

Then I have a simple entity with attributes:

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

... when I try to build a project, I get:

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].

It works when I delete pluggable or updatable keywords I know many solutions how to use JPA to generate ID, and JPA can also use (call) Oracle sequence to set (generate) ID. but I try to understand why my solution is wrong Why can't I use these two keywords with the @ ID annotation? My idea is: I want to prohibit JPA from inserting or updating caseid

1) What is the right lotion? I should only use @ ID:

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

Or better (safer) definition insertable = false:

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

2) I understand that updatable = false for @ ID is meaningless (updating the primary key is meaningless, but the original SQL may be meaningful), but what does it mean (examples of benefits you have):

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

Editor: April 13, 2012

I did some tests:

entity

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

JPA log

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

So this is not safe because JPA tries to store case_ ID (then replaced by the ID in the Oracle sequence of the trigger)

entity

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

Create method

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

JPA log

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

That's good because case_ ID is not part of the insert command

Case cannot be updated because of the comment 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.

So now the last version looks the safest, right?

Solution

You are currently using JPA annotation to indicate that you have a @ ID column that cannot be inserted or updated in any way You must be able to set the ID before inserting or updating, but JPA does not know how to do this If you don't want to set the ID in the code, you need to use the @ generatedvalue annotation on the @ ID to tell JPA what strategy to use (one of table, sequence, identity, auto)

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>