سؤال

أنا أستعمل:

  • EJB3 / JPA (السبات)
  • mysql 5.

لا بد لي من إعداد نظام لمساعدة عمليات نقل قاعدة البيانات. حاول استخدام كيوباز ولكن يبدو أنه لا يكفي لاستخدامه مع السبات.

ما أود القيام به هو:

  • لدي الإصدار 1.0 من التطبيق في الإنتاج
  • لدي الإصدار 2.0 من التطبيق المتقدمة واختباره
  • أريد تحديث قاعدة بيانات التطبيق في الإنتاج دون فقد البيانات

في الواقع أود استخدام الجديد persistence.xml وقاعدة بيانات الإنتاج لتكون قادرة على توليد "دلتا" بين قاعدة البيانات القديمة والجديدة. أود أن أكون قادرا على استرداد رمز SQL الذي يتم تنفيذه عند تشغيل HBM2DDL على وضع "التحديث".

سيتم تعديل رمز SQL هذا (إسقاط + إنشاء = إعادة تسمية وغيرها ...) لتجنب فقدان البيانات التي قد تحدث معها hbm2ddl.auto=update.

أعتقد أنه من الممكن لأن السبات يفعل ذلك عند نشر نسخة جديدة مع hbm2ddl.auto=update. وبعد لكنني أريد أن أكون قادرا على القيام بذلك في مهمة النمل مع hibernatetool.

لا أجد العديد من المعلومات حول هذا الأمر على الإنترنت، لذا أتساءل عما إذا كان شخص ما بالفعل فعل شيء من هذا القبيل هنا ويمكن أن يساعدني.

لقد فعلت ما يلي:

<hibernatetool destdir="${dist}">
            <!--
            <jdbcconfiguration propertyfile="hibtest.properties"></jdbcconfiguration>
            -->
            <jpaconfiguration persistenceunit="server-pu" />
            <classpath>
                <fileset dir="${core.lib.server}" includes="*.jar" />
                <fileset dir="${core.lib.runtime}" includes="*.jar" />
                <fileset dir="${core.lib.build}" includes="*.jar" />
                <pathelement location="${core.class}" />
                <pathelement location="${core.etc}" />
            </classpath>
            <hbm2ddl outputfilename="schema-delta.sql" format="true"
                export="false" update="true" />
</hibernatetool>

أنا لا أعرف حقا كيف أفعل، كنت قادرا على الحصول على ملف SQL الإبداعي، لكنني أريد فقط الدلتا. لا بد لي من وضع التحديث = "صحيح"؟ هل يمكنني استخدام JPACONFIG مع وحدة الثبات خارج خادم التطبيقات (يتم تعيين إعدادات DB على Ressource Jndi على Glashfish). (حاول ولا يمكنك العثور على DB)

حاولت أيضا مع <jdbcconfiguration propertyfile="hibtest.properties"></jdbcconfiguration> أو إعداد خصائص قاعدة البيانات في persistence.xml بدلا من استخدام مورد JNDI.

حصلت على الخطأ التالي:

BUILD FAILED
/home/slorber/workspace/build/build.xml:899: org.hibernate.exception.JDBCConnectionException: Getting database metadata
    at org.hibernate.tool.ant.HibernateToolTask.reportException(HibernateToolTask.java:226)
    at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:189)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:105)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:357)
    at org.apache.tools.ant.Target.performTasks(Target.java:385)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1329)
    at org.apache.tools.ant.Project.executeTarget(Project.java:1298)
    at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
    at org.eclipse.ant.internal.ui.antsupport.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1181)
    at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:423)
    at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:137)
Caused by: org.hibernate.exception.JDBCConnectionException: Getting database metadata
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:97)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.getMetaData(AbstractMetaDataDialect.java:64)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.caseForSearch(AbstractMetaDataDialect.java:163)
    at org.hibernate.cfg.reveng.dialect.JDBCMetaDataDialect.getTables(JDBCMetaDataDialect.java:22)
    at org.hibernate.cfg.reveng.JDBCReader.processTables(JDBCReader.java:476)
    at org.hibernate.cfg.reveng.JDBCReader.readDatabaseSchema(JDBCReader.java:74)
    at org.hibernate.cfg.reveng.JDBCReader.readDatabaseSchema(JDBCReader.java:860)
    at org.hibernate.cfg.JDBCBinder.readDatabaseSchema(JDBCBinder.java:115)
    at org.hibernate.cfg.JDBCBinder.readFromDatabase(JDBCBinder.java:88)
    at org.hibernate.cfg.JDBCMetaDataConfiguration.readFromJDBC(JDBCMetaDataConfiguration.java:42)
    at org.hibernate.tool.ant.JDBCConfigurationTask.doConfiguration(JDBCConfigurationTask.java:81)
    at org.hibernate.tool.ant.ConfigurationTask.getConfiguration(ConfigurationTask.java:55)
    at org.hibernate.tool.ant.HibernateToolTask.getConfiguration(HibernateToolTask.java:302)
    at org.hibernate.tool.ant.Hbm2DDLExporterTask.createExporter(Hbm2DDLExporterTask.java:51)
    at org.hibernate.tool.ant.ExporterTask.execute(ExporterTask.java:39)
    at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:186)
    ... 15 more
Caused by: java.sql.SQLException: No suitable driver found for jdbc:mysql:3306//localhost/db
    at java.sql.DriverManager.getConnection(DriverManager.java:602)
    at java.sql.DriverManager.getConnection(DriverManager.java:154)
    at org.hibernate.connection.DriverManagerConnectionProvider.getConnection(DriverManagerConnectionProvider.java:133)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.getConnection(AbstractMetaDataDialect.java:122)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.getMetaData(AbstractMetaDataDialect.java:61)
    ... 29 more
--- Nested Exception ---
org.hibernate.exception.JDBCConnectionException: Getting database metadata
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:97)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.getMetaData(AbstractMetaDataDialect.java:64)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.caseForSearch(AbstractMetaDataDialect.java:163)
    at org.hibernate.cfg.reveng.dialect.JDBCMetaDataDialect.getTables(JDBCMetaDataDialect.java:22)
    at org.hibernate.cfg.reveng.JDBCReader.processTables(JDBCReader.java:476)
    at org.hibernate.cfg.reveng.JDBCReader.readDatabaseSchema(JDBCReader.java:74)
    at org.hibernate.cfg.reveng.JDBCReader.readDatabaseSchema(JDBCReader.java:860)
    at org.hibernate.cfg.JDBCBinder.readDatabaseSchema(JDBCBinder.java:115)
    at org.hibernate.cfg.JDBCBinder.readFromDatabase(JDBCBinder.java:88)
    at org.hibernate.cfg.JDBCMetaDataConfiguration.readFromJDBC(JDBCMetaDataConfiguration.java:42)
    at org.hibernate.tool.ant.JDBCConfigurationTask.doConfiguration(JDBCConfigurationTask.java:81)
    at org.hibernate.tool.ant.ConfigurationTask.getConfiguration(ConfigurationTask.java:55)
    at org.hibernate.tool.ant.HibernateToolTask.getConfiguration(HibernateToolTask.java:302)
    at org.hibernate.tool.ant.Hbm2DDLExporterTask.createExporter(Hbm2DDLExporterTask.java:51)
    at org.hibernate.tool.ant.ExporterTask.execute(ExporterTask.java:39)
    at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:186)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:105)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:357)
    at org.apache.tools.ant.Target.performTasks(Target.java:385)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1329)
    at org.apache.tools.ant.Project.executeTarget(Project.java:1298)
    at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
    at org.eclipse.ant.internal.ui.antsupport.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1181)
    at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:423)
    at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:137)
Caused by: java.sql.SQLException: No suitable driver found for jdbc:mysql:3306//localhost/db
    at java.sql.DriverManager.getConnection(DriverManager.java:602)
    at java.sql.DriverManager.getConnection(DriverManager.java:154)
    at org.hibernate.connection.DriverManagerConnectionProvider.getConnection(DriverManagerConnectionProvider.java:133)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.getConnection(AbstractMetaDataDialect.java:122)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.getMetaData(AbstractMetaDataDialect.java:61)
    ... 29 more

يمكنني استخدام MySQL، وخصائص JDBC الخاصة بي هي:

hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=jdbc:mysql:3306//localhost/db
hibernate.connection.username=root
hibernate.connection.password=root
hibernate.connection.show_sql=true

بلدي jdbc mysql سائق في ${core.lib.server}: mysql-connector-java-5.1.7-bin.jarوبعد (حاولت أيضا وضعها في classpath <fileset dir="/home/slorber/workspace/core/lib/server" includes="*.jar" />.)

أضفته أيضا إلى تكوين Classpath من النمل (Eclipse Plugin).

لذلك أسئلتي هي:

  • هل فعلت شيئا خاطئا أن أفعل ما أريد؟
  • هل هذه هي الطريقة التي ستقوم بها DB ترحيل إطار السبات؟ (وماذا ستفعل إذا لم تكتب كل تغييرات DB في ملفات SQL مصنوعة يدويا؟)
هل كانت مفيدة؟

المحلول

HBM2DDL لديه API يمكنك الاتصال بمفردك. إذا كانت مهام النمل الحالية لا تفعل ما تريد، فيمكنك دائما إجراء مكالمات HBM2DD الخاصة بنفسك، وربما اجتياز السبات من برنامج تشغيل JDBC الزائد الذي يقوم بتسجيل بتعريف البيانات بدلا من تنفيذها في الواقع أو تحميل طرق تنفيذ HBM2DDL.

أود أيضا أن أضيف أنه يجب عليك إلقاء نظرة على استخدام كيويباز وإنشاء ملفات XML يدويا على أي نوع من الضيوف. أنت تدرك أنك ستحتاج إلى التحقق من صحة SQL التي تم إنشاؤها، فمن السهل إنشاء خطوة واحدة في وقت تتطور، ثم تعلم أنها صحيحة.

نحن نستخدم السبات، وليس استخدام تكامل السبات Liquibase، نقوم بتحديث تعيينات السبات لدينا، وتشغيل اختبارات التكامل الخاصة بنا لمعرفة أنها تفشل، وإنشاء التغييرات الساحبة الضرورية (إضافة جدول، إضافة عمود، إعادة تسمية العمود، إلخ)، ثم إعادة -رون الاختبارات ورؤية لهم تمرير. بناء التغيير خطوة خطوة تعمل بشكل جيد مع إيقاع التطور المنتظم دون اللجوء إلى الضيافة لأي شيء خارج الشيكات العقلية.

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