hibernate 2.1
MySQL Ver 12.22 Distrib 4.0.18, for Win95/Win98 (i32)
I have mapped about 20 domain objects or so in my application, and I am getting a problem with one object in particular when I try to persist updates to the object. I load the object in a formBackingObject() call. In onSubmit, I then call saveOrUpdate. I get a NonUniqueObjectException. What puzzles me is that I have done nothing that appears to be significantly different in this particular class, and I have not seen this behavior with any of my other classes.
My class is called PromotionOccurrence. It has a many-to-one with class Promotion, and a many-to-many association with a Reseller class. Judging from the attached stack trace, it looks like hibernate is checking cascade rules, but I'm not familiar enough with the SessionImpl to know what types of things I could have screwed up in my hibernate and/or spring configuration.
net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: 17, of class: com.galt.viper.common.dto.service.PromotionOccurrenc
e
at net.sf.hibernate.impl.SessionImpl.checkUniqueness(SessionImpl.java:1677)
at net.sf.hibernate.impl.SessionImpl.doUpdateMutable(SessionImpl.java:1443)
at net.sf.hibernate.impl.SessionImpl.doUpdate(SessionImpl.java:1470)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1393)
at net.sf.hibernate.engine.Cascades$4.cascade(Cascades.java:114)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
at net.sf.hibernate.engine.Cascades.cascadeCollection(Cascades.java:526)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:452)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:482)
at net.sf.hibernate.impl.SessionImpl.doUpdate(SessionImpl.java:1475)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1393)
at net.sf.hibernate.engine.Cascades$4.cascade(Cascades.java:114)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
at net.sf.hibernate.engine.Cascades.cascadeCollection(Cascades.java:526)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:452)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:482)
at net.sf.hibernate.impl.SessionImpl.doUpdate(SessionImpl.java:1475)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1393)
at org.springframework.orm.hibernate.HibernateTemplate$13.doInHibernate(HibernateTemplate.java:344)
at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:200)
at org.springframework.orm.hibernate.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:341)
at com.galt.viper.data.service.HibernatePromotionDaoImpl.savePromotionOccurrence(HibernatePromotionDaoImpl.java:34)
Here is the snippet from my hibernate configuration for PromotionOccurrence:
<set
name="retailers"
table="RESELLER_PROMOTIONS"
lazy="false"
inverse="false"
cascade="save-update"
sort="unsorted"
>
<key
column="PROMOTION_OCCURRENCE_ID"
>
</key>
<many-to-many
class="com.galt.viper.common.dto.reseller.Reseller"
column="RESELLER_USERNAME"
outer-join="auto"
/>
</set>
<many-to-one
name="promotion"
class="com.galt.viper.common.dto.service.Promotion"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="PROMOTION_ID"
not-null="true"
/>
FWIW, I'm managing transactions through a service tier class that starts a new transaction, and I have two dao's called by that service class that join existing transactions.
I call saveOrUpdate() from a Spring controller, and it's the only logic that executes in the onSubmit method:
public ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception
{
PromotionOccurrence occurrence = (PromotionOccurrence)command;
promotionService.savePromotionOccurrence(occurrence);
if (StringUtils.isNotEmpty(redirectLocation)) { //redirect to appropriate page, appending a param that will let that page know which promotion to default to
response.sendRedirect(redirectLocation + "?" + lookupHelper.getRequestParameterName() + "=" + occurrence.getPromotion().getPromotionId());
return null;
}
return new ModelAndView(getSuccessView());
}
I tried switching to saveOrUpdateCopy, and the error goes away, but the new changes are not saved. Any help that can point me in the right direction will be greatly appreciated as I've been spinning wheels on this for quite a while and may just be missing something really simple.
I can attach debug level logging for the sessionImpl if it will help.
|