Oboje wiemy, że tak wiele pytań dotyczy tego rodzaju komunikatów o błędach.Zduplikowany wpis "..." dla klucza "PODSTAWOWY"
Ale nie mogłem znaleźć żadnych dobrych odpowiedzi, ponieważ jest tak wiele odpowiedzi.
Mam tabelę przechowującą nonce
s wysłane od klientów.
Ale czasami (sporadycznie) db narzeka na duplikowanie wstawiania klucza głównego, nawet jeśli nie ma rekordu z dokładnie tym samym kluczem podstawowym.
Oto, co pokazuje JVM.
[#|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'
|#]
Oto, co pokazuje mysql.
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>
Próbowałem upuszczenie i ponowne utworzenie tabeli, ale tego samego rodzaju problemy występują.
Jestem z JPA na GlassFish.
Każda pomoc?
----------------------------------------- UPDATE
Pracuję z JPA.
Klasa 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;
}
Klasa encji.
@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;
}
I w moim Filtr zrobić
@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.
}
}
Mój dostawca JPA wydaje wykonać to oświadczenie.
INSERT INTO NONCE2 (NONCE, UDID, CREATED_DATE) VALUES (?, ?, ?)
Czy kiedykolwiek zastanawiałeś się, na czym polega problem? Mamy podobny problem w projekcie wykorzystującym JPA i unikalną kolumnę VARCHAR (255). Wygląda na to, że komunikat o błędzie wyjątku pokazuje tylko pierwszych 64 znaków wartości indeksu. Kiedy wstawimy podobny rekord bezpośrednio do DB, nie otrzymamy duplikatu błędu klucza. W twoim przypadku "c8b4bdb84606fed0-c8b4bdb84606fed0_1352426820765_1880007534138556" również ma 64 znaki. Ale nie jest to całkowita wartość, którą próbujesz wstawić: 402 brakuje na końcu. – tvirtualw
Znaleźliśmy rozwiązanie naszego problemu. Domyślnie sortowanie MySQL jest niewrażliwe na wielkość liter. Wartości, które próbowaliśmy wstawić do naszego stołu, miały te same znaki, a czasami różniły się tylko jedną literą składającą się z wielkich liter, a drugą małą. Podobnie jak "abcd" vs. "aBcd". Przy domyślnym sortowaniu spowoduje to unikalne naruszenie indeksu (przypuszczam to samo w przypadku kluczy podstawowych). Zmieniliśmy go na utf8_bin, a następnie zadziałało dla nas. – tvirtualw
Przypuszczam, że nonce musi mieć inne znaczenie niż standardowa definicja w brytyjskim slangu! – Strawberry