Hibernacja: Automatyczne tworzenie / aktualizowanie tabel db na podstawie klas jednostek


101

Mam następującą klasę encji (w 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

}

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

i scenariusz:

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

baza danych Icarus istnieje, ale obecnie nie ma żadnych tabel. Chciałbym, aby Hibernate automatycznie tworzyło i / lub aktualizowało tabele na podstawie klas encji. Jak miałbym to osiągnąć?

Odpowiedzi:


104

Nie wiem, czy pozostawienie hibernateprzodu ma znaczenie.

Odniesienie sugeruje, powinno byćhibernate.hbm2ddl.auto

Wartość createutworzy tabele podczas tworzenia sessionFactory i pozostawi je nienaruszone.

Wartość create-droputworzy tabele, a następnie usunie je po zamknięciu sessionFactory.

Może powinieneś javax.persistence.Tablewyraźnie ustawić adnotację?

Mam nadzieję że to pomoże.


12
To była brakująca „hibernacja” na początku hbm2dll.auto. dzięki!
— Jason Miesionczek

Właśnie usunąłem tę linię i nie upuści stołu. Mam nadzieję że to pomoże!
— Meinkraft

1
jak ustawić hibernację, aby tworzyć tabele tylko wtedy, gdy ich nie ma?
— Aman Nagarkoti,

81

Możesz spróbować zmienić ten wiersz w pliku persistence.xml z

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

do:

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

Ma to na celu utrzymanie schematu w celu śledzenia wszelkich zmian wprowadzonych w modelu za każdym razem, gdy uruchamiasz aplikację.

Mam to z JavaRanch


10

Czasami, w zależności od ustawienia konfiguracji, długa i krótka forma tagu właściwości również może mieć znaczenie.

np. jeśli masz to jak:

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

spróbuj zmienić to na:

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

6

W moim przypadku tabela nie została utworzona po raz pierwszy bez ostatniej właściwości wymienionej poniżej:

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

korzystał z bazy danych H2 w pamięci Wildfly


2

Jest jeden bardzo ważny szczegół, który może powstrzymać twoją hibernację przed generowaniem tabel (zakładając, że już ustawiłeś hibernate.hbm2ddl.auto). Będziesz także potrzebować @Tableadnotacji!

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

W moim przypadku pomogło już co najmniej 3 razy - nadal nie mogę tego sobie przypomnieć;)

PS. Czytaj docs hibernacji - w większości przypadków będzie pewnie nie chcesz ustawić hibernate.hbm2ddl.auto, aby create-drop, ponieważ usuwa tabele po zatrzymaniu aplikacji.


0

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

0

Aby wesprzeć odpowiedź @ thorinkor, rozszerzyłbym swoją odpowiedź, aby nie tylko używać adnotacji @Table (name = "table_name") dla encji, ale także każda zmienna potomna klasy encji powinna być opatrzona adnotacją @Column (name = "col_name"). Skutkuje to bezproblemową aktualizacją tabeli w ruchu.

Dla tych, którzy szukają konfiguracji hibernacji opartej na klasach Java, reguła ma zastosowanie również w konfiguracjach opartych na Javie (NewHibernateUtil). Mam nadzieję, że pomoże to komuś innemu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.