我正在開發一個使用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