java - MySQLIntegrityConstraintViolationException crashes application -



java - MySQLIntegrityConstraintViolationException crashes application -

this application, romecnn, uses rome 1.5.0 iterate through cnn news feed , persist url's database. database rejects duplicate links.

that there mysqlintegrityconstraintviolationexception type exceptions ok, inserts should rejected database. perhaps there's improve way avoid duplicates, sufficient. (unless else happening? thinking "if link exists, grab exception, , move on next".)

why application crash? after threshold of integrity constraint violations, connection broken?

run: [java] [el info]: 2014-11-03 01:20:39.432--serversession(28432534)--eclipselink, version: eclipse persistence services - 2.5.2.v20140319-9ad6abd [java] [el info]: connection: 2014-11-03 01:20:40.173--serversession(28432534)--file:/home/thufir/netbeansprojects/romecnn/build/classes/_romereaderpu login successful [java] [el warning]: 2014-11-03 01:20:40.405--unitofwork(6261946)--exception [eclipselink-4002] (eclipse persistence services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.databaseexception [java] internal exception: com.mysql.jdbc.exceptions.jdbc4.mysqlintegrityconstraintviolationexception: duplicate entry 'http://rss.cnn.com/~r/rss/cnn_topstories/~3/wd5aw61it7m/nr-kenya' key 'unq_links_0' [java] error code: 1062 [java] call: insert links.links (created, link, status) values (?, ?, ?) [java] bind => [3 parameters bound] [java] query: insertobjectquery(romereader.link[ id=null ]) [java] exception in thread "main" javax.persistence.rollbackexception: exception [eclipselink-4002] (eclipse persistence services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.databaseexception [java] internal exception: com.mysql.jdbc.exceptions.jdbc4.mysqlintegrityconstraintviolationexception: duplicate entry 'http://rss.cnn.com/~r/rss/cnn_topstories/~3/wd5aw61it7m/nr-kenya' key 'unq_links_0' [java] error code: 1062 [java] call: insert links.links (created, link, status) values (?, ?, ?) [java] bind => [3 parameters bound] [java] query: insertobjectquery(romereader.link[ id=null ]) [java] @ org.eclipse.persistence.internal.jpa.transaction.entitytransactionimpl.commit(entitytransactionimpl.java:157) [java] @ romereader.linkjpacontroller.create(linkjpacontroller.java:31) [java] @ romereader.main.getlinks(main.java:41) [java] @ romereader.main.main(main.java:21) [java] caused by: exception [eclipselink-4002] (eclipse persistence services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.databaseexception [java] internal exception: com.mysql.jdbc.exceptions.jdbc4.mysqlintegrityconstraintviolationexception: duplicate entry 'http://rss.cnn.com/~r/rss/cnn_topstories/~3/wd5aw61it7m/nr-kenya' key 'unq_links_0' [java] error code: 1062 [java] call: insert links.links (created, link, status) values (?, ?, ?) [java] bind => [3 parameters bound] [java] query: insertobjectquery(romereader.link[ id=null ]) [java] @ org.eclipse.persistence.exceptions.databaseexception.sqlexception(databaseexception.java:331) [java] @ org.eclipse.persistence.internal.databaseaccess.databaseaccessor.executedirectnoselect(databaseaccessor.java:900) [java] @ org.eclipse.persistence.internal.databaseaccess.databaseaccessor.executenoselect(databaseaccessor.java:962) [java] @ org.eclipse.persistence.internal.databaseaccess.databaseaccessor.basicexecutecall(databaseaccessor.java:631) [java] @ org.eclipse.persistence.internal.databaseaccess.databaseaccessor.executecall(databaseaccessor.java:558) [java] @ org.eclipse.persistence.internal.sessions.abstractsession.basicexecutecall(abstractsession.java:2002) [java] @ org.eclipse.persistence.sessions.server.clientsession.executecall(clientsession.java:298) [java] @ org.eclipse.persistence.internal.queries.datasourcecallquerymechanism.executecall(datasourcecallquerymechanism.java:242) [java] @ org.eclipse.persistence.internal.queries.datasourcecallquerymechanism.executecall(datasourcecallquerymechanism.java:228) [java] @ org.eclipse.persistence.internal.queries.datasourcecallquerymechanism.insertobject(datasourcecallquerymechanism.java:377) [java] @ org.eclipse.persistence.internal.queries.statementquerymechanism.insertobject(statementquerymechanism.java:165) [java] @ org.eclipse.persistence.internal.queries.statementquerymechanism.insertobject(statementquerymechanism.java:180) [java] @ org.eclipse.persistence.internal.queries.databasequerymechanism.insertobjectforwrite(databasequerymechanism.java:489) [java] @ org.eclipse.persistence.queries.insertobjectquery.executecommit(insertobjectquery.java:80) [java] @ org.eclipse.persistence.queries.insertobjectquery.executecommitwithchangeset(insertobjectquery.java:90) [java] @ org.eclipse.persistence.internal.queries.databasequerymechanism.executewritewithchangeset(databasequerymechanism.java:301) [java] @ org.eclipse.persistence.queries.writeobjectquery.executedatabasequery(writeobjectquery.java:58) [java] @ org.eclipse.persistence.queries.databasequery.execute(databasequery.java:899) [java] @ org.eclipse.persistence.queries.databasequery.executeinunitofwork(databasequery.java:798) [java] @ org.eclipse.persistence.queries.objectlevelmodifyquery.executeinunitofworkobjectlevelmodifyquery(objectlevelmodifyquery.java:108) [java] @ org.eclipse.persistence.queries.objectlevelmodifyquery.executeinunitofwork(objectlevelmodifyquery.java:85) [java] @ org.eclipse.persistence.internal.sessions.unitofworkimpl.internalexecutequery(unitofworkimpl.java:2896) [java] @ org.eclipse.persistence.internal.sessions.abstractsession.executequery(abstractsession.java:1804) [java] @ org.eclipse.persistence.internal.sessions.abstractsession.executequery(abstractsession.java:1786) [java] @ org.eclipse.persistence.internal.sessions.abstractsession.executequery(abstractsession.java:1737) [java] @ org.eclipse.persistence.internal.sessions.commitmanager.commitnewobjectsforclasswithchangeset(commitmanager.java:226) [java] @ org.eclipse.persistence.internal.sessions.commitmanager.commitallobjectswithchangeset(commitmanager.java:125) [java] @ org.eclipse.persistence.internal.sessions.abstractsession.writeallobjectswithchangeset(abstractsession.java:4207) [java] @ org.eclipse.persistence.internal.sessions.unitofworkimpl.committodatabase(unitofworkimpl.java:1441) [java] @ org.eclipse.persistence.internal.sessions.unitofworkimpl.committodatabasewithchangeset(unitofworkimpl.java:1531) [java] @ org.eclipse.persistence.internal.sessions.repeatablewriteunitofwork.commitrootunitofwork(repeatablewriteunitofwork.java:277) [java] @ org.eclipse.persistence.internal.sessions.unitofworkimpl.commitandresume(unitofworkimpl.java:1169) [java] @ org.eclipse.persistence.internal.jpa.transaction.entitytransactionimpl.commit(entitytransactionimpl.java:132) [java] ... 3 more [java] caused by: com.mysql.jdbc.exceptions.jdbc4.mysqlintegrityconstraintviolationexception: duplicate entry 'http://rss.cnn.com/~r/rss/cnn_topstories/~3/wd5aw61it7m/nr-kenya' key 'unq_links_0' [java] @ sun.reflect.nativeconstructoraccessorimpl.newinstance0(native method) [java] @ sun.reflect.nativeconstructoraccessorimpl.newinstance(nativeconstructoraccessorimpl.java:57) [java] @ sun.reflect.delegatingconstructoraccessorimpl.newinstance(delegatingconstructoraccessorimpl.java:45) [java] @ java.lang.reflect.constructor.newinstance(constructor.java:526) [java] @ com.mysql.jdbc.util.handlenewinstance(util.java:411) [java] @ com.mysql.jdbc.util.getinstance(util.java:386) [java] @ com.mysql.jdbc.sqlerror.createsqlexception(sqlerror.java:1040) [java] @ com.mysql.jdbc.mysqlio.checkerrorpacket(mysqlio.java:4120) [java] @ com.mysql.jdbc.mysqlio.checkerrorpacket(mysqlio.java:4052) [java] @ com.mysql.jdbc.mysqlio.sendcommand(mysqlio.java:2503) [java] @ com.mysql.jdbc.mysqlio.sqlquerydirect(mysqlio.java:2664) [java] @ com.mysql.jdbc.connectionimpl.execsql(connectionimpl.java:2794) [java] @ com.mysql.jdbc.preparedstatement.executeinternal(preparedstatement.java:2155) [java] @ com.mysql.jdbc.preparedstatement.executeupdate(preparedstatement.java:2458) [java] @ com.mysql.jdbc.preparedstatement.executeupdate(preparedstatement.java:2375) [java] @ com.mysql.jdbc.preparedstatement.executeupdate(preparedstatement.java:2359) [java] @ org.eclipse.persistence.internal.databaseaccess.databaseaccessor.executedirectnoselect(databaseaccessor.java:890) [java] ... 34 more [java] java result: 1 build successful total time: 6 seconds thufir@dur:~/netbeansprojects/romecnn$ thufir@dur:~/netbeansprojects/romecnn$

the jpacontroller:

package romereader; import java.io.serializable; import java.util.list; import javax.persistence.entitymanager; import javax.persistence.entitymanagerfactory; import javax.persistence.query; import javax.persistence.entitynotfoundexception; import javax.persistence.criteria.criteriaquery; import javax.persistence.criteria.root; import romereader.exceptions.nonexistententityexception; public class linkjpacontroller implements serializable { public linkjpacontroller(entitymanagerfactory emf) { this.emf = emf; } private entitymanagerfactory emf = null; public entitymanager getentitymanager() { homecoming emf.createentitymanager(); } public void create(link link) { entitymanager em = null; seek { em = getentitymanager(); em.gettransaction().begin(); em.persist(link); em.gettransaction().commit(); } { if (em != null) { em.close(); } } } public void edit(link link) throws nonexistententityexception, exception { entitymanager em = null; seek { em = getentitymanager(); em.gettransaction().begin(); link = em.merge(link); em.gettransaction().commit(); } grab (exception ex) { string msg = ex.getlocalizedmessage(); if (msg == null || msg.length() == 0) { integer id = link.getid(); if (findlink(id) == null) { throw new nonexistententityexception("the link id " + id + " no longer exists."); } } throw ex; } { if (em != null) { em.close(); } } } public void destroy(integer id) throws nonexistententityexception { entitymanager em = null; seek { em = getentitymanager(); em.gettransaction().begin(); link link; seek { link = em.getreference(link.class, id); link.getid(); } grab (entitynotfoundexception enfe) { throw new nonexistententityexception("the link id " + id + " no longer exists.", enfe); } em.remove(link); em.gettransaction().commit(); } { if (em != null) { em.close(); } } } public list<link> findlinkentities() { homecoming findlinkentities(true, -1, -1); } public list<link> findlinkentities(int maxresults, int firstresult) { homecoming findlinkentities(false, maxresults, firstresult); } private list<link> findlinkentities(boolean all, int maxresults, int firstresult) { entitymanager em = getentitymanager(); seek { criteriaquery cq = em.getcriteriabuilder().createquery(); cq.select(cq.from(link.class)); query q = em.createquery(cq); if (!all) { q.setmaxresults(maxresults); q.setfirstresult(firstresult); } homecoming q.getresultlist(); } { em.close(); } } public link findlink(integer id) { entitymanager em = getentitymanager(); seek { homecoming em.find(link.class, id); } { em.close(); } } public int getlinkcount() { entitymanager em = getentitymanager(); seek { criteriaquery cq = em.getcriteriabuilder().createquery(); root<link> rt = cq.from(link.class); cq.select(em.getcriteriabuilder().count(rt)); query q = em.createquery(cq); homecoming ((long) q.getsingleresult()).intvalue(); } { em.close(); } } }

while inserts made database, why chokes, apparently, on either constraints violations, or specific url, isn't clear me.

the persistence.xml file:

<?xml version="1.0" encoding="utf-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="romereaderpu" transaction-type="resource_local"> <provider>org.eclipse.persistence.jpa.persistenceprovider</provider> <class>romereader.links</class> <class>romereader.link</class> <properties> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/links?zerodatetimebehavior=converttonull"/> <property name="javax.persistence.jdbc.password" value="password"/> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.driver"/> <property name="javax.persistence.jdbc.user" value="jdbc"/> </properties> </persistence-unit> </persistence>

the easiest approach first check if link exists in database , either update/skip or insert new item. this:

em = getentitymanager(); link existing = em.find(link.class, link.getlink()); if (existing == null) { em.gettransaction().begin(); em.persist(link); em.gettransaction().commit(); }

to create maybe more robust, utilize syndentry.geturi() value unique identifier. can't check now, i'm sure maps guid element of item:

<item> <title>protectionist wins melbourne cup</title> <guid>http://edition.cnn.com/2014/11/04/asia/gallery/melbourne-cup/index.html</guid> <link>http://edition.cnn.com/2014/11/04/asia/gallery/melbourne-cup/index.html?eref=edition</link> <description>australia's melbourne cup</description> <pubdate>tue, 04 nov 2014 01:52:42 est</pubdate> </item>

if take update elements, pubdate value can used determine if item has been updated since lastly time saved it.

rss duplicate detection intresting blog post subject (unfortunately found via archive.org.)

if read rss 2.0 specification, you'll find <link> can omitted <item> can maintain in mind.

java mysql jpa exception-handling rss

Comments

Popular posts from this blog

Delphi change the assembly code of a running process -

json - Hibernate and Jackson (java.lang.IllegalStateException: Cannot call sendError() after the response has been committed) -

C++ 11 "class" keyword -