2012-11-09 11 views
6

Wie Sie und ich beide wissen, gibt es so viele Fragen über diese Art von Fehlermeldungen.Doppelten Eintrag '...' für Schlüssel 'PRIMARY'

Aber ich konnte keine guten Antworten finden, weil es so viele Antworten gibt.

Ich habe eine Tabelle gespeichert nonce s von Clients gesendet.

Aber manchmal (gelegentlich) beschwert sich db über doppelte Einfügung von Primärschlüssel, auch wenn es keinen Datensatz mit genau dem gleichen Primärschlüssel gibt.

Hier kommt, was JVM zeigt.

[#|2012-11-09T11:06:52.098+0900|WARNING|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=236;_ThreadName=Thread-2;|EJB5184:A system exception occurred during an invocation on EJB Nonce2Bean, method: public java.lang.Object kr.co.ticomms.gameground.business.AbstractEntityFacade.persist(java.lang.Object)|#] 

[#|2012-11-09T11:06:52.099+0900|WARNING|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=236;_ThreadName=Thread-2;|javax.ejb.EJBException 
     ... 
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException 
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'c8b4bdb84606fed0-c8b4bdb84606fed0_1352426820765_1880007534138556' for key 'PRIMARY' 
Error Code: 1062 
Call: INSERT INTO NONCE2 (NONCE, UDID, CREATED_DATE) VALUES (?, ?, ?) 
     bind => [3 parameters bound] 
Query: InsertObjectQuery(c8b4bdb84606fed0/c8b4bdb84606fed0_1352426820765_1880007534138556402) 
     ... 
     ... 29 more 
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException 
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'c8b4bdb84606fed0-c8b4bdb84606fed0_1352426820765_1880007534138556' for key 'PRIMARY' 
Error Code: 1062 
Call: INSERT INTO NONCE2 (NONCE, UDID, CREATED_DATE) VALUES (?, ?, ?) 
     bind => [3 parameters bound] 
Query: InsertObjectQuery(c8b4bdb84606fed0/c8b4bdb84606fed0_1352426820765_1880007534138556402) 
     ... 
     ... 59 more 
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'c8b4bdb84606fed0-c8b4bdb84606fed0_1352426820765_1880007534138556' for key 'PRIMARY' 
|#] 

Hier kommt was mysql zeigt.

Ich versuchte, die Tabelle zu löschen und neu zu erstellen, aber die gleichen Probleme treten auf.

Ich bin mit JPA auf GlassFish.

Irgendwelche Hilfe?

----------------------------------------- UPDATE

Ich arbeite mit JPA.

ID-Klasse.

public class NonceId implements Serializable { 

    public static NonceId newInstance(final String udid, final String nonce) { 
     if (udid == null) { 
      throw new IllegalArgumentException("null udid"); 
     } 
     if (nonce == null) { 
      throw new IllegalArgumentException("null nonce"); 
     } 
     final NonceId instance = new NonceId(); 
     instance.udid = udid; 
     instance.nonce = nonce; 
     return instance; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 7; 
     hash = 23 * hash + (this.udid != null ? this.udid.hashCode() : 0); 
     hash = 23 * hash + (this.nonce != null ? this.nonce.hashCode() : 0); 
     return hash; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (obj == null) { 
      return false; 
     } 
     if (getClass() != obj.getClass()) { 
      return false; 
     } 
     final NonceId other = (NonceId) obj; 
     if ((this.udid == null) ? (other.udid != null) : !this.udid.equals(other.udid)) { 
      return false; 
     } 
     if ((this.nonce == null) ? (other.nonce != null) : !this.nonce.equals(other.nonce)) { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public String toString() { 
     return udid + "/" + nonce; 
    } 

    private String udid; 

    private String nonce; 
} 

Entitätsklasse.

@Entity 
@IdClass(NonceId.class) 
@Table(name = "NONCE2") 
@XmlTransient 
public class Nonce2 implements Serializable { 

    public static final int UDID_SIZE_MIN = 1; 
    public static final int UDID_SIZE_MAX = 255; 
    public static final int NONCE_SIZE_MIN = 1; 
    public static final int NONCE_SIZE_MAX = 255; 

    public static Nonce2 newInstance(final String udid, final String nonce) { 
     if (nonce == null) { 
      throw new NullPointerException("null value"); 
     } 
     final Nonce2 instance = new Nonce2(); 
     instance.udid = udid; 
     instance.nonce = nonce; 
     return instance; 
    } 

    public Date getCreatedDate() { 
     return createdDate; 
    } 

    public String getUdid() { 
     return udid; 
    } 

    public String getNonce() { 
     return nonce; 
    } 

    @PrePersist 
    protected void _PrePersist() { 
     createdDate = new Date(); 
    } 

    @Override 
    public String toString() { 
     return udid + "/" + nonce; 
    } 

    @Column(name = "CREATED_DATE", nullable = false, updatable = false) 
    @Temporal(TemporalType.TIMESTAMP) 
    @NotNull 
    private Date createdDate; 

    @Id 
    @Column(name = "UDID", nullable = false, updatable = false) 
    @NotNull 
    @Size(min = UDID_SIZE_MIN, max = UDID_SIZE_MAX) 
    private String udid; 

    @Id 
    @Column(name = "NONCE", nullable = false, updatable = false) 
    @NotNull 
    @Size(min = NONCE_SIZE_MIN, max = NONCE_SIZE_MAX) 
    private String nonce; 
} 

Und in meinem Filter ich

@WebFilter(urlPatterns = {"/*"}) 
public class Filter_ implements Filter { 

    @Override 
    public void doFilter(final ServletRequest request, 
         final ServletResponse response, 
         final FilterChain chain) 
     throws IOException, ServletException { 

     // check whether nonce is already exist via em.find(); 

     chain.doFilter(request, response); 

     // store nonce via em.persist(); // EXCEPTION IS HERE 
     // THERE IS NO SUCH RECORD check direct SQL console. 
    } 
} 

Mein JPA-Provider diese Aussage scheint auszuführen.

INSERT INTO NONCE2 (NONCE, UDID, CREATED_DATE) VALUES (?, ?, ?) 
+1

Haben Sie jemals herausgefunden, was das Problem war? Wir haben ein ähnliches Problem in einem Projekt, das JPA und eine eindeutige VARCHAR (255) -Spalte verwendet. Es scheint, dass die Ausnahmefehlermeldung nur die ersten 64 Zeichen des Indexwerts anzeigt. Wenn wir einen ähnlichen Datensatz direkt in die DB einfügen, erhalten wir keinen doppelten Schlüsselfehler. In Ihrem Fall ist "c8b4bdb84606fed0-c8b4bdb84606fed0_1352426820765_1880007534138556" auch 64 Zeichen lang. Aber es ist nicht der vollständige Wert, den Sie einfügen möchten: 402 fehlt am Ende. – tvirtualw

+1

Wir haben eine Lösung für unser Problem gefunden. Standardmäßig wird bei der MySQL-Sortierung nicht zwischen Groß- und Kleinschreibung unterschieden. Die Werte, die wir in unsere Tabelle einfügen wollten, hatten die gleichen Zeichen und manchmal unterschieden sie sich nur dadurch, dass ein Buchstabe Großbuchstabe, der andere Kleinbuchstabe war. Wie 'abcd' vs. 'aBcd'. Mit der Standard-Sortierung wird es eine eindeutige Indexverletzung (ich denke, das gleiche für Primärschlüssel). Wir haben es in utf8_bin geändert und dann hat es für uns funktioniert. – tvirtualw

+1

Ich denke, Nonce muss eine andere Bedeutung als die Standarddefinition in UK Slang haben! – Strawberry

Antwort

3

Sie haben einen zusammengesetzten Primärschlüssel definiert in der Tabelle.

Möglicherweise versuchen Sie, Datensätze in einem Batch während derselben Sitzung einzufügen. Und der Stapel kann doppelte Einträge für die Schlüsselspalten enthalten. Bitte überprüfen Sie das.

Bitte geben Sie auch Ihren Einfügecode mit Beispieldaten an.

+0

Die automatische Wiederholungsfunktion des Apache-HTTP-Clients macht dieses Problem möglicherweise. Ich bin dran. –

Verwandte Themen