2008-11-18 10 views
40

Estoy usando JPA (implementación de Hibernate) para anotar clases de entidad para que persistan en una base de datos relacional (MySQL o SQL Server). ¿Existe alguna manera fácil de generar automáticamente el esquema de la base de datos (scripts de creación de tablas) a partir de las clases anotadas?Auto generar esquema de datos de clases de entidad anotadas JPA

Todavía estoy en la fase de creación de prototipos y anticipo los frecuentes cambios de esquema. Me gustaría poder especificar y cambiar el modelo de datos del código anotado. Grails es similar en cuanto genera la base de datos de las clases de dominio.

+0

Revisa http://stackoverflow.com/questions/779479/reverse-engineer-ddl-from-jpa-entities –

Respuesta

13

Puede usar hbm2ddl de Hibernate. Los documentos son here.

+9

Preguntó acerca de generar los esquemas únicamente a partir de las clases anotadas. Mi equipo quiere hacer lo mismo. Creo que hbm2dll solo funciona con los archivos de mapeo .hbm.xml que mi equipo no quiere usar. No creo que el OP lo haga tampoco. – Omniwombat

+1

Según "Manning Java Persistence with Hibernate", sí puede hacerlo con hbm2ddl: "El requisito previo en Hibernate para la generación automática de SQL DDL es siempre una definición de metadatos de mapeo de Hibernate, ya sea en archivos de mapeo XML o en anotaciones de código fuente Java". – dendini

9

Como nota relacionada: Se puede encontrar la documentación para generar esquemas de base de datos que utilizan EclipseLink JPA here.

+0

Gracias por eso. Mi pregunta fue respondida en el primer hit de Google gracias a ti. – AlanObject

13

generar crear y soltar guión de entidades JPA dados

Utilizamos este código para generar la caída y crear declaraciones: Sólo construir esta clase con todas las clases de entidad y llame a crear/dropTableScript.

Si es necesario, puede usar un nombre persitence.xml y persitance unit en su lugar. Solo di algo y publico el código también.

import java.util.Collection; 
import java.util.Properties; 

import org.hibernate.cfg.AnnotationConfiguration; 
import org.hibernate.dialect.Dialect; 
import org.hibernate.ejb.Ejb3Configuration; 

/** 
* SQL Creator for Tables according to JPA/Hibernate annotations. 
* 
* Use: 
* 
* {@link #createTablesScript()} To create the table creationg script 
* 
* {@link #dropTablesScript()} to create the table destruction script 
* 
*/ 
public class SqlTableCreator { 

    private final AnnotationConfiguration hibernateConfiguration; 
    private final Properties dialectProps; 

    public SqlTableCreator(final Collection<Class<?>> entities) { 

     final Ejb3Configuration ejb3Configuration = new Ejb3Configuration(); 
     for (final Class<?> entity : entities) { 
      ejb3Configuration.addAnnotatedClass(entity); 
     } 

     dialectProps = new Properties(); 
     dialectProps.put("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect"); 

     hibernateConfiguration = ejb3Configuration.getHibernateConfiguration(); 
    } 

    /** 
    * Create the SQL script to create all tables. 
    * 
    * @return A {@link String} representing the SQL script. 
    */ 
    public String createTablesScript() { 
     final StringBuilder script = new StringBuilder(); 

     final String[] creationScript = hibernateConfiguration.generateSchemaCreationScript(Dialect 
       .getDialect(dialectProps)); 
     for (final String string : creationScript) { 
      script.append(string).append(";\n"); 
     } 
     script.append("\ngo\n\n"); 

     return script.toString(); 
    } 

    /** 
    * Create the SQL script to drop all tables. 
    * 
    * @return A {@link String} representing the SQL script. 
    */ 
    public String dropTablesScript() { 
     final StringBuilder script = new StringBuilder(); 

     final String[] creationScript = hibernateConfiguration.generateDropSchemaScript(Dialect 
       .getDialect(dialectProps)); 
     for (final String string : creationScript) { 
      script.append(string).append(";\n"); 
     } 
     script.append("\ngo\n\n"); 

     return script.toString(); 
    } 
} 
+0

¡Muy buena solución! Pero usar directamente persistence.xml sería mucho más cómodo para nosotros. ¿Podría publicar el código con persistence.xml? ¡Gracias por adelantado! –

+0

Esta línea: public SqlTableCreator (colección final> entidades) debe ser la colección final entidades – r590

+0

@ r590 el bloque de código tenía algunos problemas en el formateo, pero la fuente era correcta. Puse una edición. – Mindwin

2

Si prefiere la configuración en la primavera, esto debería ser útil:

<!-- CONTAINER-MANAGED JPA Entity manager factory (No need for persistence.xml)--> 
    <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/> 
    <!-- Fine Grained JPA properties Create-Drop Records --> 
    <property name="jpaProperties"> 
    <props> 
    <prop key="hibernate.hbm2ddl.auto">create</prop> 
    </props> 
    </property> 
    </bean> 
    <!-- The JPA vendor --> 
    <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
    <!-- <property name="database" value="MySQL"/> --> 
    <property name="showSql" value="true"/> 
    <!-- <property name="generateDdl" value="true"/> --> 
    <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>  
    </bean> 
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="emf" /> 
    </bean> 
2

Usted puede utilizar el plugin de Maven para lograrlo.

 <plugin> 
      <!-- run command "mvn hibernate3:hbm2ddl" to generate DLL --> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>hibernate3-maven-plugin</artifactId> 
      <version>3.0</version> 
      <configuration> 
       <hibernatetool> 
        <classpath> 
         <path location="${project.build.directory}/classes" /> 
         <path location="${project.basedir}/src/main/resources/META-INF/" />            
        </classpath> 

        <jpaconfiguration persistenceunit="galleryPersistenceUnit" />      
        <hbm2ddl create="true" export="false" destdir="${project.basedir}/target" drop="true" outputfilename="mysql.sql" format="true" console="true"/> 
       </hibernatetool> 
      </configuration> 
     </plugin> 
1
<property name="hibernate.hbm2ddl.auto" value="update"/> 

Añadir el código anterior en el persistence.xml en las propiedades de la etiqueta. "actualización" creará la tabla la primera vez que ejecute su código, después de eso, solo actualice las estructuras de la tabla si hay algún cambio en el objeto de dominio.

7

Como Hibernate 4.3 + 2.1 implementa ahora JPA la forma adecuada para generar scripts DDL es utilizar siguiente conjunto de JPA 2.1 Propiedades:

<property name="javax.persistence.schema-generation.scripts.action" value="create"/> 
<property name="javax.persistence.schema-generation.create-source" value="metadata"/> 
<property name="javax.persistence.schema-generation.scripts.create-target" value="target/jpa/sql/create-schema.sql"/> 

A medida que se llevará a cabo en tiempo de ejecución, es posible que desee ejecutar este Generación de DDL en la construcción. Ya no hay un complemento maven oficial compatible para Hibernate4 probablemente porque el equipo de Hibernate se está mudando a Gradle.

De todos modos, este es el enfoque de la APP 2.1 para generar esta secuencia de comandos mediante programación:

import java.io.IOException; 
import java.util.Properties; 

import javax.persistence.Persistence; 

import org.hibernate.jpa.AvailableSettings; 

public class JpaSchemaExport { 

    public static void main(String[] args) throws IOException { 
     execute(args[0], args[1]); 
     System.exit(0); 
    } 

    public static void execute(String persistenceUnitName, String destination) { 
     System.out.println("Generating DDL create script to : " + destination); 

     final Properties persistenceProperties = new Properties(); 

     // XXX force persistence properties : remove database target 
     persistenceProperties.setProperty(org.hibernate.cfg.AvailableSettings.HBM2DDL_AUTO, ""); 
     persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_DATABASE_ACTION, "none"); 

     // XXX force persistence properties : define create script target from metadata to destination 
     // persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_CREATE_SCHEMAS, "true"); 
     persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_SCRIPTS_ACTION, "create"); 
     persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_CREATE_SOURCE, "metadata"); 
     persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_SCRIPTS_CREATE_TARGET, destination); 

     Persistence.generateSchema(persistenceUnitName, persistenceProperties); 
    } 

} 

Como se puede ver que es muy simple!

Ahora usted puede utilizar esto en un AntTask o un experto en la construcción como esta (para MAVEN):

  <plugin> 
       <artifactId>maven-antrun-plugin</artifactId> 
       <version>1.7</version> 
       <executions> 
        <execution> 
         <id>generate-ddl-create</id> 
         <phase>process-classes</phase> 
         <goals> 
          <goal>run</goal> 
         </goals> 
         <configuration> 
          <target> 
           <!-- ANT Task definition --> 
           <java classname="com.orange.tools.jpa.JpaSchemaExport" 
            fork="true" failonerror="true"> 
            <arg value="${persistenceUnitName}" /> 
            <arg value="target/jpa/sql/schema-create.sql" /> 
            <!-- reference to the passed-in classpath reference --> 
            <classpath refid="maven.compile.classpath" /> 
           </java> 
          </target> 
         </configuration> 

        </execution> 
       </executions> 
      </plugin> 
+0

java.lang.UnsupportedOperationException: la aplicación debe proporcionar conexiones JDBC –

+0

http://stackoverflow.com/questions/34897410/auto-generate-data-schema- from-jpa-2-1-entity-entity-classes-without-a-databa –

1

Con EclipseLink, se debe añadir la propiedad:

<property name="eclipselink.ddl-generation" value="create-tables"/> 

Como se dice aquí : http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_ddl_generation.htm

Mi persistence.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> 
    <persistence-unit name="appDB" transaction-type="JTA"> 
     <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
     <jta-data-source>LocalMySQL</jta-data-source> 
     <class>entity.Us</class> 
     <class>entity.Btl</class> 
     <class>entity.Co</class> 
     <properties> 
      <property name="eclipselink.ddl-generation" value="create-tables"/> 
     </properties> 
    </persistence-unit> 
</persistence> 
Cuestiones relacionadas