Search code examples
javaspringjpaeclipselink

Inserting to 1:m relation java spring


I have 1:m relation. I post data about "1" and also about "m" relation in one post. What i am trying to achieve is to insert data ( m ) into "1" , then persist 1 into database which should create info in database about 1 and about m.

The "1" Enitity:

 private List<OptionEntity> options;

    @OneToMany(mappedBy = "survey", cascade = CascadeType.MERGE)
    public List<OptionEntity> getOptions() {
        return options;
    }

    public void setOptions(List<OptionEntity> options) {
        this.options= options;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "survey_id", nullable = false)
    public int getSurveyId() {
        return surveyId;
    }

    public void setSurveyId(int surveyId) {
        this.surveyId = surveyId;
    }

the "m" entitites

private SurveyEntity survey;

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="survey_id")
public SurveyEntity getSurvey() {
    return survey;
}

public void setSurvey(SurveyEntity survey ) {
    this.survey = survey;
}

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "option_id", nullable = false)
public int getOptionId() {
    return optionId;
}

public void setOptionId(int optionId) {
    this.optionId = optionId;
}

However when i do

List<OptionEntity> ops = new ArrayList<>();
for( String option : options ){
    OptionEntity tmp_option = new OptionEntity();
    tmp_option.setText( option );
    ops.add(tmp_option);
}
survey.setOptions(ops);
surveyDAO.add(survey);

when add is

public void add ( SurveyEntity s )
{
  em.persist( s );
}

Creates only record for "1" entity in database. The records for all "m" entities are not inserted in the databases.

I thought whats important here is identity set to AUTO for m entities so database can create their id ( it has autoincrement ).

Seems i am wrong in this one.

What is the correct way to insert into 1:m relation at once?

Thanks for help


Solution

  • You have to do two things:

    1) Set the relationship on both sides, so in the loop add the Survey entity to each of the Option entities:

           for( String option : options ){
               OptionEntity tmp_option = new OptionEntity();
               tmp_option.setText( option );
               ops.add(tmp_option);
               tmp_option.setSurvey(survey);
           }
    

    2) Either use em.merge() instead of em.persist() or add this cascade option:

    @OneToMany(mappedBy = "survey", cascade = {CascadeType.MERGE, CascadeType.PERSIST})
    public List<OptionEntity> getOptions() {
        return options;
    }