2015-08-08 14 views
5

voglio creare un semplice webapp cheCome auto-creare il database, lo schema e la tabella solo se non esistono già

  • consentire ai client remoti per monitorare alcuni contenuti su una richiesta POST
  • persistono tutto il tracking in un database leggero
  • restituire tutto il tracciamento di una richiesta gET

Informazioni sul database, vorrei

  1. messo la sua posizione all'interno di un file delle proprietà della mia webapp (e utilizzare questa posizione per hibernate.location.url impostato in persistence.xml)
  2. che il database viene creato con lo schema e la tabella se non esistono ancora
  3. utilizzare il database esistente e lo schema e la tabella dei dati e se esistono

così ho creato un progetto Maven con:

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/main/java/org/my/inseguitore/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/main/java/org/mio/inseguitore/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; 
    } 

} 

Bene, grazie a tutti questi potenti strumenti, questo è semplice e funziona abbastanza bene, solo che non ho potuto

  1. vedere come impostare la mia posizione db attraverso una proprietà (è possibile solo attraverso tomcat server.xml tune (che non posso fare perché non appartiene a me) o spring (che è un motivo abbastanza debole per mettere un po 'di primavera nel mio progetto solo per 1 iniezione di proprietà ...),

  2. (e 3.) ogni volta che lancio la mia webapp, il mio database è vuoto. Certo, me lo dirai, dal momento che ho messo il valore "crea" nella persistenza.xml

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

Beh, ho potuto mettere

  • creare-drop: stesso risultato di "creare" nel mio caso (che è una specie di attesa, per "cadere" vuol dire un sacco come l'opposto di "keep everything at shutdown": D)
  • none: ma il database non viene creato la prima volta che la webapp non viene distribuita
  • validate: beh, posso ripristinare i miei contenuti al riavvio webapp, ma come nessuno, a prima se non esiste, lo schema e la tabella del database non vengono creati e la mia webapp non può funzionare :)

Quindi, se possibile, mantenere le cose semplici come sopra, è possibile?

Se non c'è altro modo di scrivere uno script sql per inizializzare il mio db solo se non esiste, mi farebbe piacere che tu fornissi il codice o alcuni suggerimenti, perché sono completamente stupido in questo campo.

Modifica

Così come ho messo in un commento, in realtà, "update" è il valore che cercavo. Lavora come un fascino.

Non ho trovato alcun modo diverso da molla per passare variabili anziché valori costanti. Ma hey è abbastanza comune in questo campo comunque :) (e molla anche il suo strato di orm)

risposta

2

JPA 2.1 fornisce le proprietà standard per la creazione dello schema. Cercare

javax.persistence.schema-generation.database.action 

e impostare a create o drop-and-create. Allo stesso modo ci sono proprietà per l'esecuzione di script all'avvio di un EMF. Documenti per qualsiasi implementazione JPA compatibile dovrebbero documentarli

+2

Se sostituisco per fallisce al secondo avvio perché tenta di creare la TABELLA EVENTI anche se esiste già. se imposto drop-and-create, cancella la TABLE esistente e perdo gli eventi persistenti già esistenti. – Zzirconium

+1

, ed è ciò che dovrebbero fare "creare" e "drop-and-create". Se vuoi fare altre cose, usi l'opzione degli script. Sarebbe stato bello se le persone con specifiche JPA avessero permesso anche le opzioni "validate" e "validate-and-create". Non so se il tuo provider JPA ha quelli, quello che uso ha un'opzione valida –

+0

Grazie per il tuo aggiornamento. In realtà, lo script di scrittura dovrà entrare nello schema esplicito e nella creazione di tabelle. Non c'è modo di mantenere il database automatico popolato, ma con un semplice comportamento di aggiornamento anziché "usa solo esistente" (che fallisce la prima volta) o "cancella tutto" (che cancella tutto e perde l'intera utilità di persistenza del database ...) – Zzirconium

Problemi correlati