12

Hibernate3.6.9でイライラする問題があります。MSSQLServer2008。例外と奇数列のインデックス参照に注意してください。

HQLクエリ自体:

Select r from DataStoreReference r join fetch r.container c where r.hash=:hash and r.state=0

スタックトレース:

2012-05-16 00:01:22,184 [BackgroundDeletionThread] ERROR org.hibernate.util.JDBCExceptionReporter - The value supplied cannot be converted to BIGINT.  
2012-05-16 00:01:22,186 [BackgroundDeletionThread] ERROR org.hibernate.util.JDBCExceptionReporter - The value supplied cannot be converted to BIGINT.  
2012-05-16 00:01:22,188 [BackgroundDeletionThread] ERROR org.hibernate.util.JDBCExceptionReporter - Invalid column index 14.  
2012-05-16 00:01:22,190 [BackgroundDeletionThread] ERROR org.hibernate.util.JDBCExceptionReporter - The value supplied cannot be converted to BIGINT.  
2012-05-16 00:01:22,193 [BackgroundDeletionThread] ERROR org.hibernate.util.JDBCExceptionReporter - The value supplied cannot be converted to BIGINT.  
2012-05-16 00:01:22,194 [BackgroundDeletionThread] ERROR org.hibernate.util.JDBCExceptionReporter - Invalid column index 14.  
2012-05-16 00:01:22,194 [BackgroundDeletionThread] ERROR com.flipper.utils.ServerErrorHandlerStrategy - reportError: Db :: com.flipper.datastore.workers.BackgroundDeletionThread.executeWork:87 :: EXCEPTION : com.flipper.datastore.exceptions.DBStoreException: Null value was assigned to a property of primitive type setter of com.flipper.datastore.model.DataStoreReference.usage com.flipper.datastore.exceptions.DBStoreException: Null value was assigned to a property of primitive type setter of com.flipper.datastore.model.DataStoreReference.usage  
    at com.flipper.datastore.impl.hib.HibernateDBStore.getAllReferences(HibernateDBStore.java:301)
    at    com.flipper.datastore.workers.BackgroundDeletionThread.processEntry(BackgroundDeletionThread.java:165)
    at com.flipper.datastore.workers.BackgroundDeletionThread.processSet(BackgroundDeletionThread.java:138)
    at com.flipper.datastore.workers.BackgroundDeletionThread.executeWork(BackgroundDeletionThread.java:84)
    at com.flipper.datastore.workers.BackgroundDeletionThread.run(BackgroundDeletionThread.java:60)
Caused by: org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of com.flipper.datastore.model.DataStoreReference.usage
    at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:109)
    at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:583)
    at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:229)
    at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:3847)
    at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:152)
    at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:982)
    at org.hibernate.loader.Loader.doQuery(Loader.java:857)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
    at org.hibernate.loader.Loader.doList(Loader.java:2542)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
    at org.hibernate.loader.Loader.list(Loader.java:2271)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:459)
    at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:365)
    at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1268)
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
    at com.flipper.message.dao.DataStoreDao.getAllReferencesByHash(DataStoreDao.java:136)
    at com.flipper.datastore.impl.hib.HibernateDBStore.getAllReferences(HibernateDBStore.java:298)
    ... 4 more
Caused by: java.lang.IllegalArgumentException
    at sun.reflect.GeneratedMethodAccessor556.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:66)
    ... 21 more

さて、次のことが当てはまらない場合は、ロジック(およびグーグル)からこれを理解します

a)DataStoreReferenceのすべてのインスタンス化の直後にSystem.currentTimeMillisのsetUsageが続きます)b)アイテムはマッピングでnull以外とマークされます(以下を参照)c)エクスポートされたテーブルはf_external列にのみnullを示します。使用法の列には、完全に妥当な長い数値があります。

POJO:

DataStoreReference

private long id;


private String hash;    
private long date;  
private long sze;   
private long usage; 

private int state;  
private String external;
private DataStoreContainer container; 

その後に、一般的な変更されていないゲッター/セッターが続きます。

マッピングファイル:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.flippr.datastore.model">
  <class name="DataStoreReference" table="t_dsref">
    <id name="id">
      <column name="ds_reference_id"/>
      <generator class="native"/>
    </id>
    <property name="hash" not-null="true" column="f_hash" lazy="false" index="idx_hash_dsr" type="string" length="128" />
    <property name="state" not-null="true" column="f_state" lazy="false" index="idx_hash_dsr,idx_size_dsr,idx_usage_dsr" type="integer"/>
    <!--  hibernate hates the name size -->
    <property name="sze" not-null="true" column="f_size" lazy="false" index="idx_size_dsr" type="long"/>
    <property name="date" not-null="true" column="f_date" lazy="false" type="long"/>    
    <property name="usage" not-null="true" column="f_usage" lazy="false" index="idx_usage_dsr" type="long"/>
    <property name="external" not-null="false" column="f_ext" lazy="false" type="string" length="160" />

    <many-to-one name="container" class="com.flipper.datastore.model.DataStoreContainer" 
     column="entity_id" foreign-key="fk_ds_container_id_dsr"  not-found="ignore" not-null="true"/>
   </class>
</hibernate-mapping>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.flipper.datastore.model">
  <class name="DataStoreContainer" table="t_dscnt">
    <id name="id">
      <column name="ds_container_id"/>
      <generator class="native"/>
    </id>
    <property name="containerType" column="f_type" index="idx_containerType_dsc" lazy="false" type="integer"/>
    <property name="fileCount" column="f_fc" lazy="false" type="long"/>
    <property name="deletedCount" column="f_dc" lazy="false" type="long"/>
    <property name="path" column="f_path" length="255" lazy="false"  type="string"/>
    <set cascade="save-update,delete,delete-orphan,all-delete-orphan" inverse="true" name="documents">
      <key column="entity_id" />
      <one-to-many class="com.flipper.datastore.model.DataStoreReference"/>
    </set>
  </class>
</hibernate-mapping>
4

4 に答える 4

33

エラーメッセージは明確です。少なくとも1つの行で、列f_usageにnull値があります。プリミティブ型はnullを表すことができないため、このnull値をlongのようなプリミティブ型に入れることはできません。

データベースにすでにnull値がある場合、property句のnot-null属性は効果がありません。not-null属性は、dmdの生成にのみ使用されます。ただし、データベーステーブルt_dsrefのf_usage列では、おそらくnull値が許可されています(desc t_dsrefSQLで確認してください)。

解決策:LongとLongを交換します。

private Long usage; 

値を使用する場合、たとえばnull条件を処理する必要があります

if (usage != null) {
  return usage.longValue();
else
  return -1;

(休止状態でのアクセスにゲッターとセッターを使用しているため、このコードレットはゲッターに含めないでください。データベースでは、更新後もnull値はnullのままである必要がありますが、使用する2番目のゲッターで実行できます。他のすべての場所、または休止状態のフィールドアクセスを行います。)

私の一般的な推奨事項:プリミティブデータ型は、データベースで列がNOTNULLでマークされている場合にのみ休止状態のプロパティに使用する必要があります。

于 2012-05-18T07:09:16.543 に答える
5

一部の列にプリミティブ型を使用しているが、DBではそのフィールドがnullの場合、Hibernateでこのようなエラーが発生します。ソリューション:

解決策1:ラッパークラス(intの整数...)を使用します。解決策2:列のデフォルト値を定義します。

于 2017-01-16T08:29:56.427 に答える
3

これは、拡張されたHibernate 3.6MSSQLダイアレクトのバグであることが判明しました。SQLServer2005またはSQLServer2008ダイアレクトを拡張すると、この問題が発生します。古いSQLServerダイアレクト(Hibernate 3.3xに付属しているものとほぼ同じ)を使用する場合は使用しません。おそらく、導入されたページングサポートと関係があります。はぁ

于 2012-06-19T02:12:44.067 に答える
1

Hibernateは、企業開発の実際のシナリオに一致するようにいくつかの改訂が必要です。プリミティブの代わりにオブジェクトを使用すると、このコンテキストで解決される問題よりも多くの問題が発生します。

私は2002年からJavaEEエンタープライズアプリをコーディングしています。null値のコードテーブルを参照するテーブルが多数ある可能性があることを考慮すると、このユースケースの最善の解決策は、可能であればデータベースを更新することです。

たとえば、ジュニア、シニアなどのタイトルを示す世代コードテーブルへの参照を持つpersonsテーブルがあり、多くのエントリがnullである場合、不明な参照を持つようにコードテーブルを更新してから、すべてのテーブルデータを更新します。その参照を指すnull。大きくてコードが正しくないほとんどのJavaEEアプリは、これらのテーブルへのエントリポイントを更新してみることができますが、ほとんどの場合、混乱しており、cronジョブ、Webサービスなどから実行されるあらゆる種類のエントリポイントがある可能性があるため、更新してください。 DBは、これらのnullをキャッチし、デフォルトで不明なエントリに設定して、頭痛の種を減らします。建物を最初から作成する場合、これも休止状態の混乱です。休止状態を伝えるのは簡単ではないため、プリミティブを使用してセッターを呼び出そうとしていることです。」s nullは、0または-1にしますが、20時間未満の休止状態の経験があります。ユーザータイプについて読んだだけなので、もう少し読んで、それらがどのように機能するかを確認する必要があります。

大規模なJavaEEアプリのオブジェクトは、現在市場に出回っている高品質のコーダーにとって、実行時の悪夢です。

于 2015-12-07T04:58:28.837 に答える