I have an RCP client application that uses embedded Derby in the same JVM for persistence. I access it via JPA using RESOURCE_LOCAL and Eclipse Link as a JPA provider. I leave starting the Derby instance to JPA and persistence.xml.
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME, props);
Persistence.xml
<properties>
<property name="eclipse.weaving" value="false" />
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby:pathToDb" />
<property name="eclipselink.logging.level.sql" value="FINEST" />
<property name="eclipselink.logging.parameters" value="true" />
</properties>
At one point in the application, I need to stop the underlying Derby database. All of the examples show calling:
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
DriverManager.getConnection("jdbc:derby:pathToDb;shutdown=true");
This is problematic, especially in an RCP application with multiple class loaders (it uses OSGI under the covers). I have tried using
if (factory.isOpen())
factory.close();
but this does not shutdown the Derby instance, only the JPA connection to it.
Is there a way, using JPA, to shutdown the underlying Derby instance?
Update
I tried using the OSGI console to stop the persistence related bundles including javax.persistence, JPA and Derby. Stopping these did not release the file locks that Derby put on log files.
Update 2
Revised to clarify that the use is not in an OSGI server application.
The issue was not the classloader but an import issue.
An RCP application has a "target platform" that is dynamically searched by the framework for dependencies. This does not happen when calling Class.forName(). Once I explicitly added the Derby jar to my bundle's dependencies, the class was found and the database is shutting down properly.
Lesson learned: check the simple stuff before assuming it is hard!