关于在测试类中,懒加载问题导致加载了主类之后,在测试类中引用集合类出现错误的问题

关于在测试类中,懒加载问题导致加载了主类之后,在测试类中引用集合类出现错误的问题:
主要原因是因为:hibernate的事物是给了spring管理,而测试类中写的代码,是不归spring管理的,把代码转移到service中去执行进行

在测试类:EmployeeServiceTest中直接运行

    @Test
    public void testEmployeeInDept(){
        try {
            Department department = DepartMentService.getDepartmentByName("ixin开发部");
            Set<Employee> set = department.getEmps();
            for (Employee employee : set) {
                System.out.println(employee.getName());
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }

出现错误:

    /**
     * 因为在测试代码中,事物是不归spring管理的,所以执行:
     * Department department = DepartMentService.getDepartmentByName("ixin开发部");
     *  的时候,还是有事物的,处于spring管理的事物范围之内,而执行完成之后,就断了。
     * 所以在:Set<Employee> set = department.getEmps();这个执行代码中,是获取不到内容的
     * 会报异常:
     * Hibernate: 
    select
        department0_.id as id1_0_,
        department0_.name as name2_0_ 
    from
        department department0_ 
    where
        department0_.name=?
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.xltx.productinfograb.domain.entity.Department.emps, could not initialize proxy - no Session
     */

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

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "department")
public class Department implements Serializable{

    private Long id;

    private String name;

    private Set<Employee> emps = new HashSet<>();
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    @Column(name = "name", length = 20)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    /**
     * 总结:mappedBy属性跟xml配置文件里的inverse一样。在一对多或一对一的关系映射中,如果不表明mappedBy属性,默认是由本方维护外键。但如果两方都由本方来维护的话,会多出一些update语句,性能有一定的损耗。

解决的办法就是在一的一方配置上mappedBy属性,将维护权交给多的一方来维护,就不会有update语句了。

至于为何要将维护权交给多的一方,可以这样考虑:要想一个国家的领导人记住所有人民的名字是不可能的,但可以让所有人民记住领导人的名字!

注意,配了mappedBy属性后,不要再有@JoinColumn,会冲突!
     * @return
     */
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "dept")
    public Set<Employee> getEmps() {
        return emps;
    }

    public void setEmps(Set<Employee> emps) {
        this.emps = emps;
    }

    @Override
    public String toString() {
        return "Department [id=" + id + ", name=" + name + ", emps=" + emps
                + "]";
    }

    public Department() {
        super();
        // TODO Auto-generated constructor stub
    }

}

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "employee")
public class Employee implements Serializable{

    private Long id;


    private String name;


    private float salary;


    private String email;


    private Department dept;

    public Employee() {
        super();
        // TODO Auto-generated constructor stub
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + ", salary=" + salary
                + ", email=" + email + ", dept=" + dept + "]";
    }
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    @Column(name = "name", length = 30)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    @Column(name = "salary")
    public float getSalary() {
        return salary;
    }

    public void setSalary(float salary) {
        this.salary = salary;
    }
    @Column(name = "email", length = 30)
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "dept", nullable = false)
    public Department getDept() {
        return dept;
    }

    public void setDept(Department dept) {
        this.dept = dept;
    }

}

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.xltx.orm.dao.BaseDao;
import com.xltx.productinfograb.domain.entity.Department;
import com.xltx.productinfograb.domain.entity.Employee;

@Service
@Transactional(readOnly = false, rollbackFor = Exception.class)
public class DepartMentService {

    @Autowired
    BaseDao baseDao;

    public Department add(Department department){
        Serializable id = baseDao.add(department);
        department = baseDao.get(Department.class, id);
        return department;
    }

    public Department getDepartmentByName(String departmentName){
        String hql = "From Department d where d.name = ?";
        Department department = baseDao.getFirstByHql(hql, departmentName);
        return department;
    }

    public void testEmployeeInDept(){
        Department department = getDepartmentByName("xxx开发部");
        Set<Employee> set = department.getEmps();
        for (Employee employee : set) {
            System.out.println(employee.getName());
        }
    }
}
package com.xltx.test;

import java.util.Set;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.xltx.productinfograb.domain.entity.Department;
import com.xltx.productinfograb.domain.entity.Employee;
import com.xltx.productinfograb.service.impl.DepartMentService;
import com.xltx.productinfograb.service.impl.EmployeeService;

@RunWith(SpringJUnit4ClassRunner.class)  //使用junit4进行测试  
@ContextConfiguration({"classpath:applicationContext.xml"}) //加载配置文件
public class EmployeeServiceTest {

    @Autowired
    EmployeeService employeeService;
    @Autowired
    DepartMentService DepartMentService;

    @Test
    public void add(){
        Department dept = DepartMentService.getDepartmentByName("ixin开发部");
        Employee employee = new Employee();
        employee.setDept(dept);
        employee.setEmail("13076684@qq.com");
        employee.setName("何冠宏");
        employee.setSalary(100000.00f);
        employeeService.add(employee);

        Employee employee2 = new Employee();
        employee2.setDept(dept);
        employee2.setEmail("111@qq.com");
        employee2.setName("22何冠宏");
        employee2.setSalary(200000.00f);
        employeeService.add(employee2);

        Employee employee3 = new Employee();
        employee3.setDept(dept);
        employee3.setEmail("33@qq.com");
        employee3.setName("33何冠宏");
        employee3.setSalary(300000.00f);
        employeeService.add(employee3);

    }

    /**
     * 因为在测试代码中,事物是不归spring管理的,所以执行:
     * Department department = DepartMentService.getDepartmentByName("ixin开发部");
     * 的时候,还是有事物的,处于spring管理的事物范围之内,而执行完成之后,就断了。
     * 所以在:Set<Employee> set = department.getEmps();这个执行代码中,是获取不到内容的
     * 会报异常:
     * Hibernate: 
    select
        department0_.id as id1_0_,
        department0_.name as name2_0_ 
    from
        department department0_ 
    where
        department0_.name=?
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.xltx.productinfograb.domain.entity.Department.emps, could not initialize proxy - no Session
     */
    @Test
    public void testEmployeeInDept(){
        try {
            Department department = DepartMentService.getDepartmentByName("ixin开发部");
            Set<Employee> set = department.getEmps();
            for (Employee employee : set) {
                System.out.println(employee.getName());
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }

    }

    /**
     * 将代码放到处于spring管理的service中去执行之后,就不会有问题了
     */
    @Test
    public void test1(){
        try {
            DepartMentService.testEmployeeInDept();
            System.out.println("");
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值