Hibernate: Tự động tạo / cập nhật các bảng db dựa trên các lớp thực thể


101

Tôi có lớp thực thể sau (trong 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

}

và sự kiên trì của tôi.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>

và kịch bản:

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

cơ sở dữ liệu Icarus tồn tại, nhưng hiện không có bảng nào. Tôi muốn Hibernate tự động tạo và / hoặc cập nhật các bảng dựa trên các lớp thực thể. Làm thế nào tôi sẽ thực hiện điều này?

Câu trả lời:


104

Tôi không biết liệu việc rời bỏ hibernatephía trước có tạo ra sự khác biệt hay không.

Tài liệu tham khảo cho thấy nó nên đượchibernate.hbm2ddl.auto

Giá trị của createsẽ tạo các bảng của bạn khi tạo sessionFactory và giữ nguyên chúng.

Giá trị của create-dropsẽ tạo các bảng của bạn và sau đó giảm chúng khi bạn đóng sessionFactory.

Có lẽ bạn nên đặt javax.persistence.Tablechú thích một cách rõ ràng?

Hi vọng điêu nay co ich.


12
Đó là 'trạng thái ngủ đông' bị thiếu ở phần đầu của hbm2dll.auto. cảm ơn!
Jason Miesionczek

Tôi chỉ xóa dòng đó và nó sẽ không làm rơi bảng. Hi vọng điêu nay co ich!
Meinkraft

1
làm cách nào để tạo bảng ở chế độ ngủ đông chỉ khi chúng không tồn tại?
Aman Nagarkoti

81

Bạn có thể thử thay đổi dòng này trong Persence.xml của bạn từ

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

đến:

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

Điều này được cho là để duy trì lược đồ theo bất kỳ thay đổi nào bạn thực hiện đối với Mô hình mỗi khi bạn chạy ứng dụng.

Lấy cái này từ JavaRanch


10

Đôi khi tùy thuộc vào cách đặt cấu hình, dạng dài và dạng ngắn của thẻ thuộc tính cũng có thể tạo ra sự khác biệt.

Ví dụ: nếu bạn có nó như:

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

hãy thử thay đổi nó thành:

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

6

Trong trường hợp của tôi, bảng không được tạo lần đầu tiên mà không có thuộc tính cuối cùng được liệt kê bên dưới:

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

đã sử dụng cơ sở dữ liệu H2 trong bộ nhớ của Wildfly


2

Có một chi tiết rất quan trọng, có thể ngăn chế độ ngủ đông của bạn tạo bảng (giả sử Bạn đã thiết lập hibernate.hbm2ddl.auto). Bạn cũng sẽ cần @Tablechú thích!

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

Nó đã có ích trong trường hợp của tôi ít nhất 3 lần - vẫn không thể nhớ nó;)

Tái bút. Đọc tài liệu về chế độ ngủ đông - trong hầu hết các trường hợp Có thể bạn sẽ không muốn đặt hibernate.hbm2ddl.autothành create-drop, vì nó sẽ xóa các bảng của Bạn sau khi dừng ứng dụng.


0

Trong tệp 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

Để hỗ trợ cho câu trả lời của @ thorinkor, tôi sẽ mở rộng câu trả lời của mình để không chỉ sử dụng chú thích @Table (name = "table_name") cho thực thể, mà mọi biến con của lớp thực thể cũng phải được chú thích bằng @Column (name = "col_name"). Điều này dẫn đến cập nhật liền mạch cho bảng khi đang di chuyển.

Đối với những người đang tìm kiếm cấu hình ngủ đông dựa trên lớp Java, quy tắc cũng áp dụng trong cấu hình dựa trên java (NewHibernateUtil). Hy vọng nó sẽ giúp ai đó khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.