18

프로젝트에 주석 구동 동면술 기능이 있습니다.최대 절전 모드로 인덱스 생성하기 인덱스 인덱스

이제는 열에 대한 색인을 만들고 싶습니다. 현재 열 정의는

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

이고 여기에 @Index 주석을 추가합니다.

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

다음 DROP TABLE 및 Tomcat 서버를 다시 시작하십시오. 서버가 인스턴스화 된 후 테이블이 만들어 지지만 다음 쿼리에서 새 인덱스를 볼 수 없습니다.

SHOW INDEX FROM tableName 

새로운 색인으로 표를 구성 할 것으로 예상됩니다. 나는 InnoDB를 MySQL과 함께 사용하고있다.

답변

16

흥미롭게도, 내 최대 절전 모드 구성에서 나는 hibernate.hbm2ddl.auto=update을 사용하고있었습니다.

기존 데이터베이스를 수정합니다. 나는 수동으로 테이블 tableName을 DROPping하고 Tomcat을 재시작했으며 테이블이 생성되었지만 인덱스가 생성되지 않았다.

그러나 webapp의 각 인스턴스 생성시 데이터베이스를 다시 생성하고 모든 데이터베이스를 삭제 한 다음 다시 작성하면 새 값이 생성됩니다.

+0

그래, 나는 또한이 행동을 발견했습니다. +1 주위에. –

+0

하지만 'auto.create'설정은 제작시 안전합니까? http://stackoverflow.com/a/221422/409976 그렇지 않으면 최대 절전 모드에서 색인을 어떻게 처리합니까? –

+1

https://hibernate.atlassian.net/browse/HHH-1012가 수정되었고, 이제는'update'도 함께 작동합니다. – gavenkoa

9

Hibernate에서 스키마 내보내기에 사용 된 이름 지정과 일치하지 않으므로 스키마 업데이트시 색인 생성이 의도적으로 비활성화되었습니다.

이것은 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)); 
    } 
} 

보통 나는 적어도 오라클 DB와 함께, 아무 문제없이 스키마 업데이트에 생성 된 인덱스를, 그 주석을 제거 Hibernate.jar을 다시 컴파일하고 있습니다.

최근 버전의 Hibernate에서는 공식 버전에서도 첫 번째 부분 (테이블 색인)에 대한 주석이 삭제되었으며 두 번째 주석 (고유 키를 구현하는 색인)은 여전히 ​​주석 처리되었습니다. http://opensource.atlassian.com/projects/hibernate/browse/HHH-1012

+2

이 답변을 백업하기 위해서 - 인덱스를 생성하기 위해 데이터베이스를 업데이트하는 것은 절전 모드 4.1.3과 mysq를 사용하여 나를 위해 일하고있다. 엔티티에 @Index 주석을 추가하면 테이블을 삭제하고 다시 만들지 않고 인덱스가 자동으로 생성됩니다. – jportway

2

최대 절전 모드에서 <property name="hibernate.hbm2ddl.auto">update</property을 사용하면 인덱스가 만들어집니다. 그래서 적절한 대답은 지금 업그레이드하는 것입니다. 그러나 나는이 질문을 가로 질러 온 저 같은 사람들을 위해이 대답을 남겨두고 있습니다.

+0

예. 3.2.x, 3.3.x, 3.5.0-Beta-2에서 https://hibernate.atlassian.net/browse/HHH-1012가 수정되었습니다. – gavenkoa

4

더 나은 DB 디자인은 스키마가 데이터 자체가 아닌 다른 사용자의 소유임을 의미합니다. 따라서 최대 절전 모드 시작시 아무런 오류도 발생하지 않도록 hibernate.hbm2ddl.auto=none을 설정합니다. 대신 SchemaPrinter를 사용합니다. 그 출력은 필자가 선호하는 SQL 도구를 통해 실행되어 필요할 때 스키마를 다시 생성 할 수 있습니다.

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); 
    } 

}