欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

级联操作以及session延迟关闭

程序员文章站 2022-07-03 10:40:16
...
首页说级联操作的基本配置:
在实体中定义操作关联的对象
实体:

package com.tosit.ligc.entity;

import java.util.Date;
import java.util.Set;

public class Part {
	private Integer part_id;
	private Integer par_Part_id;
	private String part_name;
	private String part_content;
	private Date part_time;
	private String part_img;
	private Set<Part> part;
	private Set<Img> img;
	
	public Set<Part> getPart() {
		return part;
	}
	public void setPart(Set<Part> part) {
		this.part = part;
	}
	private Set<News> newsset;

	public Set<Img> getImg() {
		return img;
	}
	public void setImg(Set<Img> img) {
		this.img = img;
	}
	public Set<News> getNewsset() {
		return newsset;
	}
	public void setNewsset(Set<News> newsset) {
		this.newsset = newsset;
	}
	public Integer getPart_id() {
		return part_id;
	}
	public Part() {
		super();
	}
	public void setPart_id(Integer part_id) {
		this.part_id = part_id;
	}
	
	public String getPart_name() {
		return part_name;
	}
	public void setPart_name(String part_name) {
		this.part_name = part_name;
	}
	public String getPart_content() {
		return part_content;
	}
	public void setPart_content(String part_content) {
		this.part_content = part_content;
	}
	public Date getPart_time() {
		return part_time;
	}
	public void setPart_time(Date part_time) {
		this.part_time = part_time;
	}
	
	public Integer getPar_Part_id() {
		return par_Part_id;
	}
	public void setPar_Part_id(Integer par_Part_id) {
		this.par_Part_id = par_Part_id;
	}
	public String getPart_img() {
		return part_img;
	}
	public void setPart_img(String part_img) {
		this.part_img = part_img;
	}	
}


package com.tosit.ligc.entity;

public class Img {

	private Integer img_id;
	private String img_url;
	private String img_title;
	private Integer news_id;
	private Integer foods_id;
	private Integer stay_id;
	private Part part;
	
	public Part getPart() {
		return part;
	}
	public void setPart(Part part) {
		this.part = part;
	}
	public Integer getImg_id() {
		return img_id;
	}
	public void setImg_id(Integer img_id) {
		this.img_id = img_id;
	}
	public String getImg_url() {
		return img_url;
	}
	public void setImg_url(String img_url) {
		this.img_url = img_url;
	}
	public String getImg_title() {
		return img_title;
	}
	public void setImg_title(String img_title) {
		this.img_title = img_title;
	}
	public Integer getNews_id() {
		return news_id;
	}
	public void setNews_id(Integer news_id) {
		this.news_id = news_id;
	}
	public Integer getFoods_id() {
		return foods_id;
	}
	public void setFoods_id(Integer foods_id) {
		this.foods_id = foods_id;
	}
	public Integer getStay_id() {
		return stay_id;
	}
	public void setStay_id(Integer stay_id) {
		this.stay_id = stay_id;
	}		
}


配置文件:
Part.hbm.xml:

<?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">
        <!-- package 实体所在的包名 -->
      <hibernate-mapping package="com.tosit.ligc.entity">
      	<class name="Part" table="part">
      		<id name="part_id">
      			<generator class="increment"></generator>
      		</id>
      		<property name="part_name"></property>
      		<property name="part_content"></property>
      		<property name="part_time" ></property>
      		<!-- 级联操作 -->
      		<!-- 延迟加载 -->
      		<many-to-one name="par_Part_id" class="Part" column="par_Part_id" lazy="proxy" not-null="true" >
        	</many-to-one>
      		
      		<set name="part" table="part" cascade="all"  inverse="true">
<!--cascade: 它用于指定如何操纵与当前对象关联的其他对象 all表示所有,还有save-update persist,merge,delete等等 Inverse:负责控制关系,默认为false,也就是关系的两端都能控制,如果为ture表示把 关系交给对方控制,一般情况为true not-null表示保存时候不能为空 -->
      			<key column="par_Part_id" not-null="true"></key>
      			<one-to-many class="Part" />
      		
      		</set>
      		
      		<set name="img" table="img" cascade="all"  inverse="true">
      			<key column="part_id"></key>
      		<one-to-many class="Img"/>
      		</set>	
      	</class>	
      </hibernate-mapping> 

Img.hbm.xml:

<?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.tosit.ligc.entity">
        	<class name="Img" table="img">
        	<id name="img_id">
        	<generator class="native"></generator>
        	</id>
        	<property name="img_url"></property>
        	<property name="img_title"></property>
        	<property name="news_id"></property>
        	<property name="foods_id"></property>
        	<property name="stay_id"></property>
        	<many-to-one name="part" class="Part" column="part_id" lazy="proxy" not-null="true"/>
        	</class>
      </hibernate-mapping>

写代码的时候,在Controller中使用关联表的数据是否报no session错误。百度一下是因为在applicationContext.xml 中用来延迟加载
default-lazy-init="true" default-autowire="byName">
<!-- 是否延迟加载。通过名字实现自动装配 -->
在控制器调用的时候就会报no session 错误。因为session 在hibernate执行之后会自动关闭。所以找不到

package com.tosit.ligc.web;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.metadata.HanaCallMetaDataProvider;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.tosit.ligc.entity.News;
import com.tosit.ligc.entity.Part;
import com.tosit.ligc.service.PartService;
@Controller
public class PartController {
	@Autowired
	@Qualifier("partService")
	private PartService partService;
	/**
	 获取一级栏目信息
	 */
	@RequestMapping("/index")
	public  String index(ModelMap map){
    List<Part>	partlist =	partService.getPartlist();
	map.put("partlist", partlist);
	return "index";
	}
	/**
	 * 获取二级栏目信息
	 * 
	 */
	@RequestMapping("/onePart")
	public String onePart(ModelMap map,@RequestParam(value="id")Integer id){
		String result = "index";
		List<Part> onelist = partService.getPartlist(id);
		map.put("onelist", onelist);
		if(id==1){
			result="index";
		}else{
			result ="Second/Lj-NewList";
		}
		return result;
		
	}
	/**
	 * 获取动态信息
	 * 
	 */
	
	@RequestMapping("/newslist")
	public String newslist(ModelMap map,@RequestParam(value="id")Integer id){
		this.index(map);
		List<News> list = partService.getnewlist(id);
		map.put("list", list);
		return "Second/Lj-NewList";
	}
	
}


解决方案:在web.xml 配置一个过滤器。是hibernate自带的一个session延迟关闭过滤。注意的是在hibernate3和hibernate4配置的不一样。当然还有一种就是把延迟加载关闭,但是这样数据大了之后,造成服务器运行效率级低。

<!-- 可以使spring自动事务延迟到视图解析后(用完数据后)才关闭 ,解决hibernate的延迟加载问题-->
	<filter>
		<filter-name>osivFilter</filter-name>
		<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
		<init-param>
			<!-- 指定过滤器使用的sessionFactory bean id,默认就是sessionFactory -->
			<param-name>sessionFactoryBeanName</param-name>
			<param-value>sessionFactory</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>osivFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>