Unique Constraint violation in JPA in multiple threads
I am getting the following error when using JPA to create a record in my DataBase:
####<Oct 14, 2009 10:13:14 AM CDT> <Info> <EJB> <lharding-pc> <AdminServer> <[ACTIVE] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <BEA1-003262EA920A3057A4BD> <> <1255533194632> <BEA-010227> <EJB Exception occurred during invocation from home or business: weblogic.ejb.container.internal.StatelessEJBHomeImpl@589d49 threw exception: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 1.1.0.r3338-M8): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (BDSS.CONN_USER_DOMAIN_STATE_PK) violated
Error Code: 1
Call: INSERT INTO USER_CONTEXT_STATES (ID, TEMP_FLG, STATE_INDEX, LAST_SYNC_TS, USER_CONTEXT_ID) VALUES (?, ?, ?, ?, ?)
bind => [12701, T, null, null, 100003]
Query: InsertObjectQuery(oracle.bdss.datamodel.UserContextStates@a4af11)>
I am doing the work from an EJB on a Weblogic Server and I used the JDev 'Entities From Tables' wizard to generate the code for each table.
The code works correctly most of the time. However when there are multiple threads using the EJB, I think the sequence allocation gets the same set of IDs on different threads. The Session Cache for my persistance is set to 'Default(Soft Weak)'.
Has anyone seems this before and do you know a solution?
The following are the annotations that I am using for the PK generation to the ID column (where the unique constraint is violated):
@Id
@Column(nullable = false)
@TableGenerator(name = "UserContextStatesSeq", table = "SEQUENCE",
schema = "BDSS", pkColumnName = "SEQ_NAME",
valueColumnName = "SEQ_COUNT",
pkColumnValue = "BDSS.USER_CONTEXT_STATES", allocationSize=50)
@GeneratedValue(strategy = GenerationType.TABLE,
generator = "UserContextStatesSeq")
private Long id;
The code for the EJB is shown below (just the pertinent parts):
@Stateless(name = "RuntimeEJBBean")
@Local
public class RuntimeEJBBean
implements RuntimeEJBLocal
{
@PersistenceContext(unitName="persist")
private EntityManager em;
public RuntimeEJBBean()
{
}
private void createNewContextState()
throws Exception
{
UserContextStates newState = null;
try
{
newState = new UserContextStates();
em.persist(newState);
...
em.flush();
catch (Exception e)
{
...
}
}