最近使用Hibernate遇到一个奇葩问题。
第一个类:
class ProductType { private int productTypeId; private String productTypeName; }
对应的hibernate配置文件如下:
<hibernate-mapping> <class name="org.module.ProductType" table="product_type"> <id name="productTypeId" type="integer" column="product_type_id"> <generator class="native" /> </id> <property name="productTypeName" type="string" > <column name="product_type_name" length="50" /> </property> </class> </hibernate-mapping>
第二个类:
class Product { private String productId; private String productName; private ProductType productType; private String productMemory; }
对应的hibernate配置文件如下:
<hibernate-mapping> <class name="org.module.Product" table="product"> <id name="productId" type="java.lang.String" column="product_id" length="50"> <generator class="uuid.hex" /> </id> <property name="productName" type="string" > <column name="product_name" length="50" /> </property> <property name="productMemory" type="string"> <column name="product_memory" length="50" /> </property> <many-to-one name="productType" class="org.module.ProductType" column="product_type_id" not-null="true" /> </class> </hibernate-mapping>
好了,上面一段配置其实就说明了一个问题:
1. ProductType类是Product类的外键。
在 表product_type中,有如下数据:
当我们构造一个类,写下如下代码时:
<pre name="code" class="java">//查询product_type_id=0的记录到productType,这里结果显然是0,产品 ProductType productType = ProductTypeDao.getInstance().selectProductTypeById(0); ..... Product product = new Product();//创建类别对象,用于封装类别信息 product.setProductMemory(productMemory); product.setProductName(productName); product.setProductType(productType); ..... System.out.println("productType id"+productType.getProductTypeId()); System.out.println("productType name"+productType.getProductTypeName()); boolean res = RansProductDao.getInstance().saveProduct(product);//保存类别
运行后会报错:
productType id0 productType name产品 org.hibernate.PropertyValueException: not-null property references a null or transient value: org.module.Product.productType
更奇怪的是,如果把productTypeId改为1,2,3,4,就不会有错了。。
不得不说http://stackoverflow.com 就是程序员的圣站!先丢1篇文章上来:
http://stackoverflow.com/questions/3535791/primitive-or-wrapper-for-hibernate-primary-keys
看到了么?原因就是:
如果我们使用的类型是int,那么其默认值为0时,hibernate可能会把它解析为空!,所以我们id为0,虽然能打印出来,但是hibernate会认为它是空的。这也解释了为什么只有0会出错,其他的都不会有问题。
解决方案大致有2种:
1. 把所有的int定义修改为Integer
2. 修改表,不是用id为0的记录