简体   繁体   English

hibernate异常将空值赋给基本类型setter的属性

[英]hibernate exception Null value was assigned to a property of primitive type setter

Having a frustrating problem with Hibernate 3.6.9. Hibernate 3.6.9遇到了令人沮丧的问题。 MS SQL Server 2008. Note the exception and the odd column index reference. MS SQL Server 2008.请注意异常和奇数列索引引用。

The HQL Query itself: HQL查询本身:

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

The stack trace: 堆栈跟踪:

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

Now, I'd understand this from logic (and from googling) if the following were not true 现在,如果以下情况不正确,我会从逻辑(以及谷歌搜索)中理解这一点

a) every instantiation of DataStoreReference is shortly followed by a setUsage of System.currentTimeMillis) b) the item is marked not-null in the mapping (see below) c) the exported table shows nulls only in the f_external column. a)DataStoreReference的每个实例化后面紧跟一个SystemUsusMillis的setUsage)b)该项在映射中标记为非null(见下文)c)导出的表仅在f_external列中显示空值。 The usage column has perfectly reasonable long numbers. 使用列具有完全合理的长数。

The POJO: POJO:

DataStoreReference 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; 

followed by generic unmodified getter/setters. 其次是通用的未修改的getter / setter。

The mapping file: 映射文件:

<?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>

The error message is clear: In at least one row the column f_usage has a null value. 错误消息是明确的:在至少一行中,列f_usage具有空值。 This null value can't be put into a primitive type like long, because primitive types can't represent null. 此null值不能像long一样放入基本类型,因为基本类型不能表示null。

The not-null attribute in the property clause has no effect when there already is a null value in the database. 当数据库中已存在空值时,property子句中的not-null属性无效。 The not-null attribute only is used for the dmd generation. not-null属性仅用于dmd生成。 But the f_usage column of your database table t_dsref probably allows null values (check with desc t_dsref in sql). 但是数据库表t_dsref的f_usage列可能允许空值(在sql中使用desc t_dsref检查)。

Solution: Exchange long with Long: 解决方案:与Long交换多头:

private Long usage; 

and when using the value you have to handle the null condition, for example 例如,在使用该值时,您必须处理null条件

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

(You are using getters and setters for access with hibernate, so this codelet should not be in the getter, because in the database a null value should continue to be null after an update, but you can do it in a second getter which you use everywhere else, or you do field access for hibernate.) (你使用getter和setter来访问hibernate,所以这个codelet不应该在getter中,因为在数据库中,null值在更新后应该继续为null,但是你可以在你使用的第二个getter中执行它在其他地方,或者你为hibernate进行字段访问。)

My general recommendation: Primitive datatypes should only be used for hibernate properties if the column is marked with NOT NULL in the database . 我的一般建议:如果列在数据库中标记为NOT NULL ,则原始数据类型应仅用于hibernate属性。

Turns out it is a bug with the enhanced Hibernate 3.6 MS SQL dialects. 原来这是增强的Hibernate 3.6 MS SQL方言的一个错误。 If you extend SQLServer2005 or SQLServer2008 dialects, you will have this issue. 如果扩展SQLServer2005或SQLServer2008方言,则会出现此问题。 Using the older SQLServer dialect (which is pretty much what shipped with Hibernate 3.3x) you do not. 使用较旧的SQLServer方言(这几乎是Hibernate 3.3x附带的方言)你没有。 Probably something to do with paging support introduced. 可能与引入的分页支持有关。 Sigh

Such errors happen in Hibernate when you use primitive types for some columns but that fields are null in DB. 当您对某些列使用基本类型但在DB中该字段为空时,在Hibernate中会发生此类错误。 solutions: 解决方案:

solution One: use Wrapper classes (Integer for int ...) solution Two: define default values for columns. 解决方案一:使用Wrapper类(Integer for int ...)解决方案二:定义列的默认值。

Hibernate needs some revisions to match the real life scenarios of enterprise development. Hibernate需要一些修改来匹配企业开发的现实生活场景。 Using objects instead of primitives leads to many more issues than what is solved in this context. 使用对象而不是基元会导致比在此上下文中解决的问题更多的问题。

I have been coding Java EE enterprise apps since 2002. The best solution to this use case, taking into account that you probably have many tables that reference code tables with null values is to update the database if possible. 自2002年以来,我一直在编写Java EE企业应用程序。考虑到您可能有许多引用具有空值的代码表的表,这个用例的最佳解决方案是尽可能更新数据库。

For instance if you have a persons table with a reference to a generation code table to denote titles like junior, Senior, etc and many entries are null, update the code table to have an un-known reference and then update the table data for all nulls to point to that reference. 例如,如果您有一个人员表,其中包含对生成代码表的引用以表示诸如junior,Senior等标题,并且许多条目为null,则更新代码表以获得未知引用,然后更新所有表的数据nulls指向该引用。 As most Java EE apps that are large and ill-coded you can try and update the entry points to these tables but most likely it's a mess and there may be all sorts of entry points run from cron jobs, web services, etc so update the DB to catch these nulls and default them to the unknown entry and save your self a headache. 由于大多数Java EE应用程序都很大并且编码错误,您可以尝试更新这些表的入口点,但很可能是一团糟,可能有各种入口点从cron作业,Web服务等运行,因此请更新DB捕获这些空值并将它们默认为未知条目并让您自己头疼。 If your building from scratch this is also a mess with hibernate as it's not very easy from what I can tell to tell hibernate is your trying to call a setter with a primitive, and it's null just make it 0 or -1 but then again I have less than 20 hrs of hibernate experience. 如果你的构建从头开始这也是一个混乱的hibernate,因为它不是很容易从我可以告诉告诉hibernate你试图用一个原语调用一个setter,它是null只是让它为0或-1然后再次我拥有不到20小时的休眠体验。 I just read up on user types so I'll have to read a bit more and see how they work. 我刚刚读了用户类型,所以我需要阅读更多内容,看看它们是如何工作的。

Objects in large Java EE apps are a nightmare at runtime with quality of coders on the market today. 大型Java EE应用程序中的对象在运行时是一个噩梦,当今市场上的编码器质量很高。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 避免“Hibernate异常将Null值分配给基本类型setter的属性”而不使用包装器 - Avoid “Hibernate exception Null value was assigned to a property of primitive type setter” without wrappers 在hibernate查询执行时,是否将空值赋给基本类型的属性? - Null value was assigned to a property of primitive type while hibernate query execution? null值无法分配给基本类型错误(Spring / Hibernate) - A null value cannot be assigned to a primitive type error (Spring/Hibernate) org.hibernate.PropertyAccessException:空值已分配给布尔类型的属性 - org.hibernate.PropertyAccessException: Null value was assigned to a property of boolean type Hibernate将NULL插入到基本类型字段中 - Hibernate inserting NULL into primitive type field Hibernate异常org.hibernate.PropertyValueException:not-null属性引用了null或瞬态值 - Hibernate exception org.hibernate.PropertyValueException: not-null property references a null or transient value 线程“ main” org.hibernate.PropertyValueException中的异常:not-null属性引用了null或瞬态值 - Exception in thread “main” org.hibernate.PropertyValueException: not-null property references a null or transient value 如何使用setter方法在hibernate的列中显式设置NULL值? - How to explicit set NULL value in a column in hibernate using setter method? 是否可以为值分配或与值类型变量进行比较? - Can null be assigned to or be compared to a value type variable? 分配给基元的对象类型参考变量 - Object type reference variable assigned to a primitive
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM