I'm relatively new to EJB3 and am sort of stuck on the following issue :
I made a stateless session bean which has a method "createSomeEntity". I create an entity in this method with and assign a name to it (the entity has an id and a name). At the start of this method I want to check if an entity with the same name already exists in the database.
Now obviously this goes wrong as two seperate threads can both pass the isNameUnique check and both persist the new entity. The only way I can solve this at the moment is use @Column(unique=true). Is there a solution on an application level that doesn't first require both entities to be persisted? (So, a solution where I dont have to query for entities with that name, and if there are more than one em.remove the one I wanted to create. This also doesnt work since both threads can find themselves in this situation resulting on both entities removed).
I hope someone can give me some insight into this.
This is a non-trivial issue that has a number of possible solutions. For starters, the application should also check uniqueness ahead of time since its an easy check and prevents common errors. To guarantee uniqueness in a multi-threaded environment, you should probably add the database constraint on the value, thereby preventing two entities with the same value from ever existing.
As far as the more complicated case, where two threads are both competing for a value, you can try to balance it with proper transaction management, but that often involves locking an entire table (good bye to performance). I like the strategy of letting both proceed and rolling back on the one that fails (remember, the database uniqueness constraint will trigger an application exception). The case that this occurs is so rare, the user will just see a failure message (nicely displayed I hope, instead of a stack trace) and be asked to submit again. On the second time, they will get an error that the value is not unique since as first mention, you should check for uniqueness ahead of time anyway.