Database is erased after deploying a new web application version

#1

Hello,

I'm a new ObjectDB user and currently working on a Java web application that's running within Tomcat and uses ObjectDB.

Each time I upload a new version of the web application (WAR file) and deploy it from Tomcat's manager, I get a new empty database.

I assume there is a way (possibly a simple one) of keeping the existing database and avoid this "database reset". If that's true, I'll be glad to hear about such a solution.

Thanks in advanced,

Yotam.

#2

Where is your database located (i.e. what is the path to the database file)?

If the database is located in a directory that is cleaned by the web server on every new deployment you should move it to another directory.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#3

Thanks for the quick reply.

I've moved the file to my root directory (and opened all permissions for it) but now there's a problem with accessing it:

When running a new web application version, I get an exception saying this file could not be opened (which createEntityManager throws).

It happens even when I first stop the current web application version and then deploy the new one. Something still keeps this file open and preventing the new web-app to use it.

The name of the process that uses the .odb file is "java" - not so informative (for me).

Shouldn't the file be closed automatically when I stop the server from Tomcat's manager?

When should I use the close method of EntityManagerFactory and EntityManager?

As long as the web-app is running, I have no intention of closing the connection to the database - only when deploying new versions.

#4

> When running a new web application version, I get an exception saying this file could not be opened (which createEntityManager throws).

Please post the full exception error message and stack trace.

> The name of the process that uses the .odb file is "java" - not so informative (for me).

Where do you see that process name? Is it listed on  the task manager process list? Do you have several such processes running concurrently?

> When should I use the close method of EntityManagerFactory and EntityManager?

You can close the EntityManagerFactory when the web application is closed (see this example).

Usually EntityManager instances are created and closed on every request (creating EntityManager instances is much faster than creating EntityManagerFactory instances).

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#5

> Please post the full exception error message and stack trace.

Failed to open file '/root/evee-database.odb' at com.webapp.firstwebapp.services.EventService.(EventService.java:17)
at com.webapp.firstwebapp.resources.EventResource.(EventResource.java:28)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe(ReflectionHelper.java:1129)
at org.jvnet.hk2.internal.ClazzCreator.createMe(ClazzCreator.java:274)
at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:368)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2064)
at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:711)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:653)
at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:169)
at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:185)
at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:92)
at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:61)
at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:295)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:286)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1072)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:399)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:412)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1385)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748

> Where do you see that process name? Is it listed on  the task manager process list? Do you have several such processes running concurrently?

I saw it when I ran "ps" command. Now I see it only when running the "fuser" command as follows:

[root@vmedu158 ~]# ps
  PID     TTY            TIME CMD
20256   pts/0    00:00:00 bash
20928   pts/0    00:00:00 ps
[root@vmedu158 ~]# fuser evee-database.odb
/root/evee-database.odb: 24450
[root@vmedu158 ~]# ps -p 24450
  PID     TTY           TIME CMD
24450     ?      00:07:21 java

I assume that if I'll back up the .odb file, delete it and then restore it will fix the issue of accessing the file from the new web-app version, but is there a more elegant way to do it?

#6

The stack trace indicates an exception that is thrown not directly by ObjectDB but on:

com.webapp.firstwebapp.resources.EventResource line 28

i.e. apparently by your own application.

This could be of course after catching an ObjectDB exception, but then please post the ObjectDB exception stack trace.

What is in line 28 at that class?

 

Please also verify that you close the EntityManagerFactory when the web application shuts down.

 

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#7

There's a static member in line 28, kind of a wrapper class to the database service class that does the queries.

It looks like the problem is fixed when I close the entityManagerFactory manually (using a dedicated http request) before stopping the web-app.

Trying to close the entityManager afterwards result in another exception, so I suppose closing the entityManagerFactory should be enough.

It might be out of this forum's scope, but is there a way of making sure this happens automatically when stopping the web-app from Tomcat's manager? Should I set some kind of listener?

#8

You can set a listener for creating and destroying the EntityManagerFactory:

http://www.objectdb.com/tutorial/jpa/eclipse/web/listener

When the application is stopped by the Tomcat manager the contextDestroyed method should be invoked.

On that example the listener is defined in a web.xml file (added automatically by Eclipse).

Alternatively the listener class can be annotated the with @WebListener annotation:

@WebListener
public class GuestListener implements ServletContextListener {
ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#9

I've added the listener class and modified my servlet class (which is a REST resource class in fact) according to the example in the provided link.

On runtime, the call getServletContext returns null, which result in a NullPointerException when calling getAttribute("emf").

What can I in order to make sure the servlet is configured properly (assuming this is the reason for the returning null)?

#10

> On runtime, the call getServletContext returns null, which result in a NullPointerException when calling getAttribute("emf").

Where exactly? Please follow the posting instructions and always include a full stack trace of the exception. In contextInitialized and contextDestroyed if invoked automatically as a listener event (and not by your own application) getServletContext should not return null.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#11

My bad. I've attached a file containing the full stack trace.

Just to clarify, my application does not invoke any of the methods mentioned.

java.lang.NullPointerException
 at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:123)
 at com.webapp.firstwebapp.services.DatabaseService.<init>(DatabaseService.java:36)
 at com.webapp.firstwebapp.interfaces.HasDB.<init>(HasDB.java:7)
 at com.webapp.firstwebapp.services.EventService.<init>(EventService.java:11)
 at com.webapp.firstwebapp.resources.EventResource.<clinit>(EventResource.java:31)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
 at java.lang.reflect.Constructor.newInstance(Unknown Source)
 at org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe(ReflectionHelper.java:1129)
 at org.jvnet.hk2.internal.ClazzCreator.createMe(ClazzCreator.java:274)
 at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:368)
 at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
 at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
 at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2064)
 at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:711)
 at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:653)
 at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:169)
 at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:185)
 at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
 at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109)
 at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
 at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
 at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
 at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:92)
 at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:61)
 at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
 at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:295)
 at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
 at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
 at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
 at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
 at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
 at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
 at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:286)
 at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1072)
 at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:399)
 at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
 at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
 at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
 at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
 at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
 at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:407)
 at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
 at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754)
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1376)
 at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
 at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
 at java.lang.Thread.run(Unknown Source)
#12

Is com.webapp.firstwebapp your package?

java.lang.NullPointerException
 at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:123)
 at com.webapp.firstwebapp.services.DatabaseService.<init>(DatabaseService.java:36)
 at com.webapp.firstwebapp.interfaces.HasDB.<init>(HasDB.java:7)
 at com.webapp.firstwebapp.services.EventService.<init>(EventService.java:11)
 at com.webapp.firstwebapp.resources.EventResource.<clinit>(EventResource.java:31)

The stack trace doesn't show invocation of getServletContext as shown in the provided link but deeper in your code, probably on an invalid event.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#13

I'm using 4 packages for this web application, each holds its relevant classes/interfaces:

com.webapp.firstwebapp.services
com.webapp.firstwebapp.interfaces
com.webapp.firstwebapp.model
com.webapp.firstwebapp.resources

The class called DatabaseService which extends HttpServlet is in the com.webapp.firstwebapp.services package.

I've created the listener class in the same package.

However, the servlet class (which eventually creates a static instance of DatabaseService is in the com.webapp.firstwebapp.resources package.

is this the reason why the listener methods hadn't been invoked?

Should the two be in one package for it to work properly?

 

#14

> Should the two be in one package for it to work properly?

That doesn't really matter.

> which eventually creates a static instance of DatabaseService

That may be the problem. The servlet context is available in specific listener and servlet methods only.

But this becomes a discussion about Java and Java web app rather than on ObjectDB...

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#15

Note that getServletContext is available only after the servlet init method is invoked (by the web server) and not in the servlet constructor (which of course is executed before the init method).

But again, this is not about ObjectDB but about how servlets work.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#16

I'll look into that, thank you for your comprehensive help, it's a fine product with a fine support.


Post Reply

To post a reply and/or subscribe to update notifications - please login