Hibernate 使用过程中(尤其是多对多关联中的级联保存和级联删除)的注意事项

Hibernate的多表关联关系映射、案例:一对多、多对一查询与删除、cascade级联保存、修改、删除、级联组合、案例:多对多、级联保存与外键维护、fetch、批量加载、检测策略-day03 目录第一节 Hibernate的多表关联关系映射1.1 多表关系1.2 案例:一对多、多对一第一步:实体类的编写第二步:映射文件的编写第三步:配置文件添加映射第四步:单元测试设置外键维护的方式查询一对多与删除 第一节 Hibernate的多表关联关系映射 1.1 多表关系 表之间关系存在3种:一对多、多对多、一对一 一对多:主表的主键 与 从表外键 形成 主外键关系 多对多:提供中间表(从表),提供2个字段(外键)分别对应两个主表。 一对一: 主外键关系 举例: 多对多关系:老师与学生 一对 阅读详情

(转载)Hibernate 使用过程中(尤其是多对多关联中的级联保存和级联删除)的注意事项

一.先上知识点:

1.hibernate多对多关联关系中最重要的参数是(基于配置文件xxx.hbm.xml文件形式):

1):inverse属性,如果设置inverse=“true”就代表让对方参与维护第三方表格。//这个属性特别重要,多对多关系中最好有且只有一个维护第三方表格,如果两方都维护第三方表格,那么可能第三方表格会重复维护现象(有可能会造成第三方表格联合主键的重复)

2):lazy属性,这个属性代表延迟加载与否,在讲这个属性之前,先讲一个东西,就是在hibernate多对多关联关系中,在双方的类中都会出现一个Set<XXX>这个集合属性(在读取过程中,这个set集合会被hibernate封装成persistentSet集合),当在xxx.hbm.xml文件中设置lazy=“false”时,就说明,不会让延迟加载起作用,那么这个延迟加载加载什么东西呢?延迟加载的东西就是刚刚提到的Set<XXX>集合中的东西,打个比方,现在有多对多的User类和Educate类(员工多对多培训课程),在User类中的java代码如下:

package com.ssh.entities;

import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

public class User {
    private Long id;//员工编号
    private String name;//员工用户名
    private String password;//登录密码
    private Byte sex;//性别
    private Date birthday;//生日
    private Date createtime;//创建时间
    private Byte isadmin;//是否为管理员
    private String content;//人员简介
    private Set<Educate> educate=new HashSet<Educate>();
    public Set<Educate> getEducate() {
        return educate;
    }
    public void setEducate(Set<Educate> educate) {
        this.educate = educate;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Byte getSex() {
        return sex;
    }
    public void setSex(Byte sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public Date getCreatetime() {
        return createtime;
    }
    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }
    public Byte getIsadmin() {
        return isadmin;
    }
    public void setIsadmin(Byte isadmin) {
        this.isadmin = isadmin;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public User(Long id, String name, String password, Byte sex, Date birthday,
            Date createtime, Byte isadmin, String content) {
        this.id = id;
        this.name = name;
        this.password = password;
        this.sex = sex;
        this.birthday = birthday;
        this.createtime = createtime;
        this.isadmin = isadmin;
        this.content = content;
    }
    public User() {
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", password=" + password
                + ", sex=" + sex + ", birthday=" + birthday + ", createtime="
                + createtime + ", isadmin=" + isadmin + ", content=" + content
                + "]";
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        User other = (User) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }
    
    
    
}

上述代码中标红的就是一个Set<Educate>集合。

 那我在User.hbm.xml文件中配置lazy="false"的时候,就是说明,当我前端或者后台需要加载user对象时,那这个带有对方(Educate类)的集合也会通过第三方表格顺带着把Educate类中的信息一起加载出来,

反之,当lazy="true"的时候就默认lazy延迟加载工程开启,也就是说Set集合中的东西,现在不会给加载出来。

3)cascade属性,我在项目中一般配置  cascade=“all”,这个就代表在级联操作时(保存、删除)会不会级联到关联的一方

总结:基于配置文件的hibernate 多对多就是lazy和inverse属性在起关键作用。

2.hibernate 多对多中的级联保存和删除:

1)保存,保存一般情况下不仅保存自己一方的对象到数据库,还需要顺带着把和另一方的关系也保存到第三方表格,那么这时,如果是自己这方是负责维护第三方表格的,那么当编辑自己对象的信息时(将集合中塞入对方对象到集合中,代表与对方的关系),在执行hibernate的session的saveOrupdate()方法时,不仅保存自己对象到数据库中,同时也会把维护关系保存到第三方表格中,如果自己这方没有负责维护第三方表格,那么即便自己这方的Set集合中添加了对方对象的信息,当执行hibernate的session的  saveorUpdate()方法时,只能是把自己的信息保存到自己对应的数据库中,与对方的关系(通过set集合中的信息进行设置,通过第三方的数据表格体现)的第三方表格,没有发生更新,也就是说没有达到想要的结果。

现在举例说明一下:

User类(如上)和User.hbm.xml文件:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.ssh.entities.User" table="user">
        <id column="id" name="id" type="java.lang.Long">
            <generator class="native"></generator>
        </id>
        <property name="name" length="50" type="java.lang.String"/>
        <property name="password" length="50" type="java.lang.String"/>
        <property name="sex" length="4" type="java.lang.Byte"/>
        <property name="birthday" length="23" type="java.util.Date"/>
        <property name="createtime" length="23"  type="java.util.Date"/>
        <property name="isadmin" length="4" type="java.lang.Byte"/>
        <property name="content" length="2000" type="java.lang.String"/>
        <set name="educate" table="user_educate" lazy="false" cascade="all" inverse="false">
            <key column="user_id"></key>
            <many-to-many class="com.ssh.entities.Educate" column="educate_id"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

Educate类和Educate.hbm.xml

package com.ssh.entities;

import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

public class Educate {
    private Long id;//培训标号
    private String name;//培训名称
    private String purpose;//培训目的
    private Date begintime;//培训开始时间
    private Date endtime;//培训结束时间
    private String datum;//培训材料
    private String teacher;//培训讲师
    private String student;//培训人员
    private Date createtime;//创建时间
    private Byte educate;//培训是否完成
    private String effect;//培训效果
    private String summarize;//培训总结
    private Set<User> user=new HashSet<User>();
    
    public Set<User> getUser() {
        return user;
    }
    public void setUser(Set<User> user) {
        this.user = user;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPurpose() {
        return purpose;
    }
    public void setPurpose(String purpose) {
        this.purpose = purpose;
    }
    public Date getBegintime() {
        return begintime;
    }
    public void setBegintime(Date begintime) {
        this.begintime = begintime;
    }
    public Date getEndtime() {
        return endtime;
    }
    public void setEndtime(Date endtime) {
        this.endtime = endtime;
    }
    public String getDatum() {
        return datum;
    }
    public void setDatum(String datum) {
        this.datum = datum;
    }
    public String getTeacher() {
        return teacher;
    }
    public void setTeacher(String teacher) {
        this.teacher = teacher;
    }
    public String getStudent() {
        return student;
    }
    public void setStudent(String student) {
        this.student = student;
    }
    public Date getCreatetime() {
        return createtime;
    }
    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }
    public Byte getEducate() {
        return educate;
    }
    public void setEducate(Byte educate) {
        this.educate = educate;
    }
    public String getEffect() {
        return effect;
    }
    public void setEffect(String effect) {
        this.effect = effect;
    }
    public String getSummarize() {
        return summarize;
    }
    public void setSummarize(String summarize) {
        this.summarize = summarize;
    }
    public Educate(Long id, String name, String purpose, Date begintime,
            Date endtime, String datum, String teacher, String student,
            Date createtime, Byte educate, String effect, String summarize) {
        this.id = id;
        this.name = name;
        this.purpose = purpose;
        this.begintime = begintime;
        this.endtime = endtime;
        this.datum = datum;
        this.teacher = teacher;
        this.student = student;
        this.createtime = createtime;
        this.educate = educate;
        this.effect = effect;
        this.summarize = summarize;
    }
    public Educate() {
    }
    @Override
    public String toString() {
        return "Educate [id=" + id + ", name=" + name + ", purpose=" + purpose
                + ", begintime=" + begintime + ", endtime=" + endtime
                + ", datum=" + datum + ", teacher=" + teacher + ", student="
                + student + ", createtime=" + createtime + ", educate="
                + educate + ", effect=" + effect + ", summarize=" + summarize
                + "]";
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Educate other = (Educate) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }
    
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.ssh.entities.Educate" table="educate">
        <id column="id" name="id" type="java.lang.Long">
            <generator class="native"></generator>
        </id>
        <property name="name" length="100" type="java.lang.String"></property>
        <property name="purpose" length="500" type="java.lang.String"/>
        <property name="begintime" length="23" type="java.util.Date"/>
        <property name="endtime" length="23" type="java.util.Date"/>
        <property name="datum" length="2000" type="java.lang.String"/>
        <property name="teacher" length="50" type="java.lang.String"/>
        <property name="student" length="50" type="java.lang.String"/>
        <property name="createtime" length="23" type="java.util.Date"/>
        <property name="effect" length="500" type="java.lang.String"/>
        <property name="educate" length="1" type="java.lang.Byte"/>
        <property name="summarize" length="2000" type="java.lang.String"/>
        <set name="user" table="user_educate" lazy="true" cascade="all" inverse="true">
            <key column="educate_id"></key>
            <many-to-many class="com.ssh.entities.User" column="user_id"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

 

后台控制的java代码(保存和另一方关系的代码):

public String insertcourse(){
		String[] para=request.getParameterValues("edupara");
		String userid=request.getParameter("userid");
		
		if(para.length>0){
 			User us=userService.getUser(Long.parseLong(userid));
			Set<Educate> edus=new HashSet<Educate>();
			edus=us.getEducate();
			for(String str: para ){
				Educate	educate=educateService.getForEdu(Long.parseLong(str));
			/*	Set users=new HashSet<User>();
				users=educate.getUser();
				System.out.println(users.size());
				users.add(us);
				System.out.println(users.size());
				educate.setUser(users);
				
				educateService.saveorUpdate(educate);
			*/
				edus.add(educate);
			}
			us.setEducate(edus);
			userService.saveOrUpdate(us);
		}
		return "insertcourse";

  2)删除级联的注意事项:

 (1)如果不是User维持关联关系:

           ——若连接表user_educate中有参照user表中该记录的记录(即在user_educate表中存在user_id的记录)时,则删除失败。

           ——若连接表user_educate中没有参照user表中该记录的记录时,则可以成功地将该记录删除。

     (2)如果是User维持关联关系:

           ——先将连接表user_educate中参照user表中该记录的记录删除,然后将该学生记录从user表中删除

 

最后附上后台处理的完整代码:

UserAction.java

package com.ssh.action;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;





import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.interceptor.ServletRequestAware;

import com.opensymphony.xwork2.ActionSupport;
import com.ssh.entities.Educate;
import com.ssh.entities.User;
import com.ssh.service.EducateService;
import com.ssh.service.UserService;


public class HumanAction extends ActionSupport implements ServletRequestAware{
    
    /**
     * @author zhangshitong
     */
    private static final long serialVersionUID = 1L;
    private String username;
    private String password;
    
    private UserService userService;
    
    private InputStream inputStream;
    
    private HttpServletRequest request;
    
    private Long id;
    
    private List<Educate> eduList;
    
    private List<User> userList;
    
    private EducateService educateService;
    
    private User userForEdit;



    public void setEducateService(EducateService educateService) {
        this.educateService = educateService;
    }
    
    public void setId(Long id) {
        this.id = id;
    }
    private User user;
    public void setUser(User user) {
        this.user = user;
    }
    public User getUser() {
        return user;
    }
    public InputStream getInputStream() {
        return inputStream;
    }
    
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public String getUsername() {
        return username;
    }


    public void setUsername(String username) {
        this.username = username;
    }


    public String getPassword() {
        return password;
    }


    public void setPassword(String password) {
        this.password = password;
    }

    public String adduser(){
        user.setCreatetime(new Date());
        //user.setId(null);
        System.out.println(user);
        userService.saveOrUpdate(user);
        user = null;
        return "add";
    }
    
    public String list(){
        System.out.println(userService.getForList());
        request.setAttribute("user", userService.getForList());
        return "list";
    }
    
    public String select(){
        User usertemp=userService.getUser(id);
        this.userForEdit=usertemp;
        request.setAttribute("signalUser", usertemp);
        return "edit";
    }
    
    public String delete(){
        userService.deleteUser(id);
        try {
            inputStream = new ByteArrayInputStream("1".getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            try {
                inputStream = new ByteArrayInputStream("0".getBytes("UTF-8"));
            } catch (UnsupportedEncodingException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            e.printStackTrace();
        }
        return "ajax-success";
    }
    
    public String modify(){
        user.setEducate(userForEdit.getEducate());
        user.setCreatetime(new Date());
        System.out.println(user);
        userService.saveOrUpdate(user);
        return "modified";
    }

    
    public String login(){
        User user=userService.validName(username);
        
        if(user==null){
            try {
                inputStream = new ByteArrayInputStream("3".getBytes("UTF-8"));
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }else{
        if(user.getPassword().equals(password)){
        try {request.getSession().setAttribute("user", user);
            inputStream = new ByteArrayInputStream("1".getBytes("UTF-8"));
            //ctx.getSession().put("user", user);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }    
        }else{
            try {
                inputStream = new ByteArrayInputStream("0".getBytes("UTF-8"));
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        }
        
        return "ajax-success";
    }
    
    public String userselecteducate(){
        System.out.println("这是查看员工选择课程时员工的id值:"+id);
        Set eduSet=userService.getEducateInUser(id);
        //System.out.println(eduSet);
        List<Educate> eduList=new ArrayList<Educate>();
        Iterator it=eduSet.iterator();
        while(it.hasNext()){
            Educate eduTemp=(Educate) it.next();
            eduList.add(eduTemp);
        }
        request.setAttribute("edu", eduList);
        request.setAttribute("name", username);
        request.setAttribute("id", id);
        return "userselecteducate";
    }

    public String insertcourse(){
        String[] para=request.getParameterValues("edupara");
        String userid=request.getParameter("userid");
        
        if(para.length>0){
             User us=userService.getUser(Long.parseLong(userid));
            Set<Educate> edus=new HashSet<Educate>();
            edus=us.getEducate();
            for(String str: para ){
                Educate    educate=educateService.getForEdu(Long.parseLong(str));
            /*    Set users=new HashSet<User>();
                users=educate.getUser();
                System.out.println(users.size());
                users.add(us);
                System.out.println(users.size());
                educate.setUser(users);
                
                educateService.saveorUpdate(educate);
            */
                edus.add(educate);
            }
            us.setEducate(edus);
            userService.saveOrUpdate(us);
        }
        return "insertcourse";
    }
    
    public String deletecourse(){
        String userid=request.getParameter("userid");
        User us=userService.getUser(Long.parseLong(userid));
        Educate edu=educateService.getForEdu(id);
        //edu.getUser().remove(us);
        Set<Educate> educates=new HashSet<Educate>();
        educates=us.getEducate();
        educates.remove(edu);
        us.setEducate(educates);
        userService.saveOrUpdate(us);
        try {
            inputStream = new ByteArrayInputStream("1".getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            try {
                inputStream = new ByteArrayInputStream("0".getBytes("UTF-8"));
            } catch (UnsupportedEncodingException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            e.printStackTrace();
        }
        return "ajax-success";
    }
    @Override
    public void setServletRequest(HttpServletRequest arg0) {
        // TODO Auto-generated method stub
        this.request=arg0;
    }
}

EducateAction类:

package com.ssh.action;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.interceptor.ServletRequestAware;

import com.opensymphony.xwork2.ActionSupport;
import com.ssh.entities.Educate;
import com.ssh.entities.User;
import com.ssh.service.EducateService;
import com.ssh.service.UserService;

public class EducateAction extends ActionSupport implements ServletRequestAware{

    /**
     * @author Administrator zhangshitong
     */
    private static final long serialVersionUID = 1L;
    
    private Educate educate;
    
    private EducateService educateService;
    
    private HttpServletRequest request;
    
    private InputStream inputStream;
    
    private Long id;
    
    private UserService userService;
    
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    
    public void setId(Long id) {
        this.id = id;
    }
    
    public Long getId() {
        return id;
    }
    public InputStream getInputStream() {
        return inputStream;
    }
    public void setEducateService(EducateService educateService) {
        this.educateService = educateService;
    }
    
    
    
    public Educate getEducate() {
        return educate;
    }




    public void setEducate(Educate educate) {
        this.educate = educate;
    }

    public String addeducate(){
        educate.setCreatetime(new Date());
        System.out.println(educate);
        educateService.saveorUpdate(educate);
        return "addeducate";
    }

    public String listeducate(){
        List<Educate> list=educateService.getForList();
        request.setAttribute("educate", list);
        return "listeducate";
    }
    
    public String delete(){
        System.out.println("this is id's value:"+id);
        //Set<User> users=new HashSet<User>();
        //users=null;
        List<User> userList=userService.getForList();
        Educate edu=educateService.getForEdu(id);
        Iterator<User> it=userList.iterator();
        while(it.hasNext()){
            User userListMember=it.next();
            Set<Educate> setEducate=userListMember.getEducate();
            if(setEducate.contains(edu)){
                setEducate.remove(edu);
            }
            userService.saveOrUpdate(userListMember);
        }
        //edu.setUser(users);
        //educateService.saveorUpdate(edu);
          educateService.delete(id);
        //educateService.deleteCascade(edu);
        try {
            inputStream = new ByteArrayInputStream("1".getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            try {
                inputStream = new ByteArrayInputStream("0".getBytes("UTF-8"));
            } catch (UnsupportedEncodingException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            e.printStackTrace();
        }
        return "ajax-success";
    }
    
    public String addcourse(){
        List<Educate> list=educateService.getForList();
        request.setAttribute("educate", list);
        request.setAttribute("userid", id);
        return "addcourse";
    }
    @Override
    public void setServletRequest(HttpServletRequest arg0) {
        // TODO Auto-generated method stub
        this.request=arg0;
    }

}

spring的application配置文件(事务管理):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    <!-- 导入资源文件 -->
        <context:property-placeholder location="classpath:db.properties"/>

    <!-- 配置 C3P0 数据源 -->
        <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="user" value="${jdbc.user}"></property>
            <property name="password" value="${jdbc.password}"></property>
            <property name="driverClass" value="${jdbc.driverClass}"></property>
            <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
            <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
            <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
        </bean>
    
    <!-- 配置 SessionFactory -->
        <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource"></property>
            <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
            <property name="mappingLocations" value="classpath:com/ssh/entities/*.hbm.xml"></property>
            <property name="hibernateProperties">
                <props>
                      <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>    
                </props>
            </property>
        </bean>
    <!-- 配置 Spring 的声明式事务 -->
    
      <!-- 1. 配置 hibernate 的事务管理器 -->
        <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory"></property>
        </bean>
      <!-- 2. 配置事务属性 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="get*" read-only="true"/>
                <tx:method name="*"/>
            </tx:attributes>
        </tx:advice>
      <!-- 3. 配置事务切入点, 再把事务属性和事务切入点关联起来 -->
          <aop:config>
              <aop:pointcut expression="execution(* com.ssh.dao.*.*(..))" id="txPointcut"/>
              <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
          </aop:config>
</beans>

web.xml配置的过滤器:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <filter>
        <filter-name>hibernateFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
        <init-param>
            <param-name>sessionFactoryBeanName</param-name>
            <param-value>sessionFactory</param-value>
        </init-param>
        <init-param>
            <param-name>singleSession</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>hibernateFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

 

hibernate5(14)注解映射[6]多对多中间表关联 在我们的角色管理系统中,一个用户可以有多种角色,一种角色可以赋予多个用户,显然用户和角色就是典型的多对多关系。又或者博客网站上,用户与文章点赞记录也是一个多对多关系,即一个用户可以点赞多篇文章,一篇文章可以给多个用户点赞等,这时候,我们往往需要附加一些信息,比如授权时间、点赞时间等。在上面两个实例中,都可对应于hibernate多对多映射关系的两种方式,在多对多映射中,我们往往使用中间表来建立关联关 阅读详情

相关推荐

Hibernate 关联关系 之 多对多

Hibernate 关联关系 之 多对多Hibernate 多对多关联关系数据库表entity 实体类BookCategoryTreeNodexml 配置book.hbm.xmlcategory.hbm.xmlTreeNode.hbm.xmlhibernate.cfg.xmlDaoBookDaoBookDaoTestTreeNodeDaoTreeNodeTest Hibernate 多对多关联关系...

qq_44641053的博客 536

(原创)Hibernate 使用过程中(尤其是多对多关联中的级联保存和级联删除)的注意事项(基于项目的总结)...

一.先上知识点: 1.hibernate多对多关联关系中最重要的参数是(基于配置文件xxx.hbm.xml文件形式): 1):inverse属性,如果设置inverse=“true”就代表让对方参与维护第三方表格。//这个属性特别重要,多对多关系中最好有且只有一个维护第三方表格,如果两方都维护第三方表格,那么可能第三方表格会重复维护现象(有可能会造成第三方表格联合主键的重复) 2):lazy...

weixin_30439131的博客 233

AVS3代码阅读HPM4.0

参考AVS3代码阅读(HPM6.0)(一.整体架构以及CU划分部分代码) 版本:HPM4.0 核心文件:app_encoder.c   要做的是帧间预测,所以前面的函数先暂时不管了,挖个坑以后再填。直接从enc_pic看起。 enc_pic()    ...

CRR的博客 3187

六、Spring Data JPA多对多操作

1、多对多表的保存操作 实体类: @Entity @Table(name = "sys_user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="user_id") private Long userId; @Column...

a2231476020的博客 2465

Veritas NetBackup 10.1 Windows安装指南:从账户配置到完整部署

本文详细介绍了Veritas NetBackup 10.1在Windows系统上的完整安装流程,从账户配置到部署验证。重点讲解了创建专用服务账户、安装组件选择、许可证输入等关键步骤,并提供了常见问题排查和进阶配置建议,帮助用户顺利完成企业级备份解决方案的部署。

weixin_26765287的博客 454

微生物16S数据上传NCBI的SRA库

本篇内容仅包括:俺自己的实验收集了淡水、淡水沉积物、海水、海草附着微生物样品,测序所得的Fastq格式数据,在文章投稿发表时被要求数据需上传NCBI的SRA库,得到一个PRJNA2347899这样子的IDs。仅解决了这个上传过程!

Xf_Niu的博客 7435

HIbernate--多对多的级联操作(保存、更新、删除)详解

级联操作 多对多的级联操作同一对多和多对一是一样的。如果只保存单独的一方是不可以的,还是需要保存双方的。如果想保存一方就需要设置级联操作。同样需要设置主控方。 创建表 创建sys_user、sys_role、sys_user_role三张表: 创建实体 User: public class User { //主键 private Long user_id; private String u...

吴声子夜歌的博客 1400

PID不够用?试试给PID加上‘预言’能力:史密斯预测器(SP)在温控、液位控制中的实战配置

本文深入探讨了史密斯预测器(SP)在温控和液位控制中的应用,特别针对大滞后系统的PID控制难题。通过详细解析SP的核心组件、参数整定技巧及进阶应用FSP,结合西门子PLC的实战配置方案,帮助工程师有效提升控制精度和系统稳定性。文章还提供了S7-1200的完整实现步骤和调试技巧,为工业自动化控制提供了实用解决方案。

weixin_33686714的博客 469

Hibernate一对多关联关系保存时的探究

在以前使用hibernate时,经常对保存存在关联关系的对象时,不确定是否能保存成功。 因此,特意对一对多关系的2个对象进行实践。一、pojo类和配置文件的准备 这里有一点提前说一下,外键列在数据库中并没有设置为不为null。因此可以出现外键为空的情况。(1)pojo类 (2)映射文件 (3)测试类中方法的准...

279

将AAL图谱对应到Yeo7大网络中【原理,代码分析】

本文介绍了将AAL2图谱映射到Yeo7大功能网络的方法。通过整合皮层(Yeo2011)、小脑(Buckner2011)和纹状体(Choi2012)三个区域的功能网络图谱,采用投票机制确定每个AAL区域的网络归属。具体步骤包括:1)统计每个AAL区域体素在各网络图谱中的分布;2)选择体素数量最多的网络作为该区域的最终标签。该方法实现了从解剖结构到功能网络的映射,可获得120个AAL区域对应的7大功能网络标签。

yes666666的博客 2206

TC3XX - MCAL知识点(三十五):Tasking编译器下,Tc3xx的MCAL代码如何使用多核,多核中断、多核任务、多核外设之间的MCAL配置与代码例程

文章用于记录在裸机情况下使用多核Tc387芯片,如何高效运行以及正确的代码、工程属性、链接文件配置等问题,相互结合、相互影响的地方,以示后续使用记录。

梦想技术家 963

hibernate 多对多出现先删除后插入的问题

在hibernate 多对多出现先删除后插入的问题,是应为使用了List集合,

hjtk009的专栏 1427

构建具有预测维护能力的AI Agent

随着工业4.0的推进,工业设备的复杂性和自动化程度不断提高,设备的稳定运行对于企业的生产效率和经济效益至关重要。预测维护作为一种先进的设备维护策略,能够通过对设备状态的实时监测和分析,提前预测设备故障,从而避免设备意外停机,降低维护成本。本文的目的是详细阐述如何构建具有预测维护能力的AI Agent,涵盖从数据采集、处理、模型训练到实际应用的整个流程,为企业和开发者提供全面的技术指导。本文将按照以下结构进行组织:首先介绍核心概念与联系,包括预测维护和AI Agent的基本原理和架构;

2501_92132293的博客 943

16. Hibernate 双向多对多关联映射

通过本节课程的学习,你将发现关联对象之间的微妙关系。相信这种关系对你更深入地认识HIbernate有很大的帮助。多对多双向关联映射中哪一方是关系维系者;级联操作与关系维系者。

这是一个web全栈开发的博客,取其精华去其糟粕,争取让大家一看就懂,一学就会,一用就成~ 967

基于深度学习的野生菌菇检测识别分类系统(YOLOv8 + UI界面 + 数据集)

随着深度学习技术的迅猛发展,计算机视觉领域的应用得到了广泛的关注。野生菌菇的检测与识别是一个复杂而又有趣的问题,涉及到物体检测、图像分类以及自然语言处理等技术。本文将介绍如何基于YOLOv8模型,结合自定义UI界面与数据集,构建一个高效且精确的野生菌菇检测识别分类系统。首先,我们将介绍YOLOv8的原理与特点,然后详细描述如何构建和训练野生菌菇识别模型,并介绍如何为该系统设计UI界面,最终形成一个完整的系统。本文内容包括代码实现、模型训练及数据集准备等,旨在为有类似需求的开发者提供参考和帮助。目录摘要目录。

YOLO 1547

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

hibernate多对多级联保存、级联删除

hibernate多对多级联操作

BlackEn ▪ Lee 2207

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

17. Hibernate 双向多对多关联映射

通过本节课程的学习,你将发现关联对象之间的微妙关系。相信这种关系对你更深入地认识HIbernate有很大的帮助。多对多双向关联映射中哪一方是关系维系者;级联操作与关系维系者。

这是一个web全栈开发的博客,取其精华去其糟粕,争取让大家一看就懂,一学就会,一用就成~ 908

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

hibernate 的级联保存和关联关系

转自:http://joezheng123.javaeye.com/blog/346877Customer 和 Orders 是一对多的关系,Orders和Customer是多对一关系,即这两个双向关联.Customer 和Bid是一对一的关系,一对一的关系就不存在双向和单向了如下是他们的类:customer.javaimport java.util.Date; import java.util.HashSet; import java.util.Set; public class Customer

qqzhuyuehe的专栏 1974

Hibernate级联保存和更新

级联保存和更新当Hibernate持久化一个临时对象时,在默认情下,他不会自动持久化所关联的其他临时对象,如果希望当持久化对象时把他所关联的所有临时对象进行持久化的话:可以把 的cascade属性设置为"save-update" ,cascade的默认属性值为none。cascade:设置操作对象时的级联操作,即层级之间的连锁操作值 save-update :表示当保存和更新当前对象(即inser

银狐的专栏 7876

hibernate中的关联之多对多

hibernate中的关联之多对多一、数据库的多对多1.1 数据库中不能直接映射多对多二、 hibernate的多对多2.1 hibernate可以直接映射多对多关联关系(看作两个一对多)三、多对多关系注意事项3.1 一定要定义一个主控方3.2 多对多删除3.2.1 主控方直接删除3.2.2 被控方先通过主控方解除多对多关系,再删除被控方3.2.3 禁用级联删除3.3 关联关系编辑,不需要直接操作桥接表,hibernate的主控方会自动维护示例1:新增一本书及书本类型示例2:新增一本书及已有的书本类型示例3

qq_47906421的博客 163

hibernate关联关系(多对多)

1. 数据库的多对多 1.1 数据库中不能直接映射多对多 处理:创建一个桥接表(中间表),将一个多对多关系转换成两个一对多 注1:数据库多表联接查询 永远就是二个表的联接查询 A B C D t1 C t2 D t3 注2:交叉连接 注3:外连接:left...

xieminglu的博客 226

Hibernate注解中的manytomany级联与不级联删除问题的解决

两个类用户信息和用户Tag类型  多对多的关系 1.用户信息类 package com.yunmiao.bean.player; import java.util.Date; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persisten

逍遥飞鹤的专栏 1万+

Hibernate入门第十一讲——Hibernate的多对多关联映射

在上一讲中,已经讲解过Hibernate中的一对多关联映射了,现在在其基础上,我们来讲解一下Hibernate中的多对多关联映射。 环境搭建 创建表 这里我们以用户(User)与角色(Role)为例来讲解Hibernate关联映射中的多对多关联关系,因此我们要在数据库下新建三张表——用户表、角色表以及中间表,这里笔者使用的数据库是MySQL。 CREATE TABLE `sys_user` ( ...

李阿昀的博客 1479

Hibernate的多对多关联映射

文章目录1. Hibernate多对多的关联映射案例1.1 创建表结构1.2 编写实体类1.3 编写映射文件1.4 编写核心配置文件1.5 编写测试类2. Hibernate多对多的相关操作2.1 级联保存或更新2.2 级联删除2.3 多对多的其他操作 1. Hibernate多对多的关联映射案例 1.1 创建表结构 用户表的建表语句: CREATE TABLE `sys_user` ( `us...

weixin_45990046的博客 180

Hibernate多对多的关系映射,详解(代码+图解)与应用 举个栗子,搞的清楚

外链图片转存中…(img-JVIdQqx3-1713382780713)][外链图片转存中…(img-6KeZowrn-1713382780714)][外链图片转存中…(img-tV1lyeIK-1713382780714)]

2401_84409711的博客 1085

Hibernate 一对多自关联 多对多

Hibernate 一对多自关联 多对多数据库的多对多entityBookCategoryTreeNode流程:book.hbm.xmlcategory,hbm.xmlTreeNode.hbm.xmlDaoBaoDaoBookDaoTestTreeNodeDaoTreeNodeDaoTest输出结果为: 数据库的多对多 1.1 数据库中不能直接映射多对多 处理:创建一个桥接表(中间...

what_to的博客 457
上一篇: Hibernate的详细教程
下一篇: Hibernate查询
csdn_phy
博客等级 码龄9年 15粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值