2014-12-21 4 views
7

Ich benutze EclipseLink mit JavaDB und jedes Mal, wenn ich versuche, eine neue Benutzereinheit zu erhalten, bekomme ich einen Fehler in Bezug auf das ID-Feld der neuen Benutzereinheit ist Null. Ich weiß, dass es null ist - und es sollte sein, weil das ID-Feld als die Identität in der Datenbank generiert wird. Oder liege ich falsch? Ich habe versucht, @GeneratedValue der Entität hinzuzufügen, aber das verursacht Fehler unabhängig von der verwendeten Generierungsstrategie. Ich habe auch here, here und here angesehen, aber diese Fragen scheinen sich nicht vollständig auf mein Problem beziehen. Die folgenden Ausnahmen treten immer beim Aufruf von EntityManager.persist (user) auf.Eine Entität beibehalten, wenn die ID null ist und automatisch in der Datenbank generiert wird

Ich habe auch versucht, @NotNull und @GeneratedValue zu entfernen, und seltsamerweise ist es über den anhaltenden Aufruf hinausgekommen - aber nur um beim Commit fehlzuschlagen. Soweit ich das beurteilen kann, habe ich alles richtig gemacht. Die Frage ist also: Warum kann diese Anwendung keinen neuen Benutzer hinzufügen und was muss ich tun, um sie zu beheben?

Benutzer Einheit:

@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 
} 

diesen SQL-Skript Entsprechende:

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

Benutzer Methode Create (aus dem JPA-Controller):

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(); 
     } 
    } 
} 

GenerationStrategy.Identity Fehler (im Grunde sagend, dass das ID-Feld Null ist):

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. 

GenerationStrategy.Sequence Fehler (Tabelle und Auto produzieren gleiche Ausnahme):

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)") 

Antwort

10

Verwenden Sie nicht @NotNull Nachteile Traint auf @Id Attribut generiert mit Strategie. Das Problem ist @NotNull und andere JSR-303 Constraints werden vor dem Festschreiben validiert. Und der autoincremened Bezeichner ist nicht verfügbar, bis das Commit abgeschlossen ist.

Versuchen Sie dies und kümmern sich nicht um ID Initialisierung mehr:

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

Das ist eine viel bessere Lösung - ich interessiere mich wirklich nicht mehr für die ID-Initialisierung! Ich hätte es vor dem Posten ausprobiert - aber es funktioniert. Danke @Lukas! –

0

Wenn ich Autoinkrement am Bezeichner verwenden ich tun, wie folgt:

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"); 
... 

Mit dieser Annotation für die ID:

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

Welp, die es tat. Aber wtf Mann? Warum muss ich das ID-Feld einstellen? Ich meine, JPA sollte es automatisch einstellen. –

+0

Ich muss nicht das ID-Feld festlegen - siehe die angenommene Antwort. Außerdem wird die ID auf Null gesetzt, was dazu führt, dass die Dinge verrückt werden, weil ich den Identifier mit Null starte (siehe SQL). -1 könnte funktionieren, aber ich habe es nie versucht. –

Verwandte Themen