我有一个这样的实体调查:

@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,则您与SurveyDataSurveyDataResults没有关系。如果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);
}

09-28 06:39