Hi,
I have a JSP file, which contains a table that displays a list of clients. Each of the
clients can have many addresses attached to it.
If you click on one of the clients you end up on a second page, which again displays a
table that lists all the addresses of the selected client.
There exists a corresponding Statefull Session Bean (SSB) for each JSP. Both SSBs called
ClientAction and AddressAction contain a funtion, which returns the DataModel containing
the clients and addresses respectively.
The first SSB also has a function, which returns the selected Client from the DataModel,
so that the second SSB can get the currently selected client to display his addresses:
public Client getSelection()
{
return (Client) dataModel.getRowData();
}
The second SSB calls the above function to get the currently selected Client and to
retrieve the client's addresses to initialize it's own DataModel that it needs for
it's JSP page.
If this function is called from the AddressAction SSB and we do NOT use an EXTENDED
persistent context inside the ClientAction SB (see NOTE A), then we get the first
exception (this is only the beginning):
"Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a
collection of role: de.pilati.calc.model.Client.proposals, no session or session was
closed"
After I change the persistent context of the ClientAction SSB to an extended one, I get
rid of the exception, but noticed something else, which seems very strange to me: It's
a matter of live or death for my application, from which method inside the AddressAction
the getSelection() method gets called.
In particular I it's very unhealty to call it from within the
"getAddresses()" method of the AddressAction SSB, which is used to initalize the
DataModel for use in the JSP file that displays the addresses. If I place the
getSelection() method into the function which returns(!) the DataModel, the I get the
following exception:
"Caused by: org.hibernate.TransactionException: Could not register synchronization
at
org.hibernate.transaction.CMTTransaction.registerSynchronization(CMTTransaction.java:159)
at org.hibernate.ejb.EntityManagerImpl.close(EntityManagerImpl.java:59)
at
org.jboss.ejb3.stateful.StatefulBeanContext.closeExtendedPCs(StatefulBeanContext.java:284)
at
org.jboss.ejb3.stateful.StatefulBeanContext.remove(StatefulBeanContext.java:268)
... 169 more
Caused by: javax.transaction.RollbackException: Already marked for rollback
TransactionImpl"
If I instead move the "getAddresses()" out of the function, which returns the
DataModel to the JSP page that displays the addresses into the the "list()"
function, which gets called when the user clients onto the link that selects a client,
then everything works fine. This is good, but it seems that something is very wrong
here!?
To sum it all up I have two questions:
1.Why do I need a extended persitent context? After the ?getClients()? returns all the
Entities should be detached from the persitent manger, shouldn't they? So why would a
call to return the client (not the addresses inside) cause a LazyInitializationException,
when I had retrieved the client object already before?! After all the getSelection only
returns a client, which has already been fetched.
2.Why do I get a TransactionException, when I call the ?getSelection()? method in the
function, which returns the DataModel to the JSP page(which needs it to render itself) but
NOT when I place it into the method, which gets called to navigate to the JSP page???
Here are the important code snippets:
Client SSB
------------
public class ClientAction implements BasicClientAction
{
// NOTE A: This throws the first exception so I remove it
//@PersistenceContext
@PersistenceContext(type=PersistenceContextType.EXTENDED)
EntityManager entityManager;
// Stores all the clients
DataModel dataModel;
@Begin(join = true)
public DataModel getClients()
{
if (dataModel == null)
dataModel = new ListDataModel();
dataModel.setWrappedData(entityManager.createQuery("from
Client").getResultList());
return dataModel;
}
public Client getSelection()
{
return (Client) dataModel.getRowData();
}
...
}
Address SSB
---------------
@Name("addressAction")
@Stateful
public class AddressAction implements BasicAdressAction
{
// Makes not difference if I set the context to extended or not
@PersistenceContext
EntityManager entityManager;
@In(create = true) @Out @Valid
Address address;
// Stores all the addresses of a SELECTED client
DataModel dataModel;
// This is needed to retrieve the currently selected client
@In(required = false)
BasicClientAction clientAction;
Client selectedClient;
public String list()
{
// NOTE B: Calling the getSelection() from here DOES NOT cause an excepiton
//selectedClient = clientAction.getSelection();
return "addresses";
}
@Begin(join = true)
public DataModel getAddresses()
{
if (dataModel == null)
dataModel = new ListDataModel();
// NOTE B: If the JSP page calls this fuction to initalize itself, the
// we get an exception
selectedClient = clientAction.getSelection();
dataModel.setWrappedData(selectedClient.getAddresses());
return dataModel;
}
...
}
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3990025#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...