Lazy loading problem
maykell.mflores.uci.cu Sep 1, 2008 10:29 PMHi all, i have a problema with lazy loading i think.
I have an ordinary entity that have a collection of items, the getItems() method is annotated with fetchType.Lazy, the problem is that when i persist an item an go back to the entity detail page, and click on the tab that shows the list of items assosiated with the entity, the list is returning empty, nevertheless if i go to the menu bar(my project is a seam-gen generated one) and click on the entityList option, everything works just fine, the tab shows the collection of items without problem.
There is another clue, if i go again and add another item and go back to the entity detail page i get the tab showing the collection minus the last item that was persisted.
Somebody can explain me this behavior.
This is my code:
the entity class:
package com.prueba.domain;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.validator.NotNull;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Name;
@Name("expediente")
@Entity
@Table (name="EXPEDIENTE")
public class Expediente {
private Long id;
private String nroExpediente;
private List<Testigo> testigos = new ArrayList<Testigo>();
private List<Acusado> acusados = new ArrayList<Acusado>();
@OneToMany(cascade = CascadeType.ALL ,fetch = FetchType.LAZY, mappedBy="expediente")
public List<Acusado> getAcusados() {
return acusados;
}
public void setAcusados(List<Acusado> acusados) {
this.acusados = acusados;
}
@Column (name="nroExpediente", nullable = false)
@NotNull
public String getNroExpediente() {
return nroExpediente;
}
public void setNroExpediente(String nroExpediente) {
this.nroExpediente = nroExpediente;
}
@Id
@GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@OneToMany(cascade=CascadeType.ALL,fetch = FetchType.LAZY, mappedBy = "expediente")
public List<Testigo> getTestigos() {
return testigos;
}
public void setTestigos(List<Testigo> testigoLista) {
this.testigos = testigoLista;
}
}
The item class:
package com.prueba.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import org.hibernate.validator.NotNull;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.web.RequestParameter;
@Name("acusado")
@Entity
@PrimaryKeyJoinColumn(name="PERSONA_ID")
@Table (name="ACUSADO")
public class Acusado extends Persona {
private String descripcionFisica;
private Expediente expediente;
@ManyToOne (fetch = FetchType.LAZY)
@JoinColumn(name="Expediente_ID",nullable = false)
public Expediente getExpediente() {
return expediente;
}
public void setExpediente(Expediente expediente) {
this.expediente = expediente;
}
@Column (name="descripcionFisica", nullable = false)
@NotNull
public String getDescripcionFisica() {
return descripcionFisica;
}
public void setDescripcionFisica(String descripcionFisica) {
this.descripcionFisica = descripcionFisica;
}
}
The entityHome class:
package com.prueba.facade;
import java.util.ArrayList;
import java.util.List;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.framework.EntityHome;
import com.prueba.domain.Acusado;
import com.prueba.domain.Expediente;
@Name("expedienteHome")
public class ExpedienteHome extends EntityHome<Expediente> {
@RequestParameter
Long expedienteId;
@Out
List<Acusado> listaAcusados = new ArrayList<Acusado>();
@Override
public Object getId() {
if (expedienteId == null) {
return super.getId();
} else {
return expedienteId;
}
}
@Override
@Begin
public void create() {
super.create();
}
@Transactional
public List<Acusado> getAcusados() {
if (getInstance() == null)
return null;
else {
Object lista = getInstance().getAcusados();
this.listaAcusados = (List<Acusado>)lista;
return (List<Acusado>)lista;
}
}
}
The itemAction class:
package com.prueba.facade;
import java.io.Serializable;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.Conversational;
import org.jboss.seam.annotations.FlushModeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.core.Events;
import org.jboss.seam.log.Log;
import org.jboss.seam.faces.FacesMessages;
import com.prueba.domain.Acusado;
import com.prueba.domain.Expediente;
@Name("registerAcusadoAction")
@Scope(ScopeType.CONVERSATION)
public class RegisterAcusadoAction implements Serializable{
@Logger
private Log log;
@In
FacesMessages facesMessages;
@In
private EntityManager entityManager;
@RequestParameter
String kaka;
@RequestParameter
String returnTo = "testigoList.xhtml";
String from = "/acusadoList.xhtml";
@Out(required = false) Acusado acusado;
@In (create = true)
ExpedienteHome expedienteHome;
@Transactional
@Begin(join=true)
public void registerAcusado(Acusado acusadoLocal) {
acusadoLocal.setExpediente(expedienteHome.getInstance());
entityManager.persist(acusadoLocal);
entityManager.flush();
acusado = acusadoLocal;
Events.instance().raiseTransactionSuccessEvent("EntidadCRUD","Acusado Registrado", "RegisterAcusadoAction.registerAcusado");
}
public void updateAcusado(Acusado acusadoLocal) {
boolean bol1 = entityManager.contains(acusadoLocal);
entityManager.flush();
// Events.instance().raiseTransactionSuccessEvent("EntidadCRUD","Acusado Actualizado", "RegisterAcusadoAction.updateAcusado");
}
@Transactional
public void loadAcusado() {
Events.instance().raiseTransactionSuccessEvent("EntidadCRUD","", "RegisterAcusadoAction.loadAcusado");
if (kaka != null ) {
try {
acusado = (Acusado) entityManager.find(Acusado.class, kaka);
} catch (NoResultException nre) {
} catch (NonUniqueResultException nure) {
}
}else
{
boolean bol1 = entityManager.contains(Component.getInstance("acusado"));
if (acusado == null){
acusado = new Acusado();
log.info("El acusado vino null");
}
}
boolean bol = entityManager.contains(acusado);
}
public void verPaginaRetorno()
{
if (returnTo != null)
from = returnTo;
}
public void cleanVar(String varName){
org.jboss.seam.contexts.Contexts.getConversationContext().remove(varName);
}
public String getReturnTo() {
return returnTo;
}
public void setReturnTo(String returnTo) {
this.returnTo = returnTo;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
}
the entity detail page:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich" template="layout/template.xhtml">
<ui:define name="body">
<h:messages globalOnly="true" styleClass="message" />
<h:form id="expedienteForm">
<rich:panel>
<f:facet name="header">expediente</f:facet>
<s:decorate id="nameDecoration" template="layout/edit.xhtml">
<ui:define name="label">Numero de expediente</ui:define>
<h:inputText id="nro" required="true"
value="#{expedienteHome.instance.nroExpediente}" />
</s:decorate>
<div style="clear: both" />
</rich:panel>
<div class="actionButtons"><h:commandButton id="save"
value="Salvar" action="#{expedienteHome.persist}"
rendered="#{!expedienteHome.managed}" /> <h:commandButton
id="update" value="Actualizar" action="#{expedienteHome.update}"
rendered="#{expedienteHome.managed}" /> <h:commandButton
id="delete" value="Eliminar" action="#{expedienteHome.remove}"
immediate="true" rendered="#{expedienteHome.managed}" /> <s:button
propagation="end" id="expedienteDone" value="Terminar"
view="/expedienteList.xhtml" /></div>
<rich:panel>
<rich:tabPanel id="expCollections">
<rich:tab id="acusadosTab" label="Acusados">
<!-- <h:messages globalOnly="true" styleClass="message" /> -->
<rich:panel>
<f:facet name="header">Listado de acusados para el expediente actual</f:facet>
<div class="results"><h:outputText
value="No existen acusados asociados a este expediente aun"
rendered="#{empty expedienteHome.getAcusados()}" /> <h:dataTable
id="acusadoList" var="acusado" value="#{listaAcusados}"
rendered="#{not empty listaAcusados}" cellpadding="2"
rowClasses="graybg,whitebg">
<h:column>
<f:facet name="header">CI</f:facet>
#{acusado.ci}
</h:column>
<h:column>
<f:facet name="header">Nombre</f:facet>
<s:link id="nombreLink" value="#{acusado.nombre}"
view="/registerAcusado.xhtml" propagation="join">
<f:param name="returnTo" value="/expediente.xhtml" />
</s:link>
</h:column>
<h:column>
<f:facet name="header">Direccion</f:facet>
#{acusado.direccionParticular}
</h:column>
<h:column>
<f:facet name="header">Desc Fisica</f:facet>
#{acusado.descripcionFisica}
</h:column>
</h:dataTable></div>
</rich:panel>
<div class="actionButtons"><s:button id="acusadoDone"
value="Create acusado" view="/registerAcusado.xhtml">
<f:param name="returnTo" value="/expediente.xhtml" />
</s:button></div>
</rich:tab>
</rich:tabPanel>
</rich:panel>
</h:form>
</ui:define>
</ui:composition>