JPA generating duplicate keys

做~自己de王妃 提交于 2019-12-24 10:58:26

问题


I have two entities defined as:

@Entity
public class FileMaster implements java.io.Serializable{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long fileId;

@NotNull
@Column(unique = true)
private String fileNumber = "";
private String subject = "";

@Temporal(TemporalType.DATE)
private Date date=null;
private String authPerson="";
private String authDesign="";
private String department="";


@OneToMany(mappedBy = "fileMaster", cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name="id") 
private Set<FileDetail> fileDetail = new HashSet<FileDetail>();

and second entity:

@Entity
public class FileDetail implements java.io.Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long pdfId;

//@NotNull
@Column(unique = true)
private String name;

//@NotNull
@ManyToOne 
private FileMaster fileMaster;

the following code simply tries to persist the two master-detail tables.. First insert goes well and it commits the record:

Set<FileDetail> pdfFileNames = newUpload.getPdfFileNames();
EntityManager em = Persistence.createEntityManagerFactory("fms")                
                        .createEntityManager();
em.getTransaction().begin();
FileMaster fileMaster = new FileMaster();

fileMaster.setFileNumber((String) editorForm.getField("fileNumber").getValue());
fileMaster.setSubject((String) editorForm.getField("subject").getValue());
fileMaster.setAuthDesign((String) 
editorForm.getField("authDesign").getValue());
fileMaster.setAuthPerson((String) editorForm.getField("authPerson").getValue());
fileMaster.setDate((Date) editorForm.getField("date").getValue());
fileMaster.setFileDetail(pdfFileNames);
em.persist(fileMaster);

Iterator<FileDetail> iter = pdfFileNames.iterator();

while(iter.hasNext()) {
    FileDetail fileDetail = iter.next();        
    fileDetail.setName(fileDetail.getName());
    fileDetail.setFileMaster(fileMaster);
    em.persist(fileDetail);     
    }           
em.getTransaction().commit();    
em.close();

When I try to insert the second record.... It gives me PSQLException. Since Iam new to JPA... BTW Iam using Eclipselink and PostgreSQL with JPA....Iam finding it hard to resolve this issue. Could anyone please help me over this issue... let me paste the traces as well...

 May 27, 2012 10:08:02 AM com.vaadin.Application terminalError
 SEVERE: Terminal error:
 com.vaadin.event.ListenerMethod$MethodException
 Cause: javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse                          Services - 2.2.0.v20110202-r8913):      org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value     violates unique constraint "filedetail_pkey"
Detail: Key (pdfid)=(306) already exists.
Error Code: 0
Call: INSERT INTO FILEDETAIL (PDFID, NAME, FILEMASTER_FILEID) VALUES (?, ?, ?)
bind => [306, Manning Java Persistence with Hibernate 2nd.pdf, 3]
Query: InsertObjectQuery(Manning Java Persistence with Hibernate 2nd.pdf)
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:532)
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:164)
at com.vaadin.ui.AbstractComponent.fireEvent(AbstractComponent.java:1219)
at com.vaadin.ui.Button.fireClick(Button.java:550)
at com.vaadin.ui.Button.changeVariables(Button.java:217)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.changeVariables(AbstractCommunicationManager.java:1451)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariableBurst(AbstractCommunicationManager.java:1399)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariables(AbstractCommunicationManager.java:1318)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.doHandleUidlRequest(AbstractCommunicationManager.java:763)
at com.vaadin.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:296)
at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:598)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:486)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:233)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1065)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:413)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:192)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:999)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:250)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111)
at org.eclipse.jetty.server.Server.handle(Server.java:350)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:454)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:900)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:954)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:851)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:606)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:46)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse        Persistence Services - 2.2.0.v20110202-r8913):    org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value  violates unique constraint "filedetail_pkey"
Detail: Key (pdfid)=(306) already exists.
Error Code: 0
Call: INSERT INTO FILEDETAIL (PDFID, NAME, FILEMASTER_FILEID) VALUES (?, ?, ?)
bind => [306, Manning Java Persistence with Hibernate 2nd.pdf, 3]
Query: InsertObjectQuery(Manning Java Persistence with Hibernate 2nd.pdf)
at    org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(Entit yTransactionImpl.java:102)
at  org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransac tionImpl.java:63)
at com.complete.raspberry.webui.PersonEditor.save(PersonEditor.java:178)
at com.complete.raspberry.webui.PersonEditor.buttonClick(PersonEditor.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:512)
... 36 more
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services -  2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException

回答1:


You should use GenerationType.IDENTITY to generate pdfid using auto increment instead of GenerationType.AUTO for FileDetail entity.

@Entity
public class FileDetail implements java.io.Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long pdfId;
}

GenerationType.IDENTITY

Indicates that the persistence provider must assign primary keys for the entity using a database identity column.




回答2:


Try setting logging on finest to see what is occurring.

Where does pdfFileNames come from? Are this existing objects, with existing ids? If they are existing, you should either be find/merging them, or create new ones with null ids. Ensure they do not have existing ids when you call persist.

If using SEQUENCE also ensure your increment matches your allocation size (default is 50).



来源:https://stackoverflow.com/questions/10771903/jpa-generating-duplicate-keys

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!