سؤال

لديّ كابابيلات سباتية يحركها التعليقات التوضيحية في مشروعي.

الآن أريد إنشاء فهرس عبر عمود. تعريف العمود الحالي هو

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

وأضيف @Index التعليق التوضيحي هنا.

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

ثم إسقاط الجدول وإعادة تشغيل خادم Tomcat. بعد إنشاء الخادم ، يتم إنشاء الجدول ولكن لا يمكنني رؤية فهرس جديد على الاستعلام التالي.

SHOW INDEX FROM tableName

من المتوقع إنشاء جدول مع فهرس جديد. أنا أستخدم InnoDB مع MySQL.

هل كانت مفيدة؟

المحلول

ومن المثير للاهتمام ، في تكوين السبات الخاص بي كنت أستخدمه hibernate.hbm2ddl.auto=update.

هذا واحد يعدل قاعدة بيانات موجودة. كنت أسقط الجدول يدويًا tableName وإعادة تشغيل tomcat وتم بناء الجدول ولكن لم يتم إنشاء الفهرس.

ومع ذلك ، لقد صنعت hibernate.hbm2ddl.auto=create التي تعيد إنشاء قاعدة البيانات عند كل مثيل لـ WebApp ، فقد أسقطت جميع قاعدة البيانات الخاصة بي وإعادة بنائها مرة أخرى و- هيل نعم-تم إنشاء فهرس جديد!

نصائح أخرى

تم تعطيل إنشاء الفهرس على تحديث المخطط عن عمد في السبات لأنه بدا غير متسق مع التسمية المستخدمة في تصدير المخطط.

هذا هو الرمز المعلق الذي يمكنك العثور عليه في الفصل 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) );
    }
}

عادةً ما أقوم بإزالة هذا التعليق ، وإعادة ترجمة hibernate.jar وله فهارس تم إنشاؤها على تحديث المخطط دون أي مشكلة ، على الأقل مع Oracle DB.

في الإصدارات الحديثة من السبات ، تمت إزالة التعليق على الجزء الأول (فهارس الجدول) في الإصدار الرسمي أيضًا ، بينما لا يزال يعلق على التعليق الثاني (الفهارس التي تنفذ مفاتيح فريدة). انظر المناقشة في http://opensource.atlassian.com/projects/hibernate/browse/hhh-1012

أفضل تصميم 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);
    }

}

في السبات 3.5.6 باستخدام <property name="hibernate.hbm2ddl.auto">update</property> يتم إنشاء الفهارس. لذا فإن الإجابة المناسبة الآن هي الترقية. لكنني أترك هذا الإجابة لأولئك مثلي الذين صادفوا هذا السؤال.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top