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 (?, ?, ?)
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
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
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