2

I am using EclipseLink 2.4.2 (in combination with Spring, but I don't think it has anything to do with our issue here) and we had a few times the following exception:

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.2.v20130514-5956486): org.eclipse.persistence.exceptions.DatabaseException

Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-00001 : unique constraint (****.PK_*****) violated

Our primary keys are generated by EclipseLink which uses an Oracle sequence to allocate them. I double checked, and the allocationSize matches exactly the increment by defined on the sequence.

Here is an example of how this sequence is defined in our Java class:

@Id
@SequenceGenerator(name = "SOME_GENERATOR", sequenceName = "SOME_SEQ", allocationSize = 10000, initialValue = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SOME_GENERATOR")
@Column(name = "ID")
private Long id;

Here is the sequence creation SQL-statement:

CREATE SEQUENCE SOME_SEQ INCREMENT BY 10000 START WITH 10000;

Of course, the problem is hardly reproduceable and only happens randomly. It seems to happen more often when the server is under heavy load.

I don't know if this is relevant, but here are some extra infos:

  • We have two servers accessing the same database
  • The primary key definition is inherited by many classes

My first thinking would be that this is related to concurrency, but it would seem like a rather severe issue for such a mature framework. Any other thing I should verify or that I could have overlooked?

I have looked at related posts such as theses ones:

but they don't seem to help in my case.

Community
  • 1
  • 1
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • Are you able to determine the value used for the failing statements, and the value of the sequence in the database? – Chris Oct 22 '14 at 12:44
  • @Chris unfortunately not. Those errors only happens when we run automated tests ran in parallel. SQL parameters logging is disabled. I am not sure that getting those values would help me finding the problem anyway. But if you have a lead on how I could trace back an error (in my code or in EL) from those values, I am very interested. – Guillaume Polet Oct 22 '14 at 13:02
  • Nothing specific, just reaching out for any information that can help figure out what is special about the two processes using the same number and how they got it – Chris Oct 22 '14 at 18:12
  • @Chris We actually managed to spot how the error occured. The problem came from bad combination of "Reset of DB" and EclipseLink pre-allocated id's. – Guillaume Polet Oct 23 '14 at 19:41

1 Answers1

2

We eventually found an explanation to this issue.

The actual problem came from the fact that the database was reset (so drop tables and sequences, then re-initialize everything), but the application server wasn't.

  • So in the beginning, EclipseLink was still allocating id's from the previous pre-allocated queue (e.g, [100016,100017,100018,100019,100020]].
  • Then when it hit the end of it, it restarted from the initial value ([1,2,3,4,5,...]).
  • After a while, EclipseLink reached ids that had already been allocated and hence we were hitting this Primary Key constraint violation.

Since the ids are used by multiple entities, the behaviour was rather random and collisions were actually not likely to occur.

Developers and testers will now always restart application server after a reset of the DB.

Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117