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ąć?

Jason Miesionczek
źródło

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.

zestaw narzędzi
źródło
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

billjamesdev
źródło
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>
Harbir
źródło
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

DevDio
źródło
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.

thorinkor
źródło
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>
Yusuf Aksun
źródło
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.

AbsoluteDev
źródło