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#3990025
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3990025
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user