I have a collumn as unique=true.. in Exam class....
I found that because transactions are commited automaticaly so to force the commit i use
em.commit()
However i would like to know how to check if it is unique.Running a query isnt a solution because it may be an instert after checking because of the concurency....
Which is the best way to check for uniqness?
List<Exam_Normal> exam_normals = exam.getExam_Normal();
exam.setExam_Normal(null);
try {
em.persist(exam);
em.flush();
Long i = 0L;
if (exam_normals != null) {
for (Exam_Normal e_n : exam_normals) {
i++;
e_n.setItem(i);
e_n.setId(exam);
em.persist(e_n);
}
}
} catch (Exception e) {
System.out.print("sfalma--");
}
}
d
Unfortunately with JPA there is no way to avoid a transaction rollback upon a Unique Constraint violation as the specification requires this Exception to mark the transaction for rollback. Also, because the row may not exist when you issue the 'lock' call using JPA 2.0 APIs the 'lock' call will not ensure that only the locking thread can insert the object. A 'lock' would prevent the update of the Entity but not the insert.
You would need to perform the 'persist' as you have in your code but keep it as close to the beginning of the transaction as possible or have the operation occur in its own transaction.
If the 'persist' must be part of a larger transaction and the failure to persist does not preclude this part of your application from succeeding then you should store the Entity instances from this transaction and you will be able to 'merge' them into any subsequent transaction once your application recovers from the rollback.
However I would like to know how to check if it is unique. Running a query isn't a solution because it may be an insert after checking because of the concurrency....
JPA 2.0 permits pessimistic locking and adds three lock modes for that. This might be an option for your use case.
Some references:
- Locking and Concurrency in Java Persistence 2.0
- JPA 2.0 Concurrency and locking
- EclipseLink/Development/JPA 2.0/pessimistic locking
I assume that the column is not a primary key (@Id
) in which case your application have to guarantee uniqueness. Guarantee of Uniqueness of the field will probably have to come from elsewhere. What type of value is the field? Here are some ideas
If it is a counter then you can probably use @Singleton
stateful bean (JavaEE 6. See this.
If you are using EE5, then a stateless bean with an @Entity
that maps to a auto generated key.