2012-11-09 14 views
6

Như bạn và tôi đều biết, có quá nhiều câu hỏi về loại thông báo lỗi này.Mục nhập trùng lặp '...' cho khóa 'CHÍNH'

Nhưng tôi không thể tìm thấy câu trả lời hay nào vì có quá nhiều câu trả lời.

Tôi có bảng lưu trữ nonce giây được gửi từ khách hàng.

Nhưng đôi khi (đôi khi) db phàn nàn về việc chèn khóa chính trùng lặp ngay cả khi không có bản ghi nào có cùng khóa chính.

Đây là những gì JVM hiển thị.

[#|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' 
|#] 

Đây là những gì mysql hiển thị.

mysql> SHOW VARIABLES LIKE "%version%"; 
+-------------------------+-------------------------+ 
| Variable_name   | Value     | 
+-------------------------+-------------------------+ 
| protocol_version  | 10      | 
| version     | 5.1.62-0ubuntu0.10.04.1 | 
| version_comment   | (Ubuntu)    | 
| version_compile_machine | x86_64     | 
| version_compile_os  | debian-linux-gnu  | 
+-------------------------+-------------------------+ 
5 rows in set (0.00 sec) 

mysql> DESC NONCE2; 
+--------------+--------------+------+-----+-------------------+-------+ 
| Field  | Type   | Null | Key | Default   | Extra | 
+--------------+--------------+------+-----+-------------------+-------+ 
| CREATED_DATE | timestamp | NO |  | CURRENT_TIMESTAMP |  | 
| UDID   | varchar(255) | NO | PRI | NULL    |  | 
| NONCE  | varchar(255) | NO | PRI | NULL    |  | 
+--------------+--------------+------+-----+-------------------+-------+ 
3 rows in set (0.00 sec) 

mysql> SHOW CREATE TABLE NONCE2; 
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Table | Create Table                                                    | 
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| NONCE2 | CREATE TABLE `NONCE2` (
    `CREATED_DATE` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `UDID` varchar(255) NOT NULL, 
    `NONCE` varchar(255) NOT NULL, 
    PRIMARY KEY (`UDID`,`NONCE`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 | 
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | 
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| NONCE2 |   0 | PRIMARY |   1 | UDID  | A   |   7 |  NULL | NULL |  | BTREE  |   | 
| NONCE2 |   0 | PRIMARY |   2 | NONCE  | A   |   403 |  NULL | NULL |  | BTREE  |   | 
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
2 rows in set (0.00 sec) 

mysql> 

Tôi đã thử xóa và tạo lại bảng nhưng cùng một loại vấn đề xảy ra.

Tôi có JPA trên GlassFish.

Bất kỳ trợ giúp nào?

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

Tôi đang làm việc với JPA.

Lớp ID.

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

Lớp thực thể.

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

Và trong Lọc tôi làm

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

nhà cung cấp JPA của tôi dường như thực hiện tuyên bố này.

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

Bạn đã bao giờ tìm ra vấn đề là gì chưa? Chúng tôi có một vấn đề tương tự trong một dự án sử dụng JPA và một cột VARCHAR (255) duy nhất. Dường như thông báo lỗi ngoại lệ chỉ hiển thị 64 ký tự đầu tiên của giá trị chỉ mục. Khi chúng tôi chèn một bản ghi tương tự trực tiếp vào DB, chúng tôi sẽ không nhận được lỗi khóa trùng lặp nào. Trong trường hợp của bạn "c8b4bdb84606fed0-c8b4bdb84606fed0_1352426820765_1880007534138556" cũng dài 64 ký tự. Nhưng nó không phải là giá trị hoàn chỉnh bạn đang cố gắng chèn: 402 là mất tích ở cuối. – tvirtualw

+1

Chúng tôi đã tìm ra giải pháp cho vấn đề của mình. Theo mặc định, collation MySQL không phân biệt chữ hoa chữ thường. Các giá trị mà chúng tôi đã cố chèn vào bảng của chúng tôi có cùng các ký tự và đôi khi chúng chỉ khác nhau một chữ cái là chữ hoa, chữ thường khác. Giống như 'abcd' so với 'aBcd'. Với collation mặc định nó sẽ gây ra một sự vi phạm chỉ mục duy nhất (tôi đoán tương tự cho các khóa chính). Chúng tôi thay đổi nó thành utf8_bin và sau đó nó làm việc cho chúng tôi. – tvirtualw

+1

Tôi đoán nonce phải có một ý nghĩa khác với định nghĩa chuẩn trong tiếng lóng của Vương quốc Anh! – Strawberry

Trả lời

3

Bạn có khóa chính kết hợp được xác định trên bảng.

Có thể bạn đang cố gắng chèn bản ghi vào một đợt trong cùng một phiên. Và lô có thể chứa các mục trùng lặp cho các cột khóa đã nói. Vui lòng kiểm tra.

Cũng vui lòng đăng mã chèn của bạn với dữ liệu mẫu.

+0

Có thể chức năng thử lại tự động của apache-http-client đang gây ra vấn đề này. Tôi đi vào đó. –