1

エンティティを永続化するために、GlassfishとMySQLデータベースでEclipseLink2.4.1を使用しています。
エンティティにフィールドを追加しましたが、このエンティティを永続化しようとすると、新しいフィールドは「不明」と表示されます。
新しい「テーブルの作成または拡張」機能をどのように使用することになっていますか?このフィールドに新しい列が作成されると思いました。

いくつかの関連情報を以下に示します。もっと必要な場合はお知らせください。

前もって感謝します!

スタックトレース

...
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.1.v20121003 ad44345): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 't0.TESTFIELD' in 'field list'
Error Code: 1054
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
...

persistence.xml

<persistence-unit name="myApp" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/mysql</jta-data-source>
<mapping-file>META-INF/orm.xml</mapping-file>
<properties>
  <property name="eclipselink.ddl-generation.output-mode" value="database"/>
  <property name="eclipselink.jdbc.batch-writing" value="Buffered"/>
  <property name="eclipselink.logging.level" value="INFO"/>
  <property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
</properties>

追加情報

ドロップアンドクリエイトテーブルは機能します。
私はmerge(entity)を使用して新しいエンティティを永続化しています(他の方法ではプライマリIDの重複の問題を引き起こす多くの1対多のフィールドがあるため)-これが問題である可能性があります。
MySQLログ、およびEclipseLinkからの最高のログレベルを見ると、EclipseLinkは最初に次のようにデータベースからエンティティを選択しようとします
。mysql_log:

121115 10:49:03 9 Query SELECT t0.LISTINGID, t0.DTYPE, ... , t0.TESTFIELD FROM the_entity...

これは最後のmysqlログエントリです。つまり、ここでクラッシュし、テーブルなどを削除しようとはしません。これは、ドロップアンドクリエイトまたはクリエイトオアエクステンドでマージを使用できないことを意味しますか?私はグーグルをしただけで、これに関する情報は見つかりませんでした。

EclipseLinkロギング:

FINER: client acquired: 64279491
FINER: TX binding to tx mgr, status=STATUS_ACTIVE
FINER: acquire unit of work: 161130796
FINEST: Merge clone with references nz.co.site.api.v1.ListedItemDetail@8d88ca1
FINEST: Execute query ReadObjectQuery(referenceClass=ListedItemDetail )
FINEST: Connection acquired from connection pool [read].
FINEST: reconnecting to external connection pool
FINE: SELECT t0.LISTINGID, t0.DTYPE, ... , t0.TESTFIELD, ... , FROM ITEM t0, LISTEDITEMDETAIL t1 WHERE ((t0.LISTINGID = ?) AND ((t1.LISTINGID = t0.LISTINGID) AND (t0.DTYPE = ?)))
bind => [2 parameters bound]
FINE: SELECT 1
FINEST: Connection released to connection pool [read].
WARNING: Local Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.DatabaseException

Beanトランザクション管理を使用して、新しいエンティティをマージします。

userTransaction.begin();
entityManager.merge(entity);
entityManager.flush();
userTransaction.commit();
4

1 に答える 1

3

Glassfishはeclipselink.ddl-generation.output-modeプロパティをインターセプトし、ここでの回答で説明されているようにファイルに強制的に書き出します。eclipselinkは注釈付きJPAクラスからテーブルを生成しないため 、Glassfishでjava2dbが有効になっていることを確認する必要があります。 「ドロップアンドクリエイトテーブル」が機能するため。

ただし、「create-or-extend-tables」では、データベースの内容を確認するためにデータベース接続が必要であるため、現在sql-script出力モードでは機能しません。Glassfishにoutput-modeプロパティを上書きしないように強制する方法はわかりませんが、上書きできない場合は、この機能を使用するために永続ユニット側のGlassfishを実行する必要があります。

Glassfishの回避策は、次のようなものを試すことです。

Map properties = new HashMap();
properties.put(PersistenceUnitProperties.DDL_GENERATION, PersistenceUnitProperties.CREATE_OR_EXTEND);
//create-or-extend only works on the database
properties.put(PersistenceUnitProperties.DDL_GENERATION_MODE, PersistenceUnitProperties.DDL_DATABASE_GENERATION);
//this causes DDL generation to occur on refreshMetadata rather than wait until an em is obtained
properties.put(PersistenceUnitProperties.DEPLOY_ON_STARTUP, "true");
JpaHelper.getEntityManagerFactory(em).refreshMetadata(properties);
于 2012-11-14T22:14:07.660 に答える