You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Andrew Thompson <at...@columbia.edu> on 2009/05/25 20:49:55 UTC
Trouble with TableGenerated @Id's the first time an object type is
loaded.
Hello Folks,
I've been banging my head on this for a few days and not coming up with
much. Tips on where to look / debug would be much appreciated.
Problem Summary:
For entity beans using @TableGenerator and @GeneratedValue to generate
primary key values, we consistently get a duplicate key row error when
invoking save for the first time on an object of a given type. By that
I mean, it only seems to fail when a request to the TableGenerator is
required. Subsequent GeneratedValue invocations work fine, presumably
because the next value to be used for that primary key is in memory?
Environment:
Database: We use sybase 12.5. Note, we extended an sybase dictionary to
do some things like trim strings.
JDBC Driver: we use the jconnect2 jdbc
com.sybase.jdbc2.jdbc.SybConnectionPoolDataSource driver managed by dbcp
pooledconnection.
Servlet Container: Tomcat.
Spring: we use spring's localcontainerentitymanager and inject pretty
much everything through spring. configuration/datasource etc...
Openjpa Configuration:
<entry key="openjpa.jdbc.DBDictionary"
value="org.apache.openjpa.jdbc.sql.ExtendedSybaseDictionary(schemaCase=preserve,createIdentityColumn=false,setStringRightTruncationOn=false)"
/>
<entry key="openjpa.DataCache" value="true(EvictionSchedule='30 22 * *
1')"/>
<entry key="openjpa.QueryCache" value="CacheSize=1000,
SoftReferenceSize=100"/>
<entrykey="openjpa.RemoteCommitProvider" value="sjvm"/>
<entry key="openjpa.jdbc.TransactionIsolation"
value="read-uncommitted"/>
<entry key="openjpa.InverseManager" value="true"/>
<entry key="openjpa.jdbc.SchemaFactory"
value="native(ForeignKeys=true)"/>
Sample Code below:
package edu.columbia.rascal.domain;
import org.apache.commons.lang.builder.ToStringBuilder;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;
/**
* Question entity.
*
* @author $author$
* @version $Revision$, $Date$
*/
@Entity @Table(
name = "Question",
uniqueConstraints =
@UniqueConstraint(columnNames = { "questionNumber",
"ProtocolHeaderPer_oid" })
)
@TableGenerator(
name = "generateQuestionPrimaryKey",
table = "OBJECT_NUMERATORS",
pkColumnName = "ObjectName",
valueColumnName = "LastId",
pkColumnValue = "Question"
)
public class Question implements java.io.Serializable {
//~ Static fields/initializers
-----------------------------------------------------------------
/** Use serialVersionUID for interoperability. */
private static final long serialVersionUID = -8831312774834280328L;
//~ Instance fields
----------------------------------------------------------------------------
private String answerRequired;
private String answerText;
private ProtocolHeader ProtocolHeader;
private Date meetingDate;
// Fields
private Long oid;
private String questionNumber;
//~ Constructors
-------------------------------------------------------------------------------
/** Constructors * default constructor. */
public Question() { }
/**
* minimal constructor.
*
* @param oid TODO: DOCUMENT ME!
* @param protocolHeader TODO: DOCUMENT ME!
*/
public Question(Long oid, ProtocolHeader protocolHeader) {
this.oid = oid;
this.ProtocolHeader = ProtocolHeader;
}
/**
* full constructor.
*
* @param oid TODO: DOCUMENT ME!
* @param ProtocolHeader TODO: DOCUMENT ME!
* @param answerRequired TODO: DOCUMENT ME!
* @param answerText TODO: DOCUMENT ME!
* @param questionNumber TODO: DOCUMENT ME!
* @param meetingDate TODO: DOCUMENT ME!
*/
public Question(Long oid, ProtocolHeader ProtocolHeader, String
answerRequired,
String answerText, String questionNumber, Date meetingDate
) {
this.oid = oid;
this.ProtocolHeader = ProtocolHeader;
this.answerRequired = answerRequired;
this.answerText = answerText;
this.questionNumber = questionNumber;
this.meetingDate = meetingDate;
}
//~ Methods
------------------------------------------------------------------------------------
/**
* TODO: DOCUMENT ME!
*
* @return TODO: DOCUMENT ME!
*/
@Column(
insertable = true,
updatable = true,
name = "answerRequired",
length = 1
)
public String getAnswerRequired() {
return this.answerRequired;
}
/**
* TODO: DOCUMENT ME!
*
* @return TODO: DOCUMENT ME!
*/
@Column(
insertable = true,
updatable = true,
name = "answerText"
)
public String getAnswerText() {
return this.answerText;
}
/**
* TODO: DOCUMENT ME!
*
* @return TODO: DOCUMENT ME!
*/
@JoinColumn(
name = "ProtocolHeaderPer_oid",
nullable = false
)
@ManyToOne(fetch = FetchType.LAZY)
public ProtocolHeader getProtocolHeader() {
return this.ProtocolHeader;
}
/**
* TODO: DOCUMENT ME!
*
* @return TODO: DOCUMENT ME!
*/
@Column(
insertable = true,
updatable = true,
name = "meetingDate",
length = 23
)
@Temporal(TemporalType.TIMESTAMP)
public Date getMeetingDate() {
return this.meetingDate;
}
/**
* Property accessors.
*
* @return TODO: DOCUMENT ME!
*/
@Column(
insertable = true,
updatable = true,
name = "oid",
unique = true,
nullable = false,
precision = 26,
scale = 0
)
@GeneratedValue(
strategy = GenerationType.TABLE,
generator = "generateQuestionPrimaryKey"
)
@Id public Long getOid() {
return this.oid;
}
/**
* TODO: DOCUMENT ME!
*
* @return TODO: DOCUMENT ME!
*/
@Column(
insertable = true,
updatable = true,
name = "questionNumber",
length = 4
)
public String getQuestionNumber() {
return this.questionNumber;
}
/**
* TODO: DOCUMENT ME!
*
* @param answerRequired TODO: DOCUMENT ME!
*/
public void setAnswerRequired(String answerRequired) {
this.answerRequired = answerRequired;
}
/**
* TODO: DOCUMENT ME!
*
* @param answerText TODO: DOCUMENT ME!
*/
public void setAnswerText(String answerText) {
this.answerText = answerText;
}
/**
* TODO: DOCUMENT ME!
*
* @param ProtocolHeader TODO: DOCUMENT ME!
*/
public void setProtocolHeader(ProtocolHeader ProtocolHeader) {
this.ProtocolHeader = ProtocolHeader;
}
/**
* TODO: DOCUMENT ME!
*
* @param meetingDate TODO: DOCUMENT ME!
*/
public void setMeetingDate(Date meetingDate) {
this.meetingDate = meetingDate;
}
/**
* TODO: DOCUMENT ME!
*
* @param oid TODO: DOCUMENT ME!
*/
public void setOid(Long oid) {
this.oid = oid;
}
/**
* TODO: DOCUMENT ME!
*
* @param questionNumber TODO: DOCUMENT ME!
*/
public void setQuestionNumber(String questionNumber) {
this.questionNumber = questionNumber;
}
/** @see java.lang.Object#toString() */
@Override public String toString() {
return new ToStringBuilder(this).append("oid", oid).append(
"answerRequired", answerRequired
).append("answerText",
answerText).append("questionNumber",
questionNumber
).append("meetingDate", meetingDate).toString();
}
}
______________________________________________
StackTrace:
Caused by:
<openjpa-1.2.1-r752877:753278 nonfatal general error>
org.apache.openjpa.persistence.PersistenceException: Attempt to insert
duplicate key row in object 'Question' wit
h unique index 'Question_18534058221'
{prepstmnt 1238649300 INSERT INTO dbo.Question (oid, answerRequired,
answerText, questionNumber, ProtocolHeaderPer_oid, meetingDate) VALUES
(?, ?, ?, ?, ?, ?) [p
arams=(long) 18444, (String) Y, (String) q1, (String) q1, (long) 17739,
(null) null]} [code=2601, state=23000]
FailedObject: edu.columbia.rascal.domain.Question@689d689d
at
org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4232)
at
org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4197)
at
org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:102)
at
org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:72)
at
org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:131)
at
org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.flushAndUpdate(BatchingPreparedStatementManagerImpl.java:82)
at
org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushInternal(PreparedStatementManagerImpl.java:89)
at
org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flush(PreparedStatementManagerImpl.java:72)
at
org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:543)
at
org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:105)
at
org.apache.openjpa.jdbc.kernel.BatchingConstraintUpdateManager.flush(BatchingConstraintUpdateManager.java:59)
at
org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:89)
at
org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:72)
at
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:717)
at
org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130)
at
org.apache.openjpa.datacache.DataCacheStoreManager.flush(DataCacheStoreManager.java:562)
at
org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130)
... 54 more
Caused by:
org.apache.openjpa.lib.jdbc.ReportingSQLException: Attempt to insert
duplicate key row in object 'Question' with unique index
'Quest_18534058221'
{prepstmnt 1238649300 INSERT INTO dbo.Question (oid, answerRequired,
answerText, questionNumber, ProtocolHeaderPer_oid, meetingDate) VALUES
(?, ?, ?, ?, ?, ?) [p
arams=(long) 18444, (String) Y, (String) q1, (String) q1, (long) 17739,
(null) null]} [code=2601, state=23000]
at
org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:192)
at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access
$700(LoggingConnectionDecorator.java:57)
at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator
$LoggingConnection
$LoggingPreparedStatement.executeUpdate(LoggingConnectionDecorator.java:866)
at
org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:269)
at org.apache.openjpa.jdbc.kernel.JDBCStoreManager
$CancelPreparedStatement.executeUpdate(JDBCStoreManager.java:1586)
at
org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.executeUpdate(PreparedStatementManagerImpl.java:151)
at
org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:120)
... 66 more