Skip to Main Content

Java EE (Java Enterprise Edition) General Discussion

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Cannot insert duplicate key row in object

user9175643May 7 2008 — edited May 7 2008
This is a JPA question. The tbHardware table has a PK identity column and a unique non-clustered index on CoxBarcode column.

I have a SFSB in a Seam2.0.0.GA app running on JBoss 4.2.1.GA. I am using flushMode=FlushModeType.MANUAL (Seam specific when beginning a conversation) and that's why you see the flush() reference at the end of the following code snippet.
Query query = entityManager.createNativeQuery("INSERT INTO tbHardware "+
									"VALUES (:coxBarCode, :serialNo, :currentStatus, :currentLocationNo, "+
									":desc, :hardwareModelId, :ownerTypeCode, :firstEnteredDate, :enteredByUser, :lastAuditDate, :hardwarePrice, null)")
								  .setParameter("coxBarCode", coxBarcode)
								  .setParameter("serialNo", serialNo)
								  .setParameter("currentStatus", curstatus)
								  .setParameter("currentLocationNo", curloc)
								  .setParameter("desc", desc)
								  .setParameter("hardwareModelId", selmodid)
								  .setParameter("ownerTypeCode", selectedOwner)
								  .setParameter("firstEnteredDate", firstEnteredDate)
								  .setParameter("enteredByUser", enteredByUser)
								  .setParameter("lastAuditDate", lastAuditedDate)
								  .setParameter("hardwarePrice", unitPrice);
					
					query.executeUpdate();
					
					query = entityManager.createNativeQuery("INSERT INTO TbHardwareHistory "+
								"VALUES (:hardwareId, :currentStatus, :currentLocationNo, :firstEnteredDate, null, :enteredByUser, :ownerTypeCode)")
								 .setParameter("hardwareId", findHardwareId(coxBarcode))								 
								 .setParameter("currentStatus", curstatus)
								 .setParameter("currentLocationNo", curloc)		
								 .setParameter("firstEnteredDate", firstEnteredDate)
								 .setParameter("enteredByUser", enteredByUser)
								 .setParameter("ownerTypeCode", selectedOwner);
					
					query.executeUpdate();
					
					//TO DO: following query should return only one entity, need to refactor and remove the for loop below
					
					TbHardware hw = (TbHardware)entityManager.createNativeQuery("SELECT t FROM tbHardware t WHERE t.coxBarCode = :coxBarCode AND t.serialNo = :serialNo", TbHardware.class)
																.setParameter("coxBarCode", coxBarcode)
																.setParameter("serialNo", serialNo)
																.getSingleResult();
										
					Integer hardwareId = hw.getHardwareId();
										
					query = entityManager.createNativeQuery("INSERT INTO tbHardwareNote VALUES (:hardwareId, :hardwareNote)")
					  				.setParameter("hardwareId", hardwareId).setParameter("hardwareNote", hardwareNote);
		
					query.executeUpdate();
					
					entityManager.flush();
I am getting the following in the server.log:
10:10:57,552 ERROR [STDERR] Caused by: org.hibernate.exception.SQLGrammarException: could not execute native bulk manipulation query
10:10:57,552 ERROR [STDERR] 	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
10:10:57,552 ERROR [STDERR] 	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
10:10:57,552 ERROR [STDERR] 	at org.hibernate.engine.query.NativeSQLQueryPlan.performExecuteUpdate(NativeSQLQueryPlan.java:174)
10:10:57,552 ERROR [STDERR] 	at org.hibernate.impl.SessionImpl.executeNativeUpdate(SessionImpl.java:1163)
10:10:57,552 ERROR [STDERR] 	at org.hibernate.impl.SQLQueryImpl.executeUpdate(SQLQueryImpl.java:334)
10:10:57,552 ERROR [STDERR] 	at org.hibernate.ejb.QueryImpl.executeUpdate(QueryImpl.java:48)
10:10:57,552 ERROR [STDERR] 	... 138 more
10:10:57,552 ERROR [STDERR] Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Cannot insert duplicate key row in object 'dbo.tbHardware' with unique index 'IX_tbHardwar_coxBarCode_UNIQUE'.
10:10:57,552 ERROR [STDERR] 	at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(Unknown Source)
10:10:57,552 ERROR [STDERR] 	at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(Unknown Source)
10:10:57,552 ERROR [STDERR] 	at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(Unknown Source)
10:10:57,552 ERROR [STDERR] 	at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(Unknown Source)
10:10:57,552 ERROR [STDERR] 	at com.microsoft.sqlserver.jdbc.TDSCommand.execute(Unknown Source)
10:10:57,552 ERROR [STDERR] 	at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(Unknown Source)
10:10:57,552 ERROR [STDERR] 	at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(Unknown Source)
10:10:57,552 ERROR [STDERR] 	at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(Unknown Source)
10:10:57,552 ERROR [STDERR] 	at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(Unknown Source)
10:10:57,552 ERROR [STDERR] 	at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeUpdate(WrappedPreparedStatement.java:251)
10:10:57,552 ERROR [STDERR] 	at org.hibernate.engine.query.NativeSQLQueryPlan.performExecuteUpdate(NativeSQLQueryPlan.java:165)
10:10:57,552 ERROR [STDERR] 	... 141 more
How should I handle this SQLServerException? What is the best practice regarding this from a JPA perspective? I thought about executing a select query prior to the insert in tbHardware to check to see if a record with that particular coxBarCode exists or not. Would the exception be handled differently if I used the persist() method instead of the createNativeQuery() and executeUpdate() combination? thx.

Edited by: asookazian on May 7, 2008 11:07 AM
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jun 4 2008
Added on May 7 2008
0 comments
1,190 views