the exception is:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.ws.Library.bookList, no session or session was closed
so, one possible solution is to clone the entity if it will be used out of session..
a simple example web service project:
Book.java
package com.example.ws;
import java.io.Serializable;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;
@Entitypublic class Book implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id;
private String title;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
@Override public int hashCode() { int hash = 0; hash += (id != null ? id.hashCode() : 0); return hash; }
@Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof Book)) { return false; } Book other = (Book) object; if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { return false; } return true; }
@Override public String toString() { return "com.example.ws.Book[id=" + id + "]"; }
}
Library.java
package com.example.ws;
import java.io.Serializable;import java.util.ArrayList;import java.util.List;import javax.persistence.CascadeType;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.OneToMany;
@Entitypublic class Library implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id;
private String name;
@OneToMany(fetch = FetchType.LAZY, cascade= CascadeType.ALL) private List bookList = new ArrayList();
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public List getBookList() { return bookList; }
public void setBookList(List bookList) { this.bookList = bookList; }
public String getName() { return name; }
public void setName(String name) { this.name = name; } @Override public int hashCode() { int hash = 0; hash += (id != null ? id.hashCode() : 0); return hash; }
@Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof Library)) { return false; } Library other = (Library) object; if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { return false; } return true; }
@Override public String toString() { return "com.example.ws.Library[id=" + id + "]"; }
}
HibernateUtil.java
package util;
import com.example.ws.Book;import com.example.ws.Library;import java.util.ArrayList;import java.util.List;import javax.persistence.EntityManager;import javax.persistence.EntityManagerFactory;import javax.persistence.Persistence;import javax.persistence.PersistenceUnit;import javax.persistence.Query;
/** * * @author hilal.tarakci */public class HibernateUtil {
@PersistenceUnit(unitName = "HibernateLazyInitFixPU") private EntityManagerFactory emf = null;
public EntityManager getEntityManager() { if (emf == null) { emf = Persistence.createEntityManagerFactory("HibernateLazyInitFixPU"); } return emf.createEntityManager(); }
public void create(Library item) throws Exception { EntityManager em = null; try { em = getEntityManager(); em.getTransaction().begin(); em.persist(item); em.getTransaction().commit(); } catch (Exception ex) { try { if (em != null) { em.getTransaction().rollback(); } } catch (Exception re) { re.printStackTrace(); } throw ex; } finally { if (em != null) { em.close(); } } }
public List retrieveRecordsOfBook() {
EntityManager em = getEntityManager(); try { Query q = em.createQuery("select object(o) from Book as o");
List bookList = new ArrayList(); List tempBookList = q.getResultList();
for (Book tempBook : tempBookList) { Book book = new Book(); book.setId(tempBook.getId()); book.setTitle(tempBook.getTitle());
bookList.add(book); }
return bookList; } finally { em.close(); }
}
public List retrieveRecordsOfLibrary() {
EntityManager em = getEntityManager(); try { Query q = em.createQuery("select object(o) from Library as o");
List libList = new ArrayList();
List tempLibList = q.getResultList();
for (Library tempLib : tempLibList) { Library lib = new Library(); lib.setId(tempLib.getId()); lib.setName(tempLib.getName());
List bookList = new ArrayList();
for(Book tempBook: tempLib.getBookList()) { Book book = new Book(); book.setId(tempBook.getId()); book.setTitle(tempBook.getTitle());
bookList.add(book); }
lib.setBookList(bookList);
libList.add(lib); }
return libList;
} finally { em.close(); }
}}
HibernateLazyInit.java
package com.example.ws.service;
import com.example.ws.Book;import com.example.ws.Library;import java.util.List;import javax.jws.Oneway;import javax.jws.WebMethod;import javax.jws.WebService;import util.HibernateUtil;
@WebService()public class HibernateLazyInit {
private HibernateUtil util = new HibernateUtil();
@WebMethod(operationName = "insertRecords") @Oneway public void insertRecords() { try { Book book1 = new Book(); book1.setTitle("A Good Story");
Book book2 = new Book(); book2.setTitle("A Bad Story");
Library library1 = new Library(); library1.setName("An Excellent Library");
library1.getBookList().add(book1); library1.getBookList().add(book2);
util.create(library1);
} catch (Exception ex) { ex.printStackTrace(); } }
@WebMethod(operationName = "retrieveRecordsOfBook") public List retrieveRecordsOfBook() { return util.retrieveRecordsOfBook(); }
@WebMethod(operationName = "retrieveRecordsOfLibrary") public List retrieveRecordsOfLibrary() { return util.retrieveRecordsOfLibrary();
}}
.. and the client call
public class Main {
void insertRecords() {
try { // Call Web Service Operation com.example.ws.service.HibernateLazyInitService service = new com.example.ws.service.HibernateLazyInitService(); com.example.ws.service.HibernateLazyInit port = service.getHibernateLazyInitPort(); port.insertRecords(); } catch (Exception ex) { // TODO handle custom exceptions here ex.printStackTrace(); }
}
int retrieveRecordsOfBook() {
try { // Call Web Service Operation com.example.ws.service.HibernateLazyInitService service = new com.example.ws.service.HibernateLazyInitService(); com.example.ws.service.HibernateLazyInit port = service.getHibernateLazyInitPort(); // TODO process result here java.util.List result = port.retrieveRecordsOfBook(); System.out.println("Result = "+result);
return result.size(); } catch (Exception ex) { // TODO handle custom exceptions here ex.printStackTrace();
return 0; }
}
int retrieveRecordsOfLibrary() {
try { // Call Web Service Operation com.example.ws.service.HibernateLazyInitService service = new com.example.ws.service.HibernateLazyInitService(); com.example.ws.service.HibernateLazyInit port = service.getHibernateLazyInitPort(); // TODO process result here java.util.List result = port.retrieveRecordsOfLibrary(); System.out.println("Result = "+result);
return result.size();
} catch (Exception ex) { // TODO handle custom exceptions here ex.printStackTrace();
return 0; }
}
public static void main(String[] args) { // TODO code application logic here
Main client = new Main(); client.insertRecords(); System.out.println("Size of books : " + client.retrieveRecordsOfBook() ); System.out.println("Size of library : " + client.retrieveRecordsOfLibrary() ); }
btw, the ide is netbeans 6.5.1 with glassfish.
Edit on 11:14 :
the above solution is good when you want to use standard jpa and stay away from hibernate specific solutions..
but if it is ok to use hibernate specific annotations, you can try @Fetch(FetchType.JOIN)..
Edit on 14/12/2010 :
HibernateBeanReplicator is also a solution.. see http://hilaltarakci.blogspot.com/2009/09/java-deep-clone-library.html for details..
Hiç yorum yok:
Yorum Gönder