简体   繁体   中英

detached entity passed to persist: one to one to relationship

I have an Entity Survey like this:

@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

And another Entity the SurveyDataResults like this :

 @Entity
 @Table(name = "surveydataresults")
public class SurveyDataResults {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "SURVEYRESULT_ID")
private Long Id;
..and other fields

SurveyData gets filled from a POST form, and after that i saved, there's some calculations made with those fields and then saved on the SurveyDataResult. When I submit the form for the first time, it gets saved on SurveyData and it holds a reference to the first SurveyDataResults, with id 1 where all the results are. When I fill out the form for the second time with values I get an error : detached entity passed to persist:SurveyDataResults

The problem I see, is that if I fill out the form one after another, the results of the second form submitted get saved on the SurveyDataResults with ID=1. Therefore the detached entity issue,because it has already been saved once. How do I make it that after every form submission the mapping to be accordingly ?

EDIT:

My Post Controller :

@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);
}

And in the calculateService I save every field using .save like this : 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);
}

Service:

public interface SurveyServiceResults {

public void saveSurveyResults(SurveyDataResults surveyresults);

}

Implementation:

@Service("surveyServiceResults")

public class SurveyServiceResultsImpl implements SurveyServiceResults {

@Autowired
private SurveyDataResultsRepository surveyDataResultsRepository;

@Override
public void saveSurveyResults(SurveyDataResults surveyresults) {
    surveyDataResultsRepository.save(surveyresults);
}
}

Repository :

@Repository("surveyDataResults")
public interface SurveyDataResultsRepository  extends 
JpaRepository<SurveyDataResults, Long>{}

This is the error I get :

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

An error is certainly in the CalculateServiceImpl class, where you declare the surveryresults as a class member field. This is wrong to do in classes like services and repositories, you should try not to hold state information in such classes. This surveyresults once the service is instantiated (from Spring) is the same through all the calls to CalculateXXX , that's why you get the detached entity error.

SurveyDataResults surveyresults = new SurveyDataResults();

So remove this line from there, and load and work with SurveyDataResults from inside your CalculateXXX methods

An example can be the following, however I dont know if it will work as expected because you have not posted all your code (see my inline comment for example)

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

Another point is the way you are saving the surveyResults, via the SurveyDataResultsRepository . If you do not set the survey via a setter method in SurveyDataResults like the one in my code example above, you have no relation of SurveyData and SurveyDataResults . If you don't have a SurveyData field inside the SurveyDataResults entity, then you should set the SurveyDataResults to SurveyData and save the SurveyData by calling the SurveyDataRepository.save and not via the SurveyDataResultsRepository .

eg

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM