我有这样的实体调查:
@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,其中包含所有结果。 当我第二次用值填写表单时,我得到一个错误:传递给持久化的分离实体: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
答案 0 :(得分:1)
CalculateServiceImpl
类中肯定存在错误,您将surveryresults
声明为类成员字段。这在服务和存储库这样的类中是错误的,您应该尽量不在这些类中保存state
信息。一旦服务实例化(来自Spring),surveyresults
通过对CalculateXXX
的所有调用都是相同的,这就是为什么你得到分离的实体错误。
SurveyDataResults surveyresults = new SurveyDataResults();
从那里删除此行,然后从SurveyDataResults
方法
CalculateXXX
示例可以是以下内容,但是我不知道它是否会按预期工作,因为您尚未发布所有代码(例如,请参阅我的内联注释)
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);
}
<强>更新强>
另一点是通过SurveyDataResultsRepository
保存surveyResults的方式。如果您没有通过survey
中的setter方法设置SurveyDataResults
,就像我上面的代码示例中那样,那么SurveyData
和SurveyDataResults
就没有关系。如果您在SurveyData
实体中没有SurveyDataResults
字段,则应将SurveyDataResults
设置为SurveyData
并通过调用保存SurveyData
SurveyDataRepository.save
而不是SurveyDataResultsRepository
。
e.g。
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);
}