1.现象:action无报错,客户端页面报错,无资源;
解答:资源地址有错误;
2.现象:控制台报错:org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.tekview.apex.itsm.common.bo.columnInfo.Column#0]
解答:
问题产生原因:
有一个对象A,关联了对象B ,关联关系可以使 ManyToOne,On
第二个原因:
查询的时候,假设对象A与B有着一对一的关系,一般我们配置
@On
@JoinColumn(name = "xxx"),如果B被删除了,但是A中还维护这个外键关系
要配置
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "xxx")
的模式,不知道为什么默认不是lazy的,还要配置一下fetch = FetchType.LAZY
本要急于测试所以直接设置为不关联not-found="ignore"
Hibernate的many-to-one的元素的一个属性:not-found今天看Hibernate Reference,看到多对一关系时,看到mant-to-one元素有一个属性:not-found。用来指定引用的外键不存在时将如何处理:
- exception(默认)抛出异常
- ignore 忽略
以前不知道有这个属性,Hibernate就采用默认的抛出异常来处理了。经常出现显示一个项目的列表时没有数据。
3. 现象:Property ‘columnId’ not found on type java.lang.String, hbm.xml中有这个属性,提示没有
解答:<c:forEach var="column" items="columnList" varStatus="status"> 修改为:
<c:forEach var="column" items="${columnList}" varStatus="status">
4. 现象:SpringMVC ModelAttribute无法绑定java.util.Date类型数据
解答:需要指定默认时间转换器
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
写一个Controller基类,把这些处理方法写到基类里面,然后每一个Controller去继承这个基类,应该是没问题。
5. 现象:保存实体时报错:org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.tekview.apex.itsm.common.bo.infomation.Column
解答:《精通Hibernate:Java对象持久化技术详解》第7章映射一对多关联关系,本章介绍一对多关联关系的映射方法。为大家介绍级联保存和更新。
5.1.1 <many-to-one>元素的not-null属性
当执行saveCustomerAndOrderWithCascade()方法时,会抛出如下异常:
- org.hibernate.PropertyValueException: not-null property
- references a null or transient value: mypack.Order.customer
这是在执行session.save(order1)方法时抛出的异常:
- tx = session.beginTransaction();
- Customer customer=new Customer("Jack");
- //session.save(customer); 不保存customer对象
- Order order1=new Order("Jack_Order001",customer);
- Order order2=new Order("Jack_Order002",customer);
- session.save(order1); //抛出PropertyValueException异常
- session.save(order2);
- tx.commit();
下面分析产生异常的原因。在调用session.save(order1)方法之前,order1和customer对象都是临时 (transient)对象。临时对象是指刚通过new语句创建,并且还没有被持久化的对象。假定session.save(order1)方法执行成 功,order1对象被成功持久化,就变成了持久化对象,而Hibernate不会自动持久化order1所关联的customer对象,在数据库中意味 着仅向ORDERS表中插入了一条记录,并且该记录的CUSTOMER_ID字段为null,这违反了数据库完整性约束,因为不允许ORDERS表的 CUSTOMER_ID字段为null。所以在这种情况下,Hibernate不允许持久化order1对象,会抛出 PropertyValueException异常,错误原因为order1对象的非空属性customer引用了一个临时对象customer。如果要 更加详细地了解持久化对象和临时对象的区别,参见本书第8章(通过Hibernate操纵对象(上)。
假定允许ORDERS表的CUSTOMER_ID字段为null,因此删除Order.hbm.xml文件的<many-to-one>元素的not-null属性,此时Hibernate会采用not-null属性的默认值false,修改后的代码如下:
- <many-to-one
- name="customer"
- column="CUSTOMER_ID"
- class="mypack.Customer"
- lazy="false"
- />
是否应该把<many-to-one>的not-null属性设为true,这是由实际业务需求决定的。通常,每个订单总是由某个客户 发出,因此应该把not-null属性设为true。本章在某些场合,如本节和7.2.1节,允许ORDERS表的CUSTOMER_ID外键为 null,仅仅是为了便于举例演示当映射文件的某些属性取不同值时Hibernate的运行时行为。
再次运行saveCustomerAndOrderWithCascade()方法,这次Hibernate成功地持久化了order1和order2对象,执行的insert语句为:
- insert into ORDERS (ID, ORDER_NUMBER,
CUSTOMER_ID) values (3,"Jack_Order001", null) - insert into ORDERS (ID, ORDER_NUMBER,
CUSTOMER_ID) values (4,"Jack_Order002", null)
但是当Hibernate自动清理(flush)缓存中所有持久化对象时,抛出了新的异常:
- [java]org.hibernate.TransientObjectException:
object references an unsaved transient - instance - save the transient instance before
flushing: mypack.Customer
所谓清理,是指Hibernate按照持久化对象的属性变化来同步更新数据库。Hibernate发现持久化对象order1和order2都引用临时对象customer,而在ORDERS表中相应的两条记录的CUSTOMER_ID字段为null,这意味着内存中的持久化对象的属性和数据库中记录不一致,参见图7-5,而且在这种情况下,Hibernate没办法使两者同步,因为Hibernate不会自动持久化Customer对象,所以Hibernate会抛出TransientObjectException异常,错误原因是持久化对象order1的customer属性引用了一个临时对象Customer。
图7-5 持久化对象order1和order2引用临时对象customer |
5.1.2 级联保存和更新
根据7.1.1节可以看出,当Hibernate持久化一个临时对象时,在默认情况下,它不会自动持久化所关联的其他临时对象,所以会抛出 TransientObjectException异常。如果希望当Hibernate持久化Order对象时自动持久化所关联的Customer对象, 可以把<many-to-one>的cascade属性设为"save-update",cascade属性的默认值为"none":
- <many-to-one
- name="customer"
- column="CUSTOMER_ID"
- class="mypack.Customer"
- cascade="save-update"
- not-null="true"
- lazy="false"
- />
再执行saveCustomerAndOrderWithCascade()方法中的session.save(order1)方法时,Hibernate把order1和customer对象一起持久化,此时Hibernate执行的SQL语句如下:
- insert into CUSTOMERS (ID,NAME) values (2, "Jack")
- insert into ORDERS(ID,ORDER_NUMBER,
CUSTOMER_ID)values(3,"Jack_Order001",2)
当cascade属性为"save-update",表明保存或更新当前对象时(即执行insert或update语句时),会级联保存或更新与它关联的对象。
6. 现象: 报错 org.hibernate.TransientObjectException: object references an unsaved transient instance
异常1:not-null property references a null or transient value
解决方法:将“一对多”关系中的“一”方,not-null设置为false
(参考资料:http://www.thearcmind.com/confluence/pages/viewpage.action?pageId=212)
异常2:org.hibernate.TransientObjectException: object references an unsaved transient instance
解决方法:cascade="save-update,persist"
(参考资料:http://www.laliluna.de/254.html)
异常3:org.hibernate.QueryException: could not resolve property
解决方法:"from Category category where category.userID = :userID"修改为"from Category category where userID = :userID"或者"from Category category where category.user.id = :userID"
(参考资料:http://www.laliluna.de/277.html)
异常4:could not initialize proxy - the owning Session was closed
解决方法:设置lazy为false
(参考资料:http://forum.springframework.org/showthread.php?t=27993)
异常2我在应用中碰到了这样的问题:
有三个表:userInfo deptmentInfo role
userInfo 与deptmentInfo为many to one
userInfo 与role为many to one
下面为保存UserInfo对象时的代码:
DeptmentInfo dept = new DeptmentInfo();
dept.setDeptName(deptName);
Role role = new Role();
role.setRoleName(roleName);
UserInfo user = new UserInfo();
user.setUserName(userName);
user.setUserSex(userSex);
user.setDuty(duty);
user.setPhone(phone);
user.setMobileNum(mobileNum);
user.setEmail(email);
user.setQq(qq);
user.setMsn(msn);
user.setAdress(adress);
user.setDeptmentInfo(dept);
user.setRole(role);
dao.save(user);
执行时有错:org.hibernate.TransientObjectException: object references an unsaved transient instance
于是改了UserInfo.hbm.xml的一些地方
如下:
<many-to-one name="role" class="com.oa.domain.Role"
cascade="save-update,persist" fetch="select">
<column name="ROLE_ID" precision="22" scale="0" />
</many-to-one>
<many-to-one name="deptmentInfo"
class="com.oa.domain.DeptmentInfo" cascade="save-update,persist"
fetch="select">
<column name="DEPT_ID" precision="22" scale="0" />
</many-to-one>
加了上面红色部分的,就OK了,能保存了。
8. strus1 的action里jsp调用的方法无返回值也就写成返回“ActionForward”类型的;
9. java 导入的项目很多都报cannot be resolved to a type的错误,不是导包问题
解答:这个错误可能是服务器自带的servlet库未导入的原因。