18

Tôi có chú thích chụp ảnh chú thích theo kiểu chú thích theo hướng chú thích trên dự án của tôi.Tạo chỉ mục trên DB bằng Hibernate @Index Chú thích

Bây giờ tôi muốn tạo chỉ mục trên một cột. Định nghĩa cột hiện tại của tôi là

@NotNull 
@Column(name = "hash") 
private String hash; 

và tôi thêm chú thích @Index vào đây.

@NotNull 
@Column(name = "hash") 
@Index(name="hashIndex") 
private String hash; 

rồi DROP BẢNG và khởi động lại Máy chủ Tomcat. Sau khi máy chủ được khởi tạo, bảng được tạo nhưng tôi không thể thấy chỉ mục mới trên truy vấn sau đây.

SHOW INDEX FROM tableName 

Dự kiến ​​sẽ xây dựng bảng có chỉ mục mới. Tôi đang sử dụng InnoDB với MySQL.

Trả lời

16

Thật thú vị, trong cấu hình Hibernate của tôi, tôi đã sử dụng hibernate.hbm2ddl.auto=update.

Điều này sửa đổi cơ sở dữ liệu hiện có. Tôi đã tự DROPping bảng tableName và khởi động lại Tomcat và bảng đã được xây dựng nhưng chỉ mục không được tạo ra.

Tuy nhiên, tôi đã tạo hibernate.hbm2ddl.auto=create để tạo lại cơ sở dữ liệu theo từng lần tạo webapp, nó đã xóa tất cả cơ sở dữ liệu của tôi và xây dựng lại và -hãy vâng - chỉ mục mới của tôi đã được tạo!

+0

Vâng, tôi cũng nhận thấy hành vi này. +1 tất cả xung quanh. –

+0

Nhưng cài đặt 'auto.create' có an toàn để sản xuất không? http://stackoverflow.com/a/221422/409976 nếu không, làm thế nào để bạn xử lý các chỉ mục với hibernate? –

+1

https://hibernate.atlassian.net/browse/HHH-1012 đã được sửa, giờ đây cũng hoạt động với 'cập nhật'. – gavenkoa

9

Tạo chỉ mục trên bản cập nhật giản đồ đã được cố ý vô hiệu hóa trong Hibernate vì nó có vẻ không nhất quán với việc đặt tên được sử dụng trong xuất giản đồ.

Đây là mã nhận xét mà bạn có thể tìm thấy trong lớp org.hibernate.cfg.Configuration.

//broken, 'cos we don't generate these with names in SchemaExport 
subIter = table.getIndexIterator(); 
while (subIter.hasNext()) { 
    Index index = (Index) subIter.next(); 
    if (!index.isForeignKey() || !dialect.hasImplicitIndexForForeignKey()) { 
     if (tableInfo==null || tableInfo.getIndexMetadata(index.getFilterName()) == null) { 
      script.add(index.sqlCreateString(dialect, mapping)); 
     } 
    } 
} 
//broken, 'cos we don't generate these with names in SchemaExport 
subIter = table.getUniqueKeyIterator(); 
while (subIter.hasNext()) { 
    UniqueKey uk = (UniqueKey) subIter.next(); 
    if (tableInfo==null || tableInfo.getIndexMetadata(uk.getFilterName()) == null) { 
     script.add(uk.sqlCreateString(dialect, mapping)); 
    } 
} 

Thông thường tôi xóa nhận xét đó, biên dịch lại Hibernate.jar và có chỉ mục được tạo trên bản cập nhật lược đồ mà không gặp bất kỳ vấn đề nào, ít nhất với Oracle DB.

Trong các phiên bản gần đây của Hibernate chú thích trên phần đầu tiên (bảng chỉ mục) cũng đã bị xóa trong phiên bản chính thức, trong khi nó vẫn bình luận thứ hai (chỉ mục thực hiện khóa duy nhất). Xem cuộc thảo luận tại http://opensource.atlassian.com/projects/hibernate/browse/HHH-1012

+2

chỉ để sao lưu câu trả lời này - cập nhật cơ sở dữ liệu để tạo chỉ mục đang làm việc cho tôi bằng cách sử dụng hibernate 4.1.3 và mysq. Các chỉ mục được tạo tự động cho tôi mà không cần thả và tạo lại các bảng nếu tôi thêm chú thích @Index vào một thực thể. – jportway

2

Trong Hibernate 3.5.6 sử dụng <property name="hibernate.hbm2ddl.auto">update</property> các chỉ mục được tạo. Vì vậy, một câu trả lời đúng bây giờ sẽ được nâng cấp. Nhưng tôi để lại câu trả lời này cho những người như tôi đã gặp phải câu hỏi này.

+0

Có. https://hibernate.atlassian.net/browse/HHH-1012 được khắc phục trong 3.2.x, 3.3.x, 3.5.0-Beta-2 – gavenkoa

4

Thiết kế DB tốt hơn nghĩa là lược đồ được sở hữu bởi một người dùng khác với chính dữ liệu đó. Do đó tôi đặt hibernate.hbm2ddl.auto=none do đó không có lỗi khi khởi động Hibernate. Tôi sử dụng một SchemaPrinter để thay thế. Đầu ra của nó có thể được chạy qua công cụ SQL yêu thích của tôi để tạo lại lược đồ khi được yêu cầu.

import java.io.IOException; 

import org.hibernate.cfg.AnnotationConfiguration; 
import org.hibernate.cfg.Configuration; 
import org.hibernate.cfg.Environment; 
import org.hibernate.tool.hbm2ddl.SchemaExport; 

public class SchemaPrinter { 

    public static void main(String[] args) throws IOException { 

     Configuration cfg = new AnnotationConfiguration() 
      .addAnnotatedClass(MyClass1.class) 
      .addAnnotatedClass(MyClass2.class) 
      .setProperty(Environment.USER, "user") 
      .setProperty(Environment.PASS, "password") 
      .setProperty(Environment.URL, "jdbc:sybase:jndi:file://sql.ini?mydb") 
      .setProperty(Environment.DIALECT, "org.hibernate.dialect.SybaseASE15Dialect") 
      .setProperty(Environment.DRIVER, "com.sybase.jdbc4.jdbc.SybDriver") 
      .setProperty(Environment.HBM2DDL_AUTO, "none") 
     SchemaExport exp = new SchemaExport(cfg); 
     exp.setOutputFile("schema.ddl"); 
     exp.create(true, false); 
    } 

} 
Các vấn đề liên quan