0

使用: Hibernate 4.2.3、Eclipse Juno、および JSR286 ポートレット

理解できない例外動作が発生しています。ご意見やご提案をいただければ幸いです。

特定のデータベース テーブル (レガシー データを含む) を初めて使用するときは、外部キーの親レコードが存在するかどうかを確認する必要があります。存在しない場合は、ダミーの親レコードを挿入します。その後、すべてが機能します。親レコードをチェックし続けたくないので、ステートメントの周りに try/catch ブロックを配置しました。これによりObjectNotFoundException、親がそこにない場合に発生します。親レコードが挿入されるとエラーが消えるため、親レコードが欠落しているとこの例外が発生することがわかっています。

私が助けを必要としている問題は、メソッドブロックを終了するまで例外がスローされず、必要な場所である try/catch ブロックによってキャッチされないことです。

public List<Folder> getFolders(Long folderId) {
String hql = "select folder from Folder folder where folder.folderId=:folderId order by folder.folderId";
Boolean valid = false;
List<Folder> folder = new ArrayList<Folder>();
while (!valid) {
  try {
    folder = (List<Folder>) sessionFactory
       .getCurrentSession()
       .createQuery(hql)
       .setLong("folderId", folderId)
       .list();
   valid = true;
} catch (ObjectNotFoundException e) {
try {
    sessionFactory
    .getCurrentSession()
    .createSQLQuery("INSERT INTO `folder` (`folderId`) VALUES (0);")
    .executeUpdate();
    logger.info("added parent record 0 to folder table");
    } catch (Exception e1) {
      logger.info(e1.getMessage());
      }
    }
  }
return folder;

}

編集: これがスタック トレースです。ご覧のとおり、Hibernate が警告をスローし、次のエラーは、自分のコードではなく、Spring DispatcherPortlet から発生します。

2013-10-20 23:15:07,438 WARN [org.hibernate.engine.loading.internal.LoadContexts] - HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@a5571f9<rs=com.mchange.v2.c3p0.impl.NewProxyResultSet@417e79d3>
2013-10-20 23:15:07,438 WARN [org.hibernate.engine.loading.internal.CollectionLoadContext] - HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries
2013-10-20 23:15:07,438 WARN [org.hibernate.engine.loading.internal.LoadContexts] - HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@6fad97bb<rs=com.mchange.v2.c3p0.impl.NewProxyResultSet@5d4fab2d>
2013-10-20 23:15:07,438 WARN [org.hibernate.engine.loading.internal.CollectionLoadContext] - HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries
2013-10-20 23:15:07,438 WARN [org.springframework.web.portlet.DispatcherPortlet] - Handler execution resulted in exception - forwarding to resolved error view
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.sbeko.slider.domain.Folder#10207]
    at org.hibernate.internal.SessionFactoryImpl$1$1.handleEntityNotFound(SessionFactoryImpl.java:244)
    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:212)
4

1 に答える 1

1

Hibernate ObjectNotFoundException javadoc から:

Session.load() が、指定された主キー (識別子の値) を持つ行の選択に失敗した場合にスローされます。load() は可能であればプロキシを返すため、データベースに行がなくても、load() が呼び出されたときにこの例外がスローされない場合があります。アプリケーションは、Session.get() を使用して、データベースに行が存在するかどうかをテストする必要があります。

したがって、確認する必要があることが 2 つあります。インスタンス化が遅延しているため、実際のオブジェクトの代わりにプロキシを取得し、実際のオブジェクトが実際に使用されるポイントで例外を取得しているかどうか、および session.get() が解決するかどうか問題を解決したり、目的をより適切に果たしたりします。


さらに質問を処理するために編集します。

HQLを使用して、別のSOの質問でこれを見つけました:

public Boolean exists (DTOAny instance) 
{
    Query query = getSession().             
    createQuery("select 1 from DTOAny t where t.key = :key");
        query.setString("key", instance.getKey() );
    return (query.uniqueResult() != null);
}

instance.getKey()検索しようとしているインスタンスの ID を取得するために必要なものに置き換えます。

また、言及した get() メソッドを使用する場合は、0 ではなく実際のインデックス ID が必要だと思います。頑張ってください。

于 2013-10-20T22:31:15.860 に答える