Hibernate: création / mise à jour automatique des tables de base de données en fonction des classes d'entités

101

J'ai la classe d'entité suivante (dans Groovy):

import javax.persistence.Entity
import javax.persistence.Id
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType

@Entity
public class ServerNode {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  Long id

  String firstName
  String lastName

}

et mon persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
    <persistence-unit name="NewPersistenceUnit">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/Icarus"/>
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
            <property name="hibernate.connection.username" value="root"/>
            <property name="hibernate.connection.password" value=""/>
            <property name="hibernate.archive.autodetection" value="class"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hbm2ddl.auto" value="create"/>
        </properties>
        <class>net.interaxia.icarus.data.models.ServerNode</class>
    </persistence-unit>
</persistence>

et le script:

import javax.persistence.EntityManager
import javax.persistence.EntityManagerFactory
import javax.persistence.Persistence
import net.interaxia.icarus.data.models.ServerNode

def factory = Persistence.createEntityManagerFactory("NewPersistenceUnit")
def manager = factory.createEntityManager()

manager.getTransaction().begin()

manager.persist new ServerNode(firstName: "Test", lastName: "Server")

manager.getTransaction().commit()

la base de données Icarus existe, mais n'a actuellement aucune table. Je voudrais qu'Hibernate crée et / ou mette à jour automatiquement les tables basées sur les classes d'entités. Comment pourrais-je accomplir cela?

Jason Miesionczek
la source

Réponses:

104

Je ne sais pas si laisser hibernatele devant fait une différence.

La référence suggère qu'il devrait êtrehibernate.hbm2ddl.auto

Une valeur de createcréera vos tables lors de la création de sessionFactory et les laissera intactes.

Une valeur de create-dropcréera vos tables, puis les supprimera lorsque vous fermerez sessionFactory.

Peut-être devriez-vous définir javax.persistence.Tableexplicitement l' annotation?

J'espère que cela t'aides.

boîte à outils
la source
12
C'était le 'hibernate' manquant au début de hbm2dll.auto. Merci!
Jason Miesionczek
Je viens de supprimer cette ligne et cela ne fera pas tomber la table. J'espère que cela t'aides!
Meinkraft
1
comment puis-je faire hibernate pour créer des tables uniquement si elles n'existent pas?
Aman Nagarkoti
81

Vous pouvez essayer de changer cette ligne dans votre persistence.xml à partir de

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

à:

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

Ceci est censé maintenir le schéma pour suivre toutes les modifications que vous apportez au modèle chaque fois que vous exécutez l'application.

J'ai obtenu ceci de JavaRanch

billjamesdev
la source
10

Parfois, selon la façon dont la configuration est définie, la forme longue et la forme courte de la balise de propriété peuvent également faire la différence.

par exemple si vous l'avez comme:

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

essayez de le changer en:

<property name="hibernate.hbm2ddl.auto">create</property>
Harbir
la source
6

Dans mon cas, la table n'a pas été créée pour la première fois sans la dernière propriété répertoriée ci-dessous:

<properties>
    <property name="hibernate.archive.autodetection" value="class"/>
    <property name="hibernate.show_sql" value="true"/>
    <property name="hibernate.format_sql" value="true"/>
    <property name="hbm2ddl.auto" value="create-drop"/>
    <!-- without below table was not created -->
    <property name="javax.persistence.schema-generation.database.action" value="drop-and-create" />
</properties>

a utilisé la base de données H2 en mémoire de Wildfly

DevDio
la source
2

Il y a un détail très important, qui peut éventuellement empêcher votre mise en veille prolongée de générer des tables (en supposant que vous avez déjà défini le hibernate.hbm2ddl.auto). Vous aurez également besoin de l' @Tableannotation!

@Entity
@Table(name = "test_entity")
    public class TestEntity {
}

Cela a déjà aidé dans mon cas au moins 3 fois - je ne m'en souviens toujours pas;)

PS. Lisez la documentation sur la mise en veille prolongée - dans la plupart des cas, vous ne voudrez probablement pas définir hibernate.hbm2ddl.autosur create-drop, car cela supprime vos tables après l'arrêt de l'application.

thorinkor
la source
0

Dans le fichier applicationContext.xml:

<bean id="entityManagerFactoryBean" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
      <property name="dataSource" ref="dataSource" />
      <!-- This makes /META-INF/persistence.xml is no longer necessary -->
      <property name="packagesToScan" value="com.howtodoinjava.demo.model" />
      <!-- JpaVendorAdapter implementation for Hibernate EntityManager.
           Exposes Hibernate's persistence provider and EntityManager extension interface -->
      <property name="jpaVendorAdapter">
         <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
      </property>
      <property name="jpaProperties">
         <props>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
         </props>
      </property>
   </bean>
Yusuf Aksun
la source
0

Pour soutenir la réponse de @ thorinkor, j'étendrais ma réponse pour utiliser non seulement l'annotation @Table (name = "table_name") pour l'entité, mais aussi chaque variable enfant de la classe d'entité devrait être annotée avec @Column (name = "col_name"). Cela se traduit par une mise à jour transparente de la table lors de vos déplacements.

Pour ceux qui recherchent une configuration de mise en veille prolongée basée sur une classe Java, la règle s'applique également aux configurations basées sur Java (NewHibernateUtil). J'espère que cela aide quelqu'un d'autre.

AbsoluteDev
la source