i m confronted with a problem of simultaneous using of EJB2.1 and EJB3.0 in one server application and i hope to find some help here.
currently i m migrating a complex application implemented with EJB2.1 to EJB3.0. the application consists of several moduls (about 120) that are packaged as JARs in one EAR. every modul contains a few SLSBs and EntityBeans (different layers for access, logic and data).
my problem appears in the situation when the data layer of an EJB3.0 module and the data layer of an EJB2.1 module are involved in one process (one process means one transaction for one client interaction).
a client starts a process on my server application by invoking a service of module "EJB3Module". in the first step of the process an Entity (EJB3.0) of type "EJB3Entity" is created and persisted. in the second step the primary key of this Entity (column "ID") is forwarded to the service of module "EJB21Module" that creates and persists an EntityBean (EJB2.1) of type "EJB21EntityBean". The EntityBean holds an reference to the Entity in column "EJB3Entity_ID", but the foreign key is only mapped by database and isnt mapped by JPA (EJB3.0) or CMP (EJB2.1).
the problem is, when the EntityBean of module "EJB3Module" gets persisted, an exception is thrown: "foreign key violation", because the value of column "EJB3Entity_ID" in table "EJB21EntityBean" is verified against column "ID" in table "EJB3Entity" and there is no such value.
i try to explain the reason of my problem. if i am wrong in some places, please let me know.
in my understanding, as the Entity is created by an EntityManager, it is registered in the persistence context, but not synchronized to database, because the transaction continues (JPA specification 3.2.3). later, when the EntityBean is being created CMP tries to write the EntityBean to database (because there is no persistence context in EJB2.1) and then database complains about foreign key, because the database doesnt know the Entity yet.
i successfully tried to explicitly flush the persistence context (EntityManager.flush()) to synchronize it to database after create, update and remove of an EJB3.0 Entity: the database then knows about the Entity and the EntityBean is created.
- are my assumptions correct and is this the expected behaviour?
- is there a way to set FlushModeType of EntityManager to something like always?
- if not, i guess i have to call EntityManager.flush() after every JPA action until i finally migrated all EJBs from EJB2.1 to EJB3.0. right?
- does it make sence to flush after every JPA action? or does it make even more sence to flush just before an EJB2.1 needs to read an EJB3.0 Entity?
i hope to have a discussion about my issue. please give me some input, hints and ideas, i m waiting for your answers.