tutorial how example español ejemplos java database hibernate jpa java-ee

java - how - jpa example



Generación automática de esquema de datos a partir de clases de entidad anotadas por JPA (9)

Aquí hay una explicación de cómo usar la clase SchemaExport de hibernación para hacer exactamente lo que desea.

http://jandrewthompson.blogspot.com/2009/10/how-to-generate-ddl-scripts-from.html

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?

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.


Como Hibernate 4.3+ ahora implementa JPA 2.1, la forma apropiada de generar scripts DDL es usar el siguiente conjunto de propiedades de JPA 2.1:

<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"/>

Como se ejecutará en tiempo de ejecución, es posible que desee ejecutar esta generación de DDL en la compilació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 JPA 2.1 para generar este script 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 puedes ver es muy simple!

Ahora puede usar esto en una estructura AntTask o MAVEN 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>


Como nota relacionada: la documentación para generar esquemas de bases de datos usando EclipseLink JPA se puede encontrar here .


Con EclipseLink, debe agregar 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>


Puede usar hbm2ddl desde Hibernate. Los documentos están here .


Puede usar el complemento maven para lograr esto.

<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>


Si prefiere configurar en 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>


Generar script de creación y lanzamiento para entidades JPA determinadas

Usamos este código para generar las sentencias drop y create: solo construye esta clase con todas las clases de entidad y llama a create / dropTableScript.

Si es necesario, puede usar un nombre de unidad persitence.xml y persitance. 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(); } }


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

Agregue el código anterior en la etiqueta persistence.xml under properties. "update" 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.