How to automatically create a database, schema, and table only if they do not already exist

I want to create a simple webapp that

  • allow remote clients to track some data in a send request.
  • save all tracking in a lightweight database
  • return all tracking for get

About the database, I would like

  • put your location in my webapp properties file (and use this location for hibernate.location.url set in persistence.xml file)
  • that the database is created using a schema and table, if they do not already exist.
  • use existing database and schema and table and data if they exist

So, I created a maven project with

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.my.tracker</groupId> <artifactId>tracker-webapp</artifactId> <version>0.1-SNAPSHOT</version> <packaging>war</packaging> <properties> <hibernate.version>4.3.8.Final</hibernate.version> <h2.version>1.4.185</h2.version> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-eclipse-plugin</artifactId> <version>2.9</version> <configuration> <downloadSources>true</downloadSources> <downloadJavadocs>false</downloadJavadocs> </configuration> </plugin> <!-- Set a compiler level --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> </plugin> </plugins> </build> <dependencies> <!-- Servlet API --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- JPA Provider (Hibernate) --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <!-- Database (H2) --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>${h2.version}</version> </dependency> </dependencies> </project> 

Src / main / resources / META-INF / persistence.xml

 <?xml version="1.0" encoding="UTF-8" ?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="thePersistenceUnit" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>org.my.tracker.Event</class> <properties> <property name="connection.driver_class" value="org.h2.Driver"/> <property name="hibernate.connection.url" value="jdbc:h2:./db/repository"/> <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/> <property name="hibernate.hbm2ddl.auto" value="create"/> <property name="hibernate.show_sql" value="true" /> </properties> </persistence-unit> </persistence> 

SRC / Main / WebApp / WEB-INF / web.xml

 <?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet> <servlet-name>orc-event</servlet-name> <servlet-class>org.my.tracker.EventServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>orc-event</servlet-name> <url-pattern>/event/*</url-pattern> </servlet-mapping> </web-app> 

Src / home / java / org / mine / tracker / EventServlet.java

 package org.my.tracker; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; public class EventServlet extends HttpServlet { private static final Logger LOGGER = LoggerFactory.getLogger(EventServlet.class); private static final long serialVersionUID = 1L; public static final String HTML_START="<html><body>"; public static final String HTML_END="</body></html>"; private static EntityManager manager; static { EntityManagerFactory factory = Persistence.createEntityManagerFactory("thePersistenceUnit"); manager = factory.createEntityManager(); } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); try { manager.getTransaction().begin(); @SuppressWarnings("unchecked") List<Event> events = manager.createQuery("from Event").getResultList(); Gson gson = new Gson(); out.print(gson.toJson(events)); manager.getTransaction().commit(); } catch (Exception e) { manager.getTransaction().rollback(); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String body = (String)request.getParameter("body"); if (null != body) { try { manager.getTransaction().begin(); Event event = new Event(); event.setBody(body); manager.persist(event); manager.getTransaction().commit(); } catch (Exception e) { manager.getTransaction().rollback(); } } else { LOGGER.error("null body, cannot track"); } } } 

Src / home / java / org / mine / tracker / Event.java

 package org.my.tracker; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Event { @Id @GeneratedValue private Integer id; private String body; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } } 

Well, thanks to all these powerful tools, it is simple and works pretty well, except that I couldn’t

  • See how to set my db location through a property (is it possible only through setting tomcat server.xml (which I cannot do for it doesn’t belong to me) or spring (which is a pretty weak reason to add several spring to my project for only 1 injection of properties ...),

  • (and 3.) every time I launch my webapp, my database is empty. Of course you will tell me since I put the "create" value in persistence.xml

      <property name="hibernate.hbm2ddl.auto" value="create"/> 

Well, I could put

  • create-drop: the same result as "create" in my case (which is expected, for "drop" means a lot like "keep everything on off": D)
  • none: but then the database is not created the first time you deploy webapp
  • validate: it’s good that I can restore my content when webapp reloads, but like no one, first, if it does not exist, the database schema and table are not created, and my webapp cannot work with it :)

So, I would like, if possible, to keep everything as simple as they are above, is this possible?

If there is no other way to write a sql script to initialize my db only if it does not exist, I would appreciate if you would give some code or some kind of hint, because I am not relevant in this field.

Edit

So, as I added one comment, actually the “update” is the value I was looking for. Work like a charm.

I did not find any other way than spring to pass variables instead of constant values. But, hey, this is quite common in such an area :) (and spring its orm layer too)

+5
source share
1 answer

JPA 2.1 provides standard properties for creating a schema. Find

 javax.persistence.schema-generation.database.action 

and set the value to create or drop-and-create . Similarly, there are properties for executing scripts when starting EMF. Documents for any compatible JPA implementation should document them

+2
source

All Articles