2014-12-21 10 views
7

Uso EclipseLink con JavaDB e ogni volta che provo a mantenere una nuova entità utente ottengo un errore relativo al campo ID della nuova entità utente è zero. So che è nullo e dovrebbe essere perché il campo ID è generato come identità nel database. O mi sbaglio? Ho provato ad aggiungere @GeneratedValue all'entità ma questo causa errori indipendentemente dalla strategia di generazione utilizzata. Ho anche cercato here, here e here ma queste domande non sembrano riguardare completamente il mio problema. Le eccezioni riportate di seguito si verificano sempre alla chiamata a EntityManager.persist (utente).Persistenza di un'entità quando ID è nullo e generato automaticamente nel database

Ho anche provato a rimuovere @NotNull e @GeneratedValue e, stranamente, ha superato la chiamata persistente, ma solo per fallire nel commit. Per quanto posso dire, ho messo tutto a posto. Quindi la domanda è: perché questa applicazione non riesce ad aggiungere un nuovo utente e cosa devo fare per risolverlo?

entità

utente:

@Entity(name = "User") 
@Table(name = "USERS") 
public class User implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Basic(optional = false) 
    @NotNull 
    @Column(name = "IDENTIFIER", nullable = false,unique = true) 
    private Long identifier; 
    // class shortened for brevity 
} 

Corrispondente a questo script SQL:

create table "USERSDBADMIN".USERS 
(
     IDENTIFIER BIGINT not null primary key GENERATED ALWAYS AS IDENTITY 
      (START WITH 0, INCREMENT BY 1), 
     USERNAME VARCHAR(50) not null, 
     EMAIL VARCHAR(150) not null, 
     LASTLOGIN DATE default NULL 
); 

utente Crea Method (dal controller JPA):

public void create(User user) throws PreexistingEntityException, RollbackFailureException, Exception { 
    EntityManager em = null; 
    try { 
     utx.begin(); 
     em = getEntityManager(); 
     em.persist(user); 
     utx.commit(); 
    } catch (Exception ex) { 
     try { 
      utx.rollback(); 
     } catch (Exception re) { 
      throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re); 
     } 
     if (findUser(user.getIdentifier()) != null) { 
      throw new PreexistingEntityException("User " + user + " already exists.", ex); 
     } 
     throw ex; 
    } finally { 
     if (em != null) { 
      em.close(); 
     } 
    } 
} 

errore GenerationStrategy.Identity (in pratica dicendo che il campo ID è nullo):

ex = (javax.validation.ConstraintViolationException) javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:'prePersist'. Please refer to embedded ConstraintViolations for details. 

errore GenerationStrategy.Sequence (Tabella e Auto producono stessa eccezione):

ex = (org.eclipse.persistence.exceptions.DatabaseException) Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException. Internal Exception: java.sql.SQLSyntaxErrorException: SEQUENCE 'SEQ_GEN_SEQUENCE' does not exist. Call: VALUES(NEXT VALUE FOR SEQ_GEN_SEQUENCE) Query: ValueReadQuery(sql="VALUES(NEXT VALUE FOR SEQ_GEN_SEQUENCE)") 

risposta

10

Non utilizzare @NotNull attributo sull'attributo @Id generato utilizzando la strategia GenerationType.IDENTITY. Il problema è @NotNull e altri vincoli JSR-303 sono convalidati prima del commit. E l'identificatore autoincrementato non è disponibile fino a dopo il completamento del commit.

Prova questa e non si preoccupano di ID di inizializzazione più:

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = "IDENTIFIER", nullable = false, unique = true) 
private Long identifier; 
+0

Questa è una soluzione molto migliore - non mi interessa più l'inizializzazione dell'ID! Avrei dovuto provarlo prima di postare, ma funziona. Grazie a @Lukas! –

0

Quando sto usando incremento automatico presso l'identificatore mi piace questo:

User user = new User(); 
user.setIdentifier((long) 0);// Assign 0 to ID for MSSQL/MySQL to properly auto_increment the primary key. 
user.setUserName("some name"); 
... 

Con questa annotazione per l'id:

private static final long serialVersionUID = 1L; 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Basic(optional = false) 
@NotNull 
@Column(name = "ID") 
private Long id; 
+0

Welp che ha fatto. Ma uomo? Perché devo impostare il campo ID? Voglio dire, JPA dovrebbe impostarlo automaticamente. –

+0

Non è necessario impostare il campo ID: vedere la risposta accettata. Inoltre, l'impostazione dell'ID su zero farà sì che le cose vadano male perché avvio il mio identificatore con zero (vedi SQL). -1 potrebbe funzionare ma non ho mai provato. –

Problemi correlati