| Re: [eclipselink-users] PersistenceProvider.createEntityManagerFactory() not work correctly when emSetupImpl.isUndeployed() returns true |
Please log a bug. Thanks a lot for finding the bug and suggesting the right solution, Andrei
Hello Tom,
I received following Exception: Exception Description: Unable to predeploy PersistenceUnit [fooPU] in invalid state [Undeployed] at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1101) at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:131) at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source) at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source) at my.source.MyMethod()
I think that the original intention is made so that a UNDEPLOYED state may be followed by the Line.133 . But emSetupImpl.predeploy() is throw Exception when emSetupImpl.isUndeployed()==true, and createEMF() is has passed while checking on Line.126 . When I call EntityManager.close() from another thread between PersistenceProvider.createEntityManagerFactory():Line.95 and Line.125, this problem reappears.
Thread A EMF Thread B | | createEMF----->- | | | | | |<------createEMF()Line.95-111 EMF.close()--->- | x<------createEMF()Line.125-131
I know that it should call EntityManager.close() at the end of the application, I could not but do like this this time.
Thanks.
What is the PersistenceException you see?
On 13/12/2012 1:52 AM, TH wrote:Hello all,
I am using EclipseLink 2.3.2. When I call PersistenceProvider.createEntityManagerFactory(), A PersistenceException occurs rarely.
I think that there is a problem in the following parts. in PersistenceProvider.createEntityManagerFactory(): [Line.123 of eclipselink-src-2.3.2.v20111125-r10461] [Line.123 of eclipselink-src-2.3.3.v20120629-r11760] [Line.123 of eclipselink-src-2.4.0.v20120608-r11652]
// synchronized to prevent undeploying by other threads. boolean undeployed = false; synchronized(emSetupImpl) { if(emSetupImpl.isUndeployed()) { undeployed = true; } // emSetupImpl has been already predeployed, predeploy will just increment factoryCount. emSetupImpl.predeploy(emSetupImpl.getPersistenceUnitInfo(), nonNullProperties); } if(undeployed) { // after the emSetupImpl has been obtained from emSetupImpls // it has been undeployed by factory.close() in another thread - start all over again. return createEntityManagerFactory(emName, properties); }
I think if emSetupImpl.isUndeployed() is true, do not call emSetupImpl.predeploy(). Considering processing UNDEPLOYED in the part under it, I think that it should become the following code:
synchronized(emSetupImpl) { if(emSetupImpl.isUndeployed()) { undeployed = true; } else { // emSetupImpl has been already predeployed, predeploy will just increment factoryCount. emSetupImpl.predeploy(emSetupImpl.getPersistenceUnitInfo(), nonNullProperties); } }
What do you think? Thanks.
P.S: Sorry for my bad English.
_______________________________________________ eclipselink-users mailing list eclipselink-users@xxxxxxxxxxx https://dev.eclipse.org/mailman/listinfo/eclipselink-users
_______________________________________________ eclipselink-users mailing list eclipselink-users@xxxxxxxxxxx https://dev.eclipse.org/mailman/listinfo/eclipselink-users