0

Here's a scenario I need to execute to throw the optimistic lock exception in case if something has changed underneath between the time I read from the DB and by the time I actually writes it back. I have a project that defines it's own persistence entities and unit. The EntityManager is defined with the extended persistence context. It define a bunch of persistent entities.

Now I have a dependency on some jar file and now this jar file also defines some persistence entities and it's own persistence unit(in persistence.xml file) and entityManager. The entityManager here also is defined with extended persistence context.

Both the persistence unit are pointing to the same database and same schema/library(DB2). THere are some persistent entities that are common between both the persistence units i.e. they refer to the same underlying table but since they are coming from two different jars they have a different name/package structure and a different set of keys defined as a composite primary key.

The scenario is and I need to read an entity from one of the entityManager and then write/update using the different entity manager. Since I am running this in a single transaction the persistence context propagates but since these are 2 different persistence units and each defines a different name/package structure for the same underlying table, even I read from one of them and try to save from the other, the second entity manager saves this as a new entity as if it doesn't exist in the table. So even if the data has changed for the same row in the DB between the time I read it from the first entity Manager and the time I try to write using different entity manager it doesn't throw the optimistic lock exception, it just saves it as it is.

I tried my best to explain the scenario but please don't hesitate to ask in case of query. Also, I believe if you have 2 different PU that defines persistent entity with different name for the same underlying table, you just cannot read from one em and have the other em know that since the underlying table is same, and since this row has been read by different em so let convert this entity the way that second PU defines it and when tries, the second em tries to compare the data in the table first if something has changed since the very first time the first em read from the same table and if something has changed then to throw the optimistic lock exception.

Barbareek
  • 52
  • 10
  • 1
    If they are different persistence units, they might as well be a different database (and really could be) as far as the application is concerned. I'm not sure why you would have a completely different entity over the same table in a different persistence unit - is there anyway to combine or reuse the persistence unit within the tooling, and just expand on it? This would avoid the duplicate reads that are going to be required to pull the same data into two different persistence units. As for reading from one and writing to the other - merge should figure out that it is an existing entity. – Chris Jul 12 '17 at 14:35
  • Thanks for the quick response @Chris - See, these 2 modules are managed by 2 different teams and merging the code is not possible as both are maintained by 2 different teams. Also, both the persistent unit are pointing to the SAME database. – Barbareek Jul 12 '17 at 15:34
  • understood, just pointing out your teams are duplicating the overhead at runtime - connections, statements etc. So focus on what is going wrong in your code - what do you mean exactly by 'it saves it as if it doesn't exist'? Is it doing an insert? What exactly are you calling? As for no optimistic lock - it would require both applications/persistence units to agree on using the same field for optimistic locking. You really need tighter integration for this to work, and seems you might be better off using their persistence classes and expanding on them than writing your own. – Chris Jul 12 '17 at 16:53
  • See both are independent modules and work independently (each persistence unit is part of their respective EAR project) – Barbareek Jul 14 '17 at 14:59
  • However, in one scenario one project just needs a persistence project(entities/em) from other project. So, the solution I am looking is to have the same entity manager injected at both the places i.e. in the EAR's own persistence project and also in the persistence project coming from a different module(part of different EAR project). I need to know how to tell at runtime what implementation of entity manager to use as I have 2 implementation of Entity Manager 1) That gets injected in the persistence project of the same EAR 2) Persistence project coming from a different EAR – Barbareek Jul 14 '17 at 15:00
  • If I am already having EM in my own project then whenever the code in persistence project(from different module) get's executed it should know that em already exist and to use the same em rather than creating a different em. something with the usage of @Alternative – Barbareek Jul 14 '17 at 15:00
  • You tell your application with persistence context to use by specifying the unitName : http://docs.oracle.com/javaee/6/api/javax/persistence/PersistenceContext.html – Chris Jul 14 '17 at 17:26

0 Answers0