Estoy usando la base de datos Oracle y tengo secuencia y desencadenador para generar y almacenar ID antes de insertar.JPA @Id y insertable = false, updatable = false throws excepción
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;
/
entonces he simple entidad con la propiedad:
@Id
@Column(name = "CASE_ID", insertable = false, updatable = false)
private Long caseId;
... cuando intento construir proyecto que estoy consiguiendo:
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].
Cuando quito ya sea insertable palabra clave o actualizable , entonces funciona Sé que hay muchas soluciones para generar ID usando JPA, también JPA puede usar (llamar) secuencia de oráculo para establecer ID (generado). Pero trato de entender por qué mis soluciones están equivocadas. ¿Por qué no puedo usar ambas palabras clave junto con la anotación @Id? Mi idea es: Quiero prohibir insertar o actualizar caseId por JPA.
1) ¿Cuál es la verdadera comida? Debo utilizar solamente @Id:
@Id
@Column(name = "CASE_ID")
private Long caseId;
o es mejor (más seguro) definen insertable = false también:
@Id
@Column(name = "CASE_ID", insertable = false)
private Long caseId;
2) Entiendo que actualizable = false para @Id no tiene significado (actualización clave principal no tiene sentido, pero es posible por SQL prima), pero ¿qué significa (¿tiene algún ejemplo cuando es beneficioso):
@Id
@Column(name = "CASE_ID", updatable = false)
private Long caseId;
EDITAR 2012-04-13
Hice algunas pruebas:
Entidad
@Id
@Column(name = "CASE_ID")
private Long caseId;
APP ingrese
INSERT INTO CASE (CASE_ID, CASE_DATE, INFO) VALUES (?, ?, ?)
bind => [3 parameters bound]|#]
Así que esto no es seguro, porque la APP intenta tienda CASE_ID (que se sustituye entonces por ID de secuencia de Oracle desencadenar).
Entidad
@Id
@Column(name = "CASE_ID", insertable = false)
private Long caseId;
Crear método
public void createCase(final Case caseData) {
caseData.setCaseId(-1001L);
em.persist(caseData);
}
APP ingrese
INSERT INTO CASE (CASE_DATE, INFO) VALUES (?, ?)
bind => [2 parameters bound]|#]
Es bueno, porque el CASE_ID no es parte del comando de inserción.
y actualización de CASE_ID no es posible porque ID anotación:
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.
Así que ahora la última versión se ve como el más seguro, ¿verdad?
Eche un vistazo a http://stackoverflow.com/questions/3669883/hibernate-where-do-insertable-false-updatable-false-belong-in-composite-pr y http://stackoverflow.com/questions/3805584/please-explain-about-insertable-false-updatable-false y mira si te ayuda. –
@tech_learner lamentablemente no mucho – Ziletka
No estoy seguro, si ayuda pero ¿estás buscando una clase inmutable? Si es así, échale un vistazo a esto: http://www.mkyong.com/hibernate/hibernate-mutable-example-class-and-collection/ –