1

I have a problem when I try to submit my form for the second time using a4j:commandButton

My view is:

<h:form id="myform">      
    <a4j:region renderRegionOnly="true">
        <h:panelGroup>
            <h:inputText size="4" maxlength="2"
                id="input1"
                value="#{departementController.departement.name}">
            </h:inputText>
            <h:inputText size="4" maxlength="2"
                id="input1"
                value="#{departementController.departement.subdepartement.name}">
            </h:inputText>
        </h:panelGroup>
    </a4j:region>

    <h:panelGrid columns="1">
        <a4j:commandButton
            value="save"
            action="#{departementController.validateDepartement}"/>
    </h:panelGrid>
</h:form>

When I hit save for the first time, everything goes ok, and changes are saved. But when I hit save for the second time, i get this:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session

I checked, validateDepartement() method isn't called at all the second time, I just get this exception, and save fails. Just to say that I'm handling lazy loading in views by using Open Session in View (Transaction in View).

Thanks in advance,

Stefan

Stefan Kostic
  • 262
  • 4
  • 14

2 Answers2

1

I would guess that you are getting the LazyInitializationException here:

<h:inputText size="4" maxlength="2"
            id="input1"
            value="#{departementController.departement.subdepartement.name}">

The action is not called because the exception occurs before the INVOKE_APPLICATION phase. The bean property subdepartment is likely set to a fetch type of LAZY which means that in a given transaction, upon request of subdepartment property, a Hibernate Proxy will fetch the appropriate bean for you. This will only work within the scope of that transaction however.

The second request occurs, the previous department bean exists in ViewScope, however the second request will eventually create a new Transaction. The department bean is not attached to the second Transaction which isn't a problem for data types and EAGER fetched bean properties, but it will be a LazyInitializationException for LAZY properties.

This can be fixed by reattaching the bean to the session ... or you can just set subdepartment to an EAGER fetch type, or you can just load subdepartment seperately in this departmentController managed bean.

Community
  • 1
  • 1
maple_shaft
  • 10,435
  • 6
  • 46
  • 74
  • Thanks for your answers, the thing is I have to use LAZY loading, and I didn't know where to reattach the bean, because the exception was thrown in validation phase of jsf lifecycle - if the exception was thrown somewhere in my controller code, it would be easy. – Stefan Kostic Apr 02 '13 at 13:09
  • 1
    @StefanKostic Understandable requirement, but then in this case you will need to add a seperate `subdepartment` property to `departmentController` and initialize its value on `@PostConstruct` if `subdepartment` is null. Your bean property in a ViewScoped bean will always be referencing a hibernate proxy otherwise. – maple_shaft Apr 02 '13 at 13:26
0

I found the answer, I just wasn't looking in the right direction when I did the search. Here's the link:

LazyInitializationException with CDI Managed Bean and Stateful Session Bean

Anyway, I added this to h:inputText, and now it works:

<f:attribute name="collectionType" value="java.util.ArrayList" />

However, though it works, I'm not sure if this is the best way to do it.

Community
  • 1
  • 1
Stefan Kostic
  • 262
  • 4
  • 14