[新人求指导] Hibernate4 one-to-many/many-to-one注解配置外键后,单表和多表的关联维护问题

-Micheal-Schofield- 2014-05-07 03:00:05
请教高手们一个棘手的问题 —— hibernate 4 的增删改查都是在session中处理的,并且官方推荐使用getCurrentSession来获取session,但是使用getCurrentSession会让这些事务操作结束后就释放掉session;
如果只进行原子的增删改查操作不会有问题,但是遇到复杂一点的事务组合操作问题就来了.. ..
自己就在项目中遇到一个棘手的问题,描述如下:

假设有一张餐厅表,和一张菜品信息表,菜品信息表通过restId的外键与餐厅表关联,库表设计如下:



工程中两张表的实体类都使用注解的方式进行了配置:
restaurantInfo实体类中的配置细节如下:

private Set<DishInfo> dishInfos;
@OneToMany(cascade=CascadeType.ALL,mappedBy="restaurantInfo")
public Set<DishInfo> getDishInfo() {
return dishInfos;
}
public void setDishInfo(Set<DishInfo> dishInfos) {
this.dishInfos = dishInfos;
}


dishInfo实体类中的配置细节如下:

private RestaurantInfo restaurantInfo;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "restId")
public RestaurantInfo getRestaurantInfo(){
return restaurantInfo;
}

public void setRestaurantInfo(RestaurantInfo restaurantInfo){
this.restaurantInfo = restaurantInfo;
}

其中restId在数据库中是dishInfo表的外键,非null;

问题出现在维护两张表关联的过程:


上面的方法是希望在把dishInfo数据插入dishInfo表(多的一端,或成为owner端)的同时维护和restaurantInfo表的外键关联。方法的第二个参数是之前取出的restaurantInfo的对象(属性均有值),但执行到上图中语句 restaurantInfo .getDishInfo().add(dishInfo)时就会报异常,是lazyinitialization——no session的懒加载问题

个人debug分析以后猜测:
虽然之前取出了完整的restaurantInfo的对象以及里面的信息,但是取出之后session就关闭了,hibernate很可能将包含有取出对象信息的session释放掉了,导致在上面的方法中再去从restaurantInfo对象中获取restId时已经找不到数据,因此也就取不到dishInfo中restaurantInfo对象的restId值,没有办法给dishInfo表的外键restId赋值了

急着向各位Geeker请教一下,这个问题的解决方法;此外,由于hibernate 4 对session的管理方式与hibernate 3不同(不再推荐使用openSession和closeSession的控制方法),个人觉得懒加载问题肯定会经常遇到,因此也想向各位请教一下企业级的处理方式以及这类问题的最佳实践~
...全文
266 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
LeayAo 2014-05-16
  • 打赏
  • 举报
回复
<!-- 将HibernateSession开关控制配置在Filter,保证一个请求一个session,并对lazy提供支持 -->
	<filter>
		<filter-name>OpenSessionInView</filter-name>
		<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
		<init-param>
			<param-name>flushMode</param-name>
			<param-value>AUTO</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>OpenSessionInView</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
这个就是解决session关闭问题的
zuiai_LJX 2014-05-09
  • 打赏
  • 举报
回复
restaurantInfo .getDishInfo().add(dishInfo) 不应该手动维护吧。 save后重取一次restaurantInfo就好了
乔不思 2014-05-09
  • 打赏
  • 举报
回复
还有就是,表关联之间的维护关系。核心表维护非核心表。。楼主的注解存在问题
乔不思 2014-05-09
  • 打赏
  • 举报
回复
opensessioninview模式应该就是解决这个问题的。。
小律律 2014-05-09
  • 打赏
  • 举报
回复
好多字。给你顶顶。记得结贴
Mr_sqw 2014-05-09
  • 打赏
  • 举报
回复
不对,后面的要么应该是这样的

Set<DishInfo> dishInfos =restaurantInfo.getDishInfo();
if (dishInfos = null) {
  dishInfos  = new HashSet<DishInfo>;
  dishInfos .add(dishInfo);
  restaurantInfo.setDishInfo(dishInfos  );
}else{
  dishInfos .add(dishInfo);
}
session.save(restaurantInfo);

Mr_sqw 2014-05-09
  • 打赏
  • 举报
回复
要么 dishInfo.setRestaurentInfo(restaurantInfo); session.save(dishInfo); 要么 Set<DishInfo> dishInfos =restaurantInfo.getDishInfo(); if (dishInfos = null) dishInfos = new HashSet<DishInfo> dishInfos .add(dishInfo); session.save(restaurantInfo); 应该是这样的,你试试
Mr_sqw 2014-05-09
  • 打赏
  • 举报
回复
你已经设置在多方设置了cascade=CascadeType.ALL。
这一句貌似是多余的吧

  • 打赏
  • 举报
回复
先谢了哈~ 这问题困扰了整整2天,hibernate官方文档也看了不少,还是不知道该怎么解决,一起学习!
「已注销」 2014-05-07
  • 打赏
  • 举报
回复
mark!学习 ,帮你顶下!
  • 打赏
  • 举报
回复
先顶一下~这个问题让自己非常困扰,希望各位大大能一起帮我分析下,O(∩_∩)O谢谢!

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧