I have a Struts 1.3 and Hibernate 3.1 application that uses an open-session-in-view pattern for maintaining hibernate transactions. After I do a session.save() on an object its identifier is being set in the object, however after I pass the object to a new action class all of the properties that are managed by hibernate, like the object's identifier are being set to null.
The client isn't using Spring so I had to write my own request filter implementation of the pattern which looks like:
//get a transaction from JTA
transaction = (UserTransaction)new InitialContext().lookup("java:comp/UserTransaction");
transaction.begin();
// Call the next filter (continue request processing)
chain.doFilter(request, response);
// Commit and cleanup
log.finer("Committing the database transaction");
transaction.commit();
My SaveActionClass calls a service layer to persist the object and its associated list (where I'm controlling the session) looks like this:
this.saveAddresses(vendor); //saves a persistant set to the database via dao
this.saveExpCodes(vendor, expCodes); //saves a persistant set to the database via dao
this.savePhoneNumbers(vendor); //saves a persistant set to the database via dao
vendor.save(); //saves the vendor object to the database via dao
session.flush();
session.refresh(vendor);
After the vendor object is persisted the vendor object and all of its children objects have valid identi开发者_JAVA技巧fiers. The vendor object is then added to a DynActionForm property and then forwarded to a ViewActionClass:
dynaActionForm.set(VENDOR_PROPERTY_NAME, vendor);
return actionMapping.findForward(target); //viewvendor
Then in the ViewActionClass when I get the vendor property all the identifiers are set to null:
Vendor vendor = (Vendor)dynaActionForm.get(VENDOR_PROPERTY_NAME); //vendorid is now null
Why is the persistent object losing its identifiers when its being passed from one action class to another via property in dynActionForm?
The trick here was the placement of the session.refresh() in the getVendor service method:
public Vendor getVendor(Vendor vendor, Boolean refresh) {
Session session = HibernateUtil.getSession();
session.setFlushMode(FlushMode.MANUAL);
//refreshing the session here before the get call gave me the would still set some properties to null
/*
if(refresh.booleanValue()){
session.refresh(vendor);
}
*/
vendor = vendor.get();
//however putting the refresh here, after the get() call populated the vendor object properly
if(refresh.booleanValue()){
session.refresh(vendor);
}
....
}
精彩评论