我正在开发一个使用Hibernate和JSF/primefaces的Java Web应用程序。 我有时得到错误等休眠,会话,延迟加载
1)与相同标识符的对象已经与会话相关联。
2)未能加载延迟初始化*,没有会话存在或者会话已经关闭。
我知道这是由于我的应用程序编码不正确。 这是我在做的一个方法:
当用户请求一个页面(让它成为员工列表)。 用户将获得员工列表页面(empployeeList.xhtml) EmployeeListMBean是此页面的托管bean。 在构造函数的托管bean中调用方法populateEmployees()。 populateEmployee()将使用EmployeeDao方法getAllEmployee()来getAllemployees。
Employee类放在这里:
@Entity
@Table(name = "Employee")
@NamedQueries({
@NamedQuery(name = "Employee.getAllEmployee", query = "from Employee"),
@NamedQuery(name = "Employee.findEmployeeByFirstName", query = "from Employee where firstName = :firstName"),
@NamedQuery(name = "Employee.findEmployeeByLastName", query = "from Employee where lastName = :lastName"),
@NamedQuery(name = "Employee.findEmployeeByMiddleName", query = "from Employee where middleName = :middleName"),
@NamedQuery(name = "Employee.findEmployeeByOffice", query = "from Employee where office.id = :officeId")
})
public class Employee implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "EID")
private long id;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
@Column(name = "GENDER")
private String gender;
@Column(name = "DOB")
@Temporal(javax.persistence.TemporalType.DATE)
private Date dateOfBirth;
@Column(name = "DOH")
@Temporal(javax.persistence.TemporalType.DATE)
private Date dateOfHire;
@ManyToOne(cascade= CascadeType.ALL)
private Office office;
@OneToOne(cascade = CascadeType.ALL)
private ResidenceAddress residence;
@OneToMany
private List<Project> projects;
//getters and setters
}
这里是我的EmployeeDao:
public class EmployeeDao implements Serializable{
private SessionFactory factory;
private Session session;
public void addEmployee(Employee employee){
factory = HibernateUtil.getSessionFactory();
session = factory.openSession();
session.beginTransaction();
session.save(employee);
session.getTransaction.commit();
}
public List<Employee> getAllEmployee(){
factory = HibernateUtil.getSessionFactory();
session = factory.openSession();
session.beginTransaction();
List<Employee> cities = session.getNamedQuery("Employee.getAllEmployee").list();
session.close();
return cities;
}
public Employee getEmployeeByEmployeeId(long employeeId){
factory = HibernateUtil.getSessionFactory();
session = factory.openSession();
session.beginTransaction();
Employee employee = (Employee) session.get(Employee.class, employeeId);
session.close();
return employee;
}
}
问题1) 这里,在这些方法中我将结束会话,然后返回回结果到managedbeans。 所以在员工列表页面列表中列出了名字dob dateOfHire。我有一个buutton查看更多细节。在点击这个按钮时,我想显示选定的员工使用相同的managedbeans的所有项目,但它给我错误(2),lazyload失败,没有会话或会话已经关闭。 如果我保持在dao的getemployeeMethod中打开会话,我猜可能会导致内存泄漏问题或其他问题。是这样吗? 也,我尝试了懒惰和渴望加载。请告诉我何时/如何使用这些类型的抓取。 我该如何解决这个问题?我可以去过滤器或facelisteners解决这个问题吗?
问题2) 如果试图编辑雇员的项目,并使用session.saveorupadte(),merge(),flush()更新,我得到这样的错误,“具有相同标识符的对象是已经与会话相关“ 我该如何解决这个问题?
问题3) 我知道这个SessionFactory是比较消耗资源。所以只有一个实例就足够用于一个应用程序。但会话呢? 对于单用户的应用程序,只需要一个会话? 请告诉我开发这样的应用程序的好策略。
感谢大家:)
这确实是多个问题。如果您专注于每个问题的一个问题,您可能会得到更好的答复。 – 2012-04-08 12:26:32