2014-11-03 7 views
2

이 응용 프로그램 RomeCNNRome 1.5.0을 사용하여 CNN 뉴스 피드를 반복하고 URL을 데이터베이스에 유지합니다. 데이터베이스가 중복 링크를 거부합니다.MySQLIntegrityConstraintViolationException 응용 프로그램이 다운 됨

유형 예외가 MySQLIntegrityConstraintViolationException 인 경우 해당 삽입이 데이터베이스에서 거부되어야합니다. 아마도 중복을 피하는 더 좋은 방법이있을 수 있지만, 지금은 충분합니다. (다른 문제가 발생하지 않는다면 "링크가 이미 존재하고 예외를 잡아서 다음으로 넘어 간다"라고 생각하고있었습니다.)

응용 프로그램이 충돌하는 이유는 무엇입니까? 무결성 제약 조건 위반의 특정 임계 값 이후에 연결이 끊어 졌습니까?

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' for key 'UNQ_links_0' 
    [java] Error Code: 1062 
    [java] Call: INSERT INTO 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' for key 'UNQ_links_0' 
    [java] Error Code: 1062 
    [java] Call: INSERT INTO links.links (created, link, status) VALUES (?, ?, ?) 
    [java]  bind => [3 parameters bound] 
    [java] Query: InsertObjectQuery(romereader.Link[ id=null ]) 
    [java]  at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:157) 
    [java]  at romereader.LinkJpaController.create(LinkJpaController.java:31) 
    [java]  at romereader.Main.getLinks(Main.java:41) 
    [java]  at 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' for key 'UNQ_links_0' 
    [java] Error Code: 1062 
    [java] Call: INSERT INTO links.links (created, link, status) VALUES (?, ?, ?) 
    [java]  bind => [3 parameters bound] 
    [java] Query: InsertObjectQuery(romereader.Link[ id=null ]) 
    [java]  at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331) 
    [java]  at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:900) 
    [java]  at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:962) 
    [java]  at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:631) 
    [java]  at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558) 
    [java]  at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2002) 
    [java]  at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:298) 
    [java]  at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242) 
    [java]  at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228) 
    [java]  at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:377) 
    [java]  at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:165) 
    [java]  at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:180) 
    [java]  at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:489) 
    [java]  at org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:80) 
    [java]  at org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:90) 
    [java]  at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:301) 
    [java]  at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58) 
    [java]  at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899) 
    [java]  at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:798) 
    [java]  at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108) 
    [java]  at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85) 
    [java]  at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896) 
    [java]  at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804) 
    [java]  at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1786) 
    [java]  at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1737) 
    [java]  at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:226) 
    [java]  at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:125) 
    [java]  at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:4207) 
    [java]  at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1441) 
    [java]  at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531) 
    [java]  at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277) 
    [java]  at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169) 
    [java]  at 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' for key 'UNQ_links_0' 
    [java]  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    [java]  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 
    [java]  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    [java]  at java.lang.reflect.Constructor.newInstance(Constructor.java:526) 
    [java]  at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) 
    [java]  at com.mysql.jdbc.Util.getInstance(Util.java:386) 
    [java]  at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1040) 
    [java]  at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4120) 
    [java]  at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052) 
    [java]  at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503) 
    [java]  at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664) 
    [java]  at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2794) 
    [java]  at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155) 
    [java]  at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458) 
    [java]  at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375) 
    [java]  at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359) 
    [java]  at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:890) 
    [java]  ... 34 more 
    [java] Java Result: 1 

BUILD SUCCESSFUL 
Total time: 6 seconds 
[email protected]:~/NetBeansProjects/RomeCNN$ 
[email protected]:~/NetBeansProjects/RomeCNN$ 

JpaController : 삽입은이 중 제약 조건 위반 또는 특정 URL에 분명히된다는 이유를 데이터베이스로 만들어 동안

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() { 
     return emf.createEntityManager(); 
    } 

    public void create(Link link) { 
     EntityManager em = null; 
     try { 
      em = getEntityManager(); 
      em.getTransaction().begin(); 
      em.persist(link); 
      em.getTransaction().commit(); 
     } finally { 
      if (em != null) { 
       em.close(); 
      } 
     } 
    } 

    public void edit(Link link) throws NonexistentEntityException, Exception { 
     EntityManager em = null; 
     try { 
      em = getEntityManager(); 
      em.getTransaction().begin(); 
      link = em.merge(link); 
      em.getTransaction().commit(); 
     } catch (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 with id " + id + " no longer exists."); 
       } 
      } 
      throw ex; 
     } finally { 
      if (em != null) { 
       em.close(); 
      } 
     } 
    } 

    public void destroy(Integer id) throws NonexistentEntityException { 
     EntityManager em = null; 
     try { 
      em = getEntityManager(); 
      em.getTransaction().begin(); 
      Link link; 
      try { 
       link = em.getReference(Link.class, id); 
       link.getId(); 
      } catch (EntityNotFoundException enfe) { 
       throw new NonexistentEntityException("The link with id " + id + " no longer exists.", enfe); 
      } 
      em.remove(link); 
      em.getTransaction().commit(); 
     } finally { 
      if (em != null) { 
       em.close(); 
      } 
     } 
    } 

    public List<Link> findLinkEntities() { 
     return findLinkEntities(true, -1, -1); 
    } 

    public List<Link> findLinkEntities(int maxResults, int firstResult) { 
     return findLinkEntities(false, maxResults, firstResult); 
    } 

    private List<Link> findLinkEntities(boolean all, int maxResults, int firstResult) { 
     EntityManager em = getEntityManager(); 
     try { 
      CriteriaQuery cq = em.getCriteriaBuilder().createQuery(); 
      cq.select(cq.from(Link.class)); 
      Query q = em.createQuery(cq); 
      if (!all) { 
       q.setMaxResults(maxResults); 
       q.setFirstResult(firstResult); 
      } 
      return q.getResultList(); 
     } finally { 
      em.close(); 
     } 
    } 

    public Link findLink(Integer id) { 
     EntityManager em = getEntityManager(); 
     try { 
      return em.find(Link.class, id); 
     } finally { 
      em.close(); 
     } 
    } 

    public int getLinkCount() { 
     EntityManager em = getEntityManager(); 
     try { 
      CriteriaQuery cq = em.getCriteriaBuilder().createQuery(); 
      Root<Link> rt = cq.from(Link.class); 
      cq.select(em.getCriteriaBuilder().count(rt)); 
      Query q = em.createQuery(cq); 
      return ((Long) q.getSingleResult()).intValue(); 
     } finally { 
      em.close(); 
     } 
    } 

} 

, 나에게 분명하지 않다.

persistence.xml 파일 : 나는 그렇게 같은 방법을 만들 업데이트

<?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> 

답변

1

가장 쉬운 방법은 먼저 링크가 데이터베이스에 있는지 확인한 다음 업데이트/건너 뛰기 또는 새 항목 삽입입니다. 이 같은 기본적으로 뭔가 :

em = getEntityManager(); 
Link existing = em.find(Link.class, link.getLink()); 
if (existing == null) { 
    em.getTransaction().begin(); 
    em.persist(link); 
    em.getTransaction().commit(); 
} 

것은이 어쩌면 더 강력한, 나는 고유 식별자로 SyndEntry.getUri() 값을 사용하는 것이 확인하십시오. 지금은 확인할 수 없지만, 나는 그것이 항목의 guid 요소에 매핑 확신 : 항목이되어있는 경우, 요소를 업데이트하도록 선택할 경우, pubDate 값을 확인하는 데 사용할 수 있습니다

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

마지막으로 저장 한 이후로 업데이트되었습니다.

RSS Duplicate Detection

이 주제에 대한 기계류 블로그 게시물입니다 (불행하게도 현재 archive.org를 통해 발견 만.)

당신이 RSS 2.0 specification, 당신은 <link><item>에서 생략 될 수 있음을 확인할 수 있습니다 읽으면 그래서도 할 수있다 명심하기 좋다.

0

: 터무니없는 것 같다

public void create(Link link) { 
    EntityManager em = null; 
    try { 
     em = getEntityManager(); 
     em.getTransaction().begin(); 
     em.persist(link); 
     em.getTransaction().commit(); 
    } catch (Exception e) { 
     log.fine(e.toString()); 
    } finally { 
     if (em != null) { 
      em.close(); 
     } 
    } 
} 

. 그러나 충돌없이 실행되는 것처럼 해결책이라고 생각합니다. 더 나은 솔루션을 환영합니다. 아마도 일반적인 접근법에 결함이있을 수 있습니다.

관련 문제