# org.hibernate.LazyInitializationException: failed to lazily



## FT77 (26. Jul 2007)

Hallo,

ich arbeite an meiner Masterarbeit. Es handelt sich um eine Webanwendung mit folgenden Komponenten. Hibernate 3.2, JSF 1.1, Tomcat 5.5.

Ich möchte eine Diagnostik einer Realisierung zuweisen und erhalte folgende Fehlermeldung:



> HTTP Status 500 -
> 
> --------------------------------------------------------------------------------
> 
> ...



hier die jsp:


```
...
<h:dataTable id="diagnodtikSelection" value="#{diagnostikListController.diagnostikSelections}" var="diagnostikSelection">
				<f:param id="id" value="#{diagnostikSelection.diagnostik.id}"/>
				<h:column>
					<h:outputText value="#{diagnostikSelection.diagnostik.name}"/>
				</h:column>
				<h:column>
					<h:commandLink
						actionListener="#{diagnostikListController.bearbeitenDiagnostik}"
						action="bearbeitenDiagnostik"
						>
						<h:outputText value="bearbeiten"/>
						<f:param id="bearbeiten" value="#{diagnostikSelection.diagnostik.id}" name="id"/>
					</h:commandLink>
				</h:column>
				<h:column>
					<h:commandLink
						actionListener="#{realisierungController.selectDiagnostik}"
						action="selectDiagnostik"
						>
						<h:outputText value="zuweisen"/>
						<f:param id="realisierungZuweisen" value="#{diagnostikSelection.diagnostik.id}" name="id"/>
					</h:commandLink>
				</h:column>
				<h:column>
					<h:selectBooleanCheckbox id="selektion" value="#{diagnostikSelection.selected}"/>
				</h:column>
			</h:dataTable> 
...
```

von actionListener="#{realisierungController.selectDiagnostik}"  geht's dann zu:


```
package prozessManager.controller;

import javax.faces.component.UIParameter;
import javax.faces.event.ActionEvent;

import org.hibernate.Session;

import prozessManager.domain.Diagnostik;
import prozessManager.domain.Realisierung;
import prozessManager.services.HibernateUtil;

public class RealisierungController {

	private Realisierung realisierung = new Realisierung();

	public Realisierung getRealisierung() {
		return realisierung;
	}

	public void setRealisierung(Realisierung realisierung) {
		this.realisierung = realisierung;
	}
	
	public String saveRealisierung() {
		
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.save(realisierung);
		return "realisierungList";
	}

	public String deleteRealisierung(){
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.delete(realisierung);
		return "realisierungList";
	}
	public String createRealisierung(){
		realisierung=null;
		realisierung = new Realisierung();
		return "anlegenRealisierung";
	}
	public String updateRealisierung() {
		
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.update(realisierung);
		return "realisierungList";
	}
	public void selectPerson(ActionEvent actionEvent) {
		Long id = (Long) ((UIParameter)actionEvent.getComponent().findComponent("realisierungZuweisen")).getValue();
		PersonListController personListController = new PersonListController();
		realisierung.setPerson(personListController.getPerson(id));
		updateRealisierung();
	}
	public String selectDiagnostik(ActionEvent actionEvent) {
		Long id = (Long) ((UIParameter)actionEvent.getComponent().findComponent("realisierungZuweisen")).getValue();
		System.out.println(id);
		DiagnostikListController diagnostikListController = new DiagnostikListController();
		Diagnostik aDiagnostik = new Diagnostik();
		aDiagnostik= diagnostikListController.getDiagnostik(id);
		System.out.println(aDiagnostik.getName());
		System.out.println(this.realisierung.getHauptdiagnose());
		realisierung.addDiagnostik(aDiagnostik);
		updateRealisierung();
		return "realisierungList";
	}
}
```

public String selectDiagnostik(ActionEvent actionEvent) läuft glatt durch bis zur Zeile "realisierung.addDiagnostik(aDiagnostik);"
Dann kommt die oben aufgeführte Fehlermeldung, die ich nicht verstehe. Eine Session müsste doch offen sein. Hier noch meine Service Klassen:

```
package prozessManager.web;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.hibernate.Transaction;

import prozessManager.services.HibernateUtil;

public class HibernateSessionRequestFilter implements Filter {

	public void destroy() {
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		Transaction transaction = HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
		try {
			chain.doFilter(request, response);
			transaction.commit();
		}
		catch(Throwable throwable) {
			transaction.rollback();
			if (throwable instanceof ServletException) {
				throw (ServletException) throwable;
			}
			ServletException servletException = new ServletException();
			servletException.initCause(throwable);
			throw servletException;
		}
		
	}

	public void init(FilterConfig arg0) throws ServletException {
	}

}
```


```
package prozessManager.services;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

import prozessManager.domain.Diagnostik;
import prozessManager.domain.Patient;
import prozessManager.domain.Person;
import prozessManager.domain.Realisierung;
import prozessManager.domain.Test;



public class HibernateUtil {

	private static boolean recreateDB = false;
	
	public static void setRecreateDB(boolean recreateDB) {
		HibernateUtil.recreateDB = recreateDB;
	}
	
	public static SessionFactory getSessionFactory() {
		if (sessionFactory == null) {
			sessionFactory = sessionFactory("hibernate.cfg.xml");
		}
		return sessionFactory;
	}
	
	private static SessionFactory sessionFactory = null;
	
	private static SessionFactory sessionFactory(String configurationFileName) {
		try {
			AnnotationConfiguration annotationConfiguration = 
				new AnnotationConfiguration()
				.addAnnotatedClass(Person.class)
				.addAnnotatedClass(Test.class)
				.addAnnotatedClass(Realisierung.class)
				.addAnnotatedClass(Diagnostik.class)
				.addAnnotatedClass(Patient.class);
			
			if (recreateDB) annotationConfiguration.setProperty("hibernate.hbm2ddl.auto", "create");
			annotationConfiguration.configure();
			return annotationConfiguration.buildSessionFactory();
		} catch (Throwable ex){
			System.err.println("Initial SessionFactory creation failed." + ex);
			throw new ExceptionInInitializerError(ex);
		}
	}
	
}
```


----------



## FT77 (26. Jul 2007)

... hier noch die Entity Klasse Realisierung mit angesprochnen Methode addDiagnostik:


```
package prozessManager.domain;

import java.util.LinkedList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.CascadeType;

 @Entity
 @Table(name="Realisierung")
public class Realisierung {
	private String nebendiagnose;
	private String hauptdiagnose;
	private Person person;
	private List<Diagnostik> diagnostikList = new LinkedList<Diagnostik>();
	private Long id;
	
	
	public Realisierung(String nebendiagnose, String hauptdiagnose, Person person) {
		this.nebendiagnose = nebendiagnose;
		this.hauptdiagnose = hauptdiagnose;
		this.person=person;
	}
	public Realisierung() {
	}
	public String getHauptdiagnose() {
		return hauptdiagnose;
	}
	public void setHauptdiagnose(String hauptdiagnose) {
		this.hauptdiagnose = hauptdiagnose;
	}
	
	@Id @GeneratedValue(strategy=GenerationType.AUTO)
	public Long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getNebendiagnose() {
		return nebendiagnose;
	}
	public void setNebendiagnose(String nebendiagnose) {
		this.nebendiagnose = nebendiagnose;
	}
	@OneToOne
	@JoinColumn(name="Person_FK")
	public Person getPerson() {
		return person;
	}
	public void setPerson(Person person) {
		this.person = person;
	}
	
	@ManyToMany(mappedBy="realisierungen")
	public List<Diagnostik> getDiagnostikList() {
		return diagnostikList;
	}
	public void setDiagnostikList(List<Diagnostik> diagnostikList) {
		this.diagnostikList = diagnostikList;
	}
	public void addDiagnostik(Diagnostik diagnostik){
		diagnostikList.add(diagnostik);
	}
}
```


----------



## SlaterB (26. Jul 2007)

was hälst du von dem allgemeinen Hinweis, dass DB-Operationen in ein Servlet gehören und nicht in die JSP? 

--------

unabhängig davon:
hast du jemals erfolgreich DB-Operationen in JSPs durchgeführt?
klappt es also nur bei diesen Code nicht oder generell?

wann wird denn so eine Session zerstört/ geschlossen?
gibt es dafür eine Codestelle?
dann könntest du dort 
System.out.println("session zu");
schreiben
und in deine JSP an der fraglichen Stelle
System.out.println("zugriff auf session");
schreiben und vergleichen

-------

generell gibts noch das Problem, Hibernate-Objekte in der Http-Session zu speichern und bei späteren Request dann Dinge nachzuladen,
die Session vom ersten Request ist da aber hoffentlich schon sehr lange zu,
einfache Lösung wie bei JSPs: einfach solche Objekte nicht rauslassen aus der sicheren Servlet-Umgebung


----------



## Guest (26. Jul 2007)

Entschuldige, aber ich verstehe dich leider nicht:



> was hälst du von dem allgemeinen Hinweis, dass DB-Operationen in ein Servlet gehören und nicht in die JSP? icon_wink.gif



Habe ich denn  DB-Operationen in meiner JSP? Ich denke nicht. Die liegen doch in den Controller Klassen.



> hast du jemals erfolgreich DB-Operationen in JSPs durchgeführt?
> klappt es also nur bei diesen Code nicht oder generell?



siehe Oben. Ansonsten kann ich sagen, dass ich verschiedene Entitäten in der DB anlegen kann. Es lassen sich auch Entitäten einander zuweisen und diese Verindungen abspeichern.

Felix


----------



## SlaterB (26. Jul 2007)

in deiner JSP steht
#{realisierungController.selectDiagnostik} 
was intern zu einem addDiagnostik() in dem Hibernate-Objekt führt,
was wiederum zu einem DB-Zugriff führt

du sagst es doch selber: 'Ich möchte eine Diagnostik einer Realisierung zuweisen'

wie passt
'Ich möchte eine Diagnostik einer Realisierung zuweisen'
zu
'Habe ich denn DB-Operationen in meiner JSP?'
?


----------



## Rydl (27. Jul 2007)

versuch doch mal das hier: http://www.hibernate.org/43.html

entweder du nutzt einen OpenSessionInView Filter oder Interceptor. vielleicht hilfts dir ja...


----------



## KSG9|sebastian (31. Jul 2007)

Eben! 
Problem ist dass Hibernate nur das "oberste" Element von deinem Modelgeflecht zieht.
Dannach wird dann die Session geschlossen.
Irgendwann kommt dann ein Code wo sowas sagt wie
rootClass.getDataCollection(). Dann versucht Hibernate eben mit der Session von rootClass die Collection zu laden und stellt fest dass die Session geschlossen ist.
Andere Möglichkeit ist das Objekt wieder der Session bekanntzumachen (glaub merge oder sowas).
Aber schau dir mal die SessionInViewFilter an.

Gruß Sebastian


----------



## kleiner_held (1. Aug 2007)

Probier mal

```
@ManyToMany(mappedBy="realisierungen", fetch=FetchType.EAGER)
	public List<Diagnostik> getDiagnostikList() {
		return diagnostikList;
	}
```


----------



## KSG9|sebastian (1. Aug 2007)

@kleiner held: Es macht aber keinen Sinn auf LazyInitialization zu verzichten. Bei nem größeren Objektgeflecht wirst doch wahnsinnig bis alles aus der Datenbank gezogen wurde.


----------

