我有一个这样的实体调查:
@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
信息。在从surveyresults
的所有调用中实例化(从Spring)服务以来,此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
。例如
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);
}