Hi,
I'm trying to do an update/merge on a set of objects. The initial insert has been working fine, but the update has been failing.
I've been searching the web and trying what I find for the past day and a half, but I can't get my app to work. I keep getting the "
a different object with the same identifier value was already associated with the session" error, which I believe is related to the set related to the single.
I would bet that my error is simple, but I can't find it. Can anyone help?
My hbm file looks like this:
Code:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-lazy="false">
<class name="com.mt.ecom.services.feedback.dao.MtFeedbackSurvey" table="MT_FEEDBACK_SURVEY">
<id name="id" type="java.lang.Long">
<column name="ID" index="MT_FEEDBACK_PROFILE_DATA_PK" />
<!-- this forces the ID to be the same as that of the 'feedback' -->
<generator class="foreign">
<param name="property">profile</param>
</generator>
</id>
<one-to-one name="profile" lazy="false" class="com.mt.ecom.services.feedback.dao.MtFeedbackProfile" constrained="true" foreign-key="MT_FEEDBACK_SURVEY_FK" />
<set name="responses" cascade="all-delete-orphan" lazy="false" inverse="true">
<key column="SURVEY_ID" update="false" not-null="true" />
<one-to-many class="com.mt.ecom.services.feedback.dao.MtFeedbackSurveyData" />
</set>
<property name="sentDate" type="java.util.Date" column="SENT_DATE" length="7" />
<property name="responseDate" type="java.util.Date" column="RESPONSE_DATE" length="7" />
<property name="badRating" type="java.lang.Boolean" column="IS_BAD_RATINGS" />
</class>
<class name="com.mt.ecom.services.feedback.dao.MtFeedbackSurveyData" table="MT_FEEDBACK_SURVEY_DATA">
<composite-id>
<key-property name="surveyId" type="java.lang.Long" column="SURVEY_ID" />
<key-property name="questionNumber" type="java.lang.Integer" column="QUESTION_NUMBER" />
</composite-id>
<many-to-one name="survey" column="SURVEY_ID" class="com.mt.ecom.services.feedback.dao.MtFeedbackSurvey" insert="false" update="false" cascade="save-update" not-null="true"
foreign-key="MT_FEEDBACK_SURVEY_DATA_FK" index="MT_FEEDBACK_SURVEY_DATA_IDX" />
<property name="questionTranslation" column="QUESTION_TRANSLATION" type="java.lang.String" />
<property name="responseValue" column="RESPONSE_VALUE" type="java.lang.Integer" />
<property name="responseTranslation" column="RESPONSE_TRANSLATION" type="java.lang.String" />
</class>
</hibernate-mapping>
The Survey object looks like this:
Code:
package com.mt.ecom.services.feedback.dao;
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
public class MtFeedbackSurvey implements Serializable
{
private static final long serialVersionUID = 1L;
private Long feedbackId;
private Boolean isBadRating;
private MtFeedbackProfile profile;
private Date responseDate;
private Set<MtFeedbackSurveyData> responses = new HashSet<MtFeedbackSurveyData>();
private Date sentDate;
public MtFeedbackSurvey()
{
super();
}
public void addResponse(MtFeedbackSurveyData response)
{
responses.add(response);
}
@Override
public boolean equals(Object obj)
{
if(obj == null)
{
return false;
}
if(obj == this)
{
return true;
}
if(obj.getClass() != getClass())
{
return false;
}
MtFeedbackSurvey rhs = (MtFeedbackSurvey) obj;
return new EqualsBuilder().appendSuper(super.equals(obj)).append(feedbackId, rhs.feedbackId).isEquals();
}
public Boolean getBadRating()
{
return isBadRating;
}
public Long getId()
{
return feedbackId;
}
public MtFeedbackProfile getProfile()
{
return profile;
}
public Date getResponseDate()
{
return responseDate;
}
public Set<MtFeedbackSurveyData> getResponses()
{
return responses;
}
public Date getSentDate()
{
return sentDate;
}
@Override
public int hashCode()
{
int result = responses != null ? responses.hashCode() : 0;
result = 31 * result + (feedbackId != null ? feedbackId.hashCode() : 0);
result = 31 * result + (isBadRating != null ? isBadRating.hashCode() : 0);
result = 31 * result + (responseDate != null ? responseDate.hashCode() : 0);
result = 31 * result + (sentDate != null ? sentDate.hashCode() : 0);
return result;
}
public Boolean isBadRating()
{
return isBadRating;
}
public void removeResponse(MtFeedbackSurveyData response)
{
responses.remove(response);
}
public void setBadRating(Boolean b)
{
isBadRating = b;
}
public void setId(Long feedbackId)
{
this.feedbackId = feedbackId;
}
public void setProfile(MtFeedbackProfile profile)
{
this.profile = profile;
}
public void setResponseDate(Date responseDate)
{
this.responseDate = responseDate;
}
public void setResponses(Set<MtFeedbackSurveyData> responses)
{
if(responses != null)
{
for(MtFeedbackSurveyData response : responses)
{
if(response != null)
{
response.setSurvey(this);
}
}
}
this.responses = responses;
}
public void setSentDate(Date sentDate)
{
this.sentDate = sentDate;
}
public String toString()
{
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
and the SurveyData object looks like this:
Code:
package com.mt.ecom.services.feedback.dao;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import com.mt.ecom.services.feedback.FeedbackSurveyResponse;
public class MtFeedbackSurveyData implements Serializable
{
private static final long serialVersionUID = 1L;
private Integer questionNumber;
private String questionTranslation;
private String responseTranslation;
private Integer responseValue;
private MtFeedbackSurvey survey;
public MtFeedbackSurveyData()
{
}
public MtFeedbackSurveyData(MtFeedbackSurvey survey)
{
this.survey = survey;
}
public MtFeedbackSurveyData(MtFeedbackSurvey survey, FeedbackSurveyResponse fsr)
{
this(survey);
this.questionNumber = fsr.getQuestionNumber();
this.questionTranslation = fsr.getQuestionTranslation();
this.responseValue = fsr.getResponseValue();
this.responseTranslation = fsr.getResponseTranslation();
}
public MtFeedbackSurveyData(MtFeedbackSurvey survey, Integer questionNumber, String questionTranslation, Integer responseValue, String responseTranslation)
{
this(survey);
this.questionNumber = questionNumber;
this.questionTranslation = questionTranslation;
this.responseValue = responseValue;
this.responseTranslation = responseTranslation;
}
@Override
public boolean equals(Object obj)
{
if(obj == null)
{
return false;
}
if(obj == this)
{
return true;
}
if(obj.getClass() != getClass())
{
return false;
}
MtFeedbackSurveyData rhs = (MtFeedbackSurveyData) obj;
return new EqualsBuilder().appendSuper(super.equals(obj)).append(questionNumber, rhs.questionNumber).append(survey, rhs.survey).isEquals();
}
public Integer getQuestionNumber()
{
return questionNumber;
}
public String getQuestionTranslation()
{
return questionTranslation;
}
public String getResponseTranslation()
{
return responseTranslation;
}
public Integer getResponseValue()
{
return responseValue;
}
public MtFeedbackSurvey getSurvey()
{
return survey;
}
public Long getSurveyId()
{
return survey == null ? null : survey.getId();
}
@Override
public int hashCode()
{
int result = 0;
result = 31 * result + (questionNumber != null ? questionNumber.hashCode() : 0);
result = 31 * result + (questionTranslation != null ? questionTranslation.hashCode() : 0);
result = 31 * result + (responseValue != null ? responseValue.hashCode() : 0);
result = 31 * result + (responseTranslation != null ? responseTranslation.hashCode() : 0);
return result;
}
public void setQuestionNumber(Integer questionNumber)
{
this.questionNumber = questionNumber;
}
public void setQuestionTranslation(String questionTranslation)
{
this.questionTranslation = questionTranslation;
}
public void setResponseTranslation(String responseTranslation)
{
this.responseTranslation = responseTranslation;
}
public void setResponseValue(Integer responseValue)
{
this.responseValue = responseValue;
}
public void setSurvey(MtFeedbackSurvey survey)
{
this.survey = survey;
}
public void setSurveyId(Long ignored)
{
}
public String toString()
{
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
Finally the method that does the save looks like this:
Code:
public Long saveForSurvey(MtFeedbackProfile instance)
{
Long key = null;
if ((instance.getContent() != null) && (instance.getContent().getCreationTime() == null))
{
instance.getContent().setCreationTime(new Date());
}
Session session = sessionFactory.openSession();
try
{
if (instance.getId() == null)
{
LOG.debug("saveForSurvey(): instance is null");
key = (Long) session.save(instance);
}
else
{
LOG.debug("saveForSurvey(): instance is not null");
session.merge(instance);
key = instance.getId();
}
session.flush();
}
catch(HibernateException e)
{
e.printStackTrace();
}
finally
{
session.close();
}
return key;
}