Hibernate: Criar / atualizar automaticamente as tabelas de banco de dados com base em classes de entidade

101

Eu tenho a seguinte classe de entidade (em 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

}

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

e o roteiro:

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

o banco de dados Icarus existe, mas atualmente não tem tabelas. Gostaria que o Hibernate criasse e / ou atualizasse automaticamente as tabelas com base nas classes de entidade. Como eu faria isso?

Jason Miesionczek
fonte

Respostas:

104

Não sei se deixar de hibernatelado faz diferença.

A referência sugere que deveria serhibernate.hbm2ddl.auto

Um valor de createcriará suas tabelas na criação da sessionFactory e as deixará intactas.

Um valor de create-dropirá criar suas tabelas e, em seguida, eliminá-las quando você fechar a sessionFactory.

Talvez você deva definir a javax.persistence.Tableanotação explicitamente?

Espero que isto ajude.

kit de ferramentas
fonte
12
Era a falta de 'hibernação' no início do hbm2dll.auto. obrigado!
Jason Miesionczek de
Acabei de remover essa linha e não vai derrubar a mesa. Espero que isto ajude!
Meinkraft
1
como faço para hibernar para criar tabelas somente se elas não existirem?
Aman Nagarkoti de
81

Você pode tentar mudar esta linha em seu persistence.xml de

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

para:

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

Isso deve manter o esquema para seguir todas as alterações feitas no modelo sempre que executar o aplicativo.

Peguei isso de JavaRanch

billjamesdev
fonte
10

Às vezes, dependendo de como a configuração é definida, o formato longo e o formato curto da tag de propriedade também podem fazer a diferença.

por exemplo, se você tem como:

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

tente mudar para:

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

No meu caso, a tabela não foi criada pela primeira vez sem a última propriedade listada abaixo:

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

usou o banco de dados H2 em memória do Wildfly

DevDio
fonte
2

Há um detalhe muito importante, que pode impedir que seu hibernate gere tabelas (supondo que você já tenha configurado o hibernate.hbm2ddl.auto). Você também precisará da @Tableanotação!

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

Já ajudou no meu caso pelo menos 3 vezes - ainda não me lembro;)

PS. Leia os documentos do hibernate - na maioria dos casos, você provavelmente não desejará definir hibernate.hbm2ddl.autocomo create-drop, porque ele exclui Suas tabelas após interromper o aplicativo.

Thorinkor
fonte
0

No arquivo 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
fonte
0

Em apoio à resposta de @torinkor, eu estenderia minha resposta para usar não apenas a anotação @Table (name = "table_name") para entidade, mas também todas as variáveis ​​filho da classe de entidade devem ser anotadas com @Column (name = "col_name"). Isso resulta em uma atualização contínua para a mesa em movimento.

Para aqueles que procuram uma configuração de hibernate baseada em classe Java, a regra também se aplica a configurações baseadas em java (NewHibernateUtil). Espero que isso ajude mais alguém.

AbsoluteDev
fonte