![](/img/trans.png)
[英]Fix detached entity passed to persist in one to one relationship in JPA
[英]detached entity passed to persist: one to one to relationship
我有一個這樣的實體調查:
@Entity
public class SurveyData {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "SURVEY_ID")
private Long Id;
@ManyToOne
@JsonBackReference
@JoinColumn(name = "client_id")
public Client client;
@OneToOne
@JsonManagedReference
@JoinColumn(name = "surveyresult_id")
private SurveyDataResults surveyDataResults;
private Character unit;
..and other fields
另一個實體的SurveyDataResults如下所示:
@Entity
@Table(name = "surveydataresults")
public class SurveyDataResults {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "SURVEYRESULT_ID")
private Long Id;
..and other fields
SurveyData從POST表單中填寫,在我保存之后,使用這些字段進行了一些計算,然后保存在SurveyDataResult中。 當我第一次提交表單時,它會保存在SurveyData上,並保存對第一個SurveyDataResults的引用,其中ID為1,所有結果都在其中。 當我第二次使用值填寫表單時,出現錯誤:分離實體傳遞給persist:SurveyDataResults
我看到的問題是,如果我一個接一個地填寫表單,則提交的第二個表單的結果將保存在ID = 1的SurveyDataResults上。 因此,分離實體問題,因為它已被保存一次。 如何確保在每個表單提交后都相應地映射?
編輯:
我的后控制器:
@RequestMapping(value = "/user/calculate", method = RequestMethod.POST)
public ModelAndView createNewSurvey(@Valid SurveyData survey_data, BindingResult bindingResult) {
long clientId = survey_data.client.getId();
SurveyData newSurvey = surveyService.saveSurvey(survey_data);
Long surveyId = newSurvey.getId();
calculateService.CalculateFirst(surveyId);
calculateService.CalculateSecond(surveyId);
calculateService.CalculateThird(surveyId);
=
return new ModelAndView("redirect:/user/surveys?getId=" + clientId);
}
然后在calculateService中,使用.save這樣保存每個字段,如下所示:surveyServiceResults.saveSurveyResults(surveyresults);
@Service("calculateService")
public class CalculateServiceImpl implements CalculateService {
@Autowired
private SurveyDataRepository surveyDataRepository;
SurveyDataResults surveyresults = new SurveyDataResults();
@Autowired
private SurveyServiceResults surveyServiceResults;
public void CalculateFirst(Long id){
SurveyData survey = surveyDataRepository.findOne(id);
Integer c=survey.getA()+survey.getB();
surveyResults.setC(c);
surveyServiceResults.saveSurveyResults(surveyresults);
}
public void CalculateSecond(Long id){
SurveyData survey = surveyDataRepository.findOne(id);
Integer D=survey.getB()+survey.getM();
surveyResults.setD(D);
surveyServiceResults.saveSurveyResults(surveyresults);
}
服務:
public interface SurveyServiceResults {
public void saveSurveyResults(SurveyDataResults surveyresults);
}
執行:
@Service("surveyServiceResults")
公共類SurveyServiceResultsImpl實現SurveyServiceResults {
@Autowired
private SurveyDataResultsRepository surveyDataResultsRepository;
@Override
public void saveSurveyResults(SurveyDataResults surveyresults) {
surveyDataResultsRepository.save(surveyresults);
}
}
倉庫:
@Repository("surveyDataResults")
public interface SurveyDataResultsRepository extends
JpaRepository<SurveyDataResults, Long>{}
這是我得到的錯誤:
detached entity passed to persist: com.test.test1.model.SurveyDataResults; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.test.test1.model.SurveyDataResults
CalculateServiceImpl
類中肯定存在錯誤,您在其中將surveryresults
聲明為類成員字段。 在諸如服務和存儲庫之類的類中這樣做是錯誤的,您應盡量不要在此類中保存state
信息。 通過從CalculateXXX
進行的所有調用(從Spring實例化)該服務后,此surveyresults
都是相同的,這就是為什么出現分離的實體錯誤的原因。
SurveyDataResults surveyresults = new SurveyDataResults();
因此,從此處刪除此行,並從CalculateXXX
方法內部加載並使用SurveyDataResults
下面是一個示例,但是我不知道它是否會按預期工作,因為您尚未發布所有代碼(例如,請參閱我的嵌入式注釋)
public void CalculateFirst(Long id){
SurveyData survey = surveyDataRepository.findOne(id);
Integer c=survey.getA()+survey.getB();
SurveyDataResults surveyResults = survey.getSurveyresults();
if (surveyResults == null) {
surveyResults = new SurveyDataResults();
surveyResults.setSurvey(survey); //not present in your code but I assume it exists
}
surveyResults.setC(c);
surveyServiceResults.saveSurveyResults(surveyresults);
}
UPDATE
另一點是您通過SurveyDataResultsRepository
保存SurveyResults的SurveyDataResultsRepository
。 如果您沒有像上面我的代碼示例中那樣通過SurveyDataResults
的設置方法設置survey
,則沒有SurveyData
和SurveyDataResults
關系。 如果你沒有一個SurveyData
的場內SurveyDataResults
實體,那么你應該設置SurveyDataResults
到SurveyData
並保存SurveyData
通過調用SurveyDataRepository.save
而不是通過SurveyDataResultsRepository
。
例如
public void CalculateFirst(Long id){
SurveyData survey = surveyDataRepository.findOne(id);
Integer c=survey.getA()+survey.getB();
SurveyDataResults surveyResults = survey.getSurveyresults();
if (surveyResults == null) {
surveyResults = new SurveyDataResults();
survey.setSurveyDataResults(surveyResults);
}
surveyResults.setC(c);
surveyDataRepository.save(survey);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.