mysql - EclipseLink JPA Duplicate entry when persisting -
i have strange error when trying persist annotated object.
this code:
if (hashtags != null && !hashtags.isempty()) { tweet.sethashtags(new linkedlist<hashtag>()); (hashtag hashtag : hashtags) { hashtag hashtagentity = em .find(hashtag.class, hashtag.gettag()); if (hashtagentity == null) { logwrapper.logger.debug("h: " + hashtag.gettag()); em.persist(hashtag); tweet.gethashtags().add(hashtag); } else { tweet.gethashtags().add(hashtagentity); } } }
i know if try persist existing object exception check before calling persist method. can not find primary key cause exception not in log file nor in mysql database , confusing me how exception indicating primary key value not exist in database in first place.
edit
those annotated classes show attributes , annotations:
@entity public class tweet { @id @column(name = "id") private long id; private usuario usuario; private string texto; @temporal(temporaltype.timestamp) private date fecha; private int numretweets; @manytomany(fetch = fetchtype.eager) @jointable(name = "tweet_usuario_mencionado", joincolumns = { @joincolumn(name = "tweet_id", referencedcolumnname = "id") }, inversejoincolumns = { @joincolumn(name = "usuario_id", referencedcolumnname = "id") }) private linkedlist<usuario> usuariosreferenciados; @manytomany(fetch = fetchtype.eager) @jointable(name = "tweet_hashtag", joincolumns = { @joincolumn(name = "tweet_id", referencedcolumnname = "id") }, inversejoincolumns = { @joincolumn(name = "hashtag_id", referencedcolumnname = "id") }) private linkedlist<hashtag> hashtags; ... @entity @access(accesstype.field) public class usuario { @id @column(name = "id") private long id; private string nombreenpantalla; private int numtweets; @temporal(temporaltype.timestamp) private date fecharegistro; @onetomany(mappedby = "usuario", fetch = fetchtype.eager) private linkedlist<tweet> tweets; private int numfollowers; private double tweetsperday; ... @entity public class hashtag { @id @column(name = "id") private string tag; ...
this entire method code have problem:
public tweet creartweet(long idtweet, date fechatweet, int numretweets, string textotweet, long idusuario, date fecharegistrousuario, int followersusuario, string nombreenpantallausuario, int numtweetsusuario, list<usuario> usuariosmencionados, list<hashtag> hashtags) { entitymanager em = emf.createentitymanager(); em.gettransaction().begin(); tweet tweet = new tweet(); tweet.setfecha(fechatweet); tweet.setid(idtweet); tweet.setnumretweets(numretweets); tweet.settexto(textotweet); em.persist(tweet); usuario user = em.find(usuario.class, idusuario); if (user == null) { user = new usuario(); user.setfecharegistro(fecharegistrousuario); user.setid(idusuario); user.setnombreenpantalla(nombreenpantallausuario); user.setnumfollowers(followersusuario); user.setnumtweets(numtweetsusuario); em.persist(user); } tweet.setusuario(user); if (usuariosmencionados != null && !usuariosmencionados.isempty()) { tweet.setusuariosreferenciados(new linkedlist<usuario>()); (usuario usuariomencionado : usuariosmencionados) { usuario usuarioentity = em.find(usuario.class, usuariomencionado.getid()); if (usuarioentity == null) { logwrapper.logger.debug("u: " + usuariomencionado.getid() + " " + usuariomencionado.getnombreenpantalla()); em.persist(usuariomencionado); tweet.getusuariosreferenciados().add(usuariomencionado); } else { tweet.getusuariosreferenciados().add(usuarioentity); } } } if (hashtags != null && !hashtags.isempty()) { tweet.sethashtags(new linkedlist<hashtag>()); (hashtag hashtag : hashtags) { hashtag hashtagentity = em .find(hashtag.class, hashtag.gettag()); if (hashtagentity == null) { logwrapper.logger.debug("h: " + hashtag.gettag()); em.persist(hashtag); tweet.gethashtags().add(hashtag); } else { tweet.gethashtags().add(hashtagentity); } } } em.gettransaction().commit(); em.close(); return tweet; }
and entire stack-trace:
[el warning]: 2015-03-17 01:50:48.411--unitofwork(841203)--exception [eclipselink-4002] (eclipse persistence services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.databaseexception internal exception: com.mysql.jdbc.exceptions.jdbc4.mysqlintegrityconstraintviolationexception: duplicate entry '??' key 'primary' error code: 1062 call: insert hashtag (id) values (?) bind => [1 parameter bound] query: insertobjectquery(um.es.tfg.modelo.hashtag@7a77e4) exception in thread "main" javax.persistence.rollbackexception: exception [eclipselink-4002] (eclipse persistence services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.databaseexception internal exception: com.mysql.jdbc.exceptions.jdbc4.mysqlintegrityconstraintviolationexception: duplicate entry '??' key 'primary' error code: 1062 call: insert hashtag (id) values (?) bind => [1 parameter bound] query: insertobjectquery(um.es.tfg.modelo.hashtag@7a77e4) @ org.eclipse.persistence.internal.jpa.transaction.entitytransactionimpl.commit(entitytransactionimpl.java:159) @ um.es.tfg.dao.jpa.jpatweetdao.creartweet(jpatweetdao.java:76) @ um.es.tfg.core.tweetprocessorminer.startprocess(tweetprocessorminer.java:105) @ um.es.tfg.main.main.main(main.java:24) caused by: exception [eclipselink-4002] (eclipse persistence services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.databaseexception internal exception: com.mysql.jdbc.exceptions.jdbc4.mysqlintegrityconstraintviolationexception: duplicate entry '??' key 'primary' error code: 1062 call: insert hashtag (id) values (?) bind => [1 parameter bound] query: insertobjectquery(um.es.tfg.modelo.hashtag@7a77e4) @ org.eclipse.persistence.exceptions.databaseexception.sqlexception(databaseexception.java:331) @ org.eclipse.persistence.internal.databaseaccess.databaseaccessor.executedirectnoselect(databaseaccessor.java:902) @ org.eclipse.persistence.internal.databaseaccess.databaseaccessor.executenoselect(databaseaccessor.java:964) @ org.eclipse.persistence.internal.databaseaccess.databaseaccessor.basicexecutecall(databaseaccessor.java:633) @ org.eclipse.persistence.internal.databaseaccess.databaseaccessor.executecall(databaseaccessor.java:560) @ org.eclipse.persistence.internal.sessions.abstractsession.basicexecutecall(abstractsession.java:2055) @ org.eclipse.persistence.sessions.server.clientsession.executecall(clientsession.java:306) @ org.eclipse.persistence.internal.queries.datasourcecallquerymechanism.executecall(datasourcecallquerymechanism.java:242) @ org.eclipse.persistence.internal.queries.datasourcecallquerymechanism.executecall(datasourcecallquerymechanism.java:228) @ org.eclipse.persistence.internal.queries.datasourcecallquerymechanism.insertobject(datasourcecallquerymechanism.java:377) @ org.eclipse.persistence.internal.queries.statementquerymechanism.insertobject(statementquerymechanism.java:165) @ org.eclipse.persistence.internal.queries.statementquerymechanism.insertobject(statementquerymechanism.java:180) @ org.eclipse.persistence.internal.queries.databasequerymechanism.insertobjectforwrite(databasequerymechanism.java:489) @ org.eclipse.persistence.queries.insertobjectquery.executecommit(insertobjectquery.java:80) @ org.eclipse.persistence.queries.insertobjectquery.executecommitwithchangeset(insertobjectquery.java:90) @ org.eclipse.persistence.internal.queries.databasequerymechanism.executewritewithchangeset(databasequerymechanism.java:301) @ org.eclipse.persistence.queries.writeobjectquery.executedatabasequery(writeobjectquery.java:58) @ org.eclipse.persistence.queries.databasequery.execute(databasequery.java:904) @ org.eclipse.persistence.queries.databasequery.executeinunitofwork(databasequery.java:803) @ org.eclipse.persistence.queries.objectlevelmodifyquery.executeinunitofworkobjectlevelmodifyquery(objectlevelmodifyquery.java:108) @ org.eclipse.persistence.queries.objectlevelmodifyquery.executeinunitofwork(objectlevelmodifyquery.java:85) @ org.eclipse.persistence.internal.sessions.unitofworkimpl.internalexecutequery(unitofworkimpl.java:2896) @ org.eclipse.persistence.internal.sessions.abstractsession.executequery(abstractsession.java:1857) @ org.eclipse.persistence.internal.sessions.abstractsession.executequery(abstractsession.java:1839) @ org.eclipse.persistence.internal.sessions.abstractsession.executequery(abstractsession.java:1790) @ org.eclipse.persistence.internal.sessions.commitmanager.commitnewobjectsforclasswithchangeset(commitmanager.java:227) @ org.eclipse.persistence.internal.sessions.commitmanager.commitallobjectsforclasswithchangeset(commitmanager.java:194) @ org.eclipse.persistence.internal.sessions.commitmanager.commitallobjectswithchangeset(commitmanager.java:139) @ org.eclipse.persistence.internal.sessions.abstractsession.writeallobjectswithchangeset(abstractsession.java:4260) @ org.eclipse.persistence.internal.sessions.unitofworkimpl.committodatabase(unitofworkimpl.java:1441) @ org.eclipse.persistence.internal.sessions.unitofworkimpl.committodatabasewithchangeset(unitofworkimpl.java:1531) @ org.eclipse.persistence.internal.sessions.repeatablewriteunitofwork.commitrootunitofwork(repeatablewriteunitofwork.java:278) @ org.eclipse.persistence.internal.sessions.unitofworkimpl.commitandresume(unitofworkimpl.java:1169) @ org.eclipse.persistence.internal.jpa.transaction.entitytransactionimpl.commit(entitytransactionimpl.java:134) ... 3 more caused by: com.mysql.jdbc.exceptions.jdbc4.mysqlintegrityconstraintviolationexception: duplicate entry '??' key 'primary' @ sun.reflect.nativeconstructoraccessorimpl.newinstance0(native method) @ sun.reflect.nativeconstructoraccessorimpl.newinstance(unknown source) @ sun.reflect.delegatingconstructoraccessorimpl.newinstance(unknown source) @ java.lang.reflect.constructor.newinstance(unknown source) @ com.mysql.jdbc.util.handlenewinstance(util.java:377) @ com.mysql.jdbc.util.getinstance(util.java:360) @ com.mysql.jdbc.sqlerror.createsqlexception(sqlerror.java:971) @ com.mysql.jdbc.mysqlio.checkerrorpacket(mysqlio.java:3887) @ com.mysql.jdbc.mysqlio.checkerrorpacket(mysqlio.java:3823) @ com.mysql.jdbc.mysqlio.sendcommand(mysqlio.java:2435) @ com.mysql.jdbc.mysqlio.sqlquerydirect(mysqlio.java:2582) @ com.mysql.jdbc.connectionimpl.execsql(connectionimpl.java:2530) @ com.mysql.jdbc.preparedstatement.executeinternal(preparedstatement.java:1907) @ com.mysql.jdbc.preparedstatement.executeupdate(preparedstatement.java:2141) @ com.mysql.jdbc.preparedstatement.executeupdate(preparedstatement.java:2077) @ com.mysql.jdbc.preparedstatement.executeupdate(preparedstatement.java:2062) @ org.eclipse.persistence.internal.databaseaccess.databaseaccessor.executedirectnoselect(databaseaccessor.java:892) ... 35 more
edit 2
if em.flush() after every persist operation , comment following lines in code, error stops popping:
tweet.getusuariosreferenciados().add(usuariomencionado); tweet.getusuariosreferenciados().add(usuarioentity); tweet.gethashtags().add(hashtag); tweet.gethashtags().add(hashtagentity);
i commenting above lines trying little operations possible locate problem , tried without commenting lines , still error if so, said having them commented , flushing after every persist, code run fine not associate 2 more lists (hashtags , mentioned users ) of entities main entity (tweet). know due many persists without flushing doing in 1 transaction getting error don't know why says duplicate key.
after taking deep @ log produced eclipselink, found main problems due incompatible characters encoding. source producing text encoded in utf-8 , database using latin1 encoding. after inserting new row primary key can not represented correctly in latin1 in 1 of tables inserted ??? every interrogation sign replaces character , length of key matches length of original word , why getting duplicate entry exception, because after inserting example strange word composed 3 strange characters ??? duplicate entry exception when trying insert different strange word composed 3 different strange characters. tried configuring tables in database use utf-8 still getting problem because utf8 in mysql uses 3 bytes represent character , source has utf-8 encoded in 4 bytes. used utf8mb4 tables , not enough solve problem , needed configure mysql server character_set_server=utf8mb4
, restart server , doing connector/j able autodetect utf-8 setting properly.
Comments
Post a Comment