web-dev-qa-db-fra.com

Comment l'hibernation enregistre-t-elle les annotations un-à-plusieurs / plusieurs-à-un? (Les enfants n'épargnent pas)

J'ai hérité d'une application de mise en veille prolongée et j'ai rencontré des problèmes. Il semble que le code ne sauve pas l'enfant dans une relation un-à-plusieurs. C'est bidirectionnel, mais lors de la sauvegarde de l'objet parent, cela ne semble pas sauver l'enfant.

La classe Question est le parent dans ce cas.

// Question.Java
@Entity
@SequenceGenerator(name = "question_sequence", sequenceName = "seq_question", allocationSize = 1000)
@Table(name = "question")
public class Question {
   protected Long questionId;
   protected Set<AnswerValue> answerValues;

   public TurkQuestion(){}

   public TurkQuestion(Long questionId){
      this.questionId = questionId;
   }

   @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "question_sequence")
   @Column(name = "question_id")
   public Long getQuestionId(){
      return questionId;
   }

   @OneToMany(fetch = FetchType.EAGER)
   @JoinColumn(name = "question_id",referencedColumnName="question_id")
   public Set<AnswerValue> getAnswerValues(){
      return answerValues;
   }

   public void setQuestionId(Long questionId){
      this.questionId = questionId;
   }

   public void setAnswerValues(Set<AnswerValue> answerValues){
      this.answerValues = answerValues;
   }
}

AnswerValue est la classe enfant.

// AnswerValue.Java
@Entity
@SequenceGenerator(name = "answer_value_sequence", sequenceName = "seq_answer_value", allocationSize = 1)
@Table(name = "answer_value")
public class AnswerValue {
    protected Long answerValueId;
    protected Question question;
    protected String answerValue;

    public AnswerValue(){}

    public AnswerValue(Long answerValueId, Long questionId, String answerValue){
       this.answerValueId = answerValueId;
       this.question = new Question(questionId);
       this.answerValue = answerValue;
    }

    @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "answer_value_sequence")
    @Column(name = "answer_value_id")
    public Long getAnswerValueId(){
       return answerValueId;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "question_id", nullable = false )
    public Question getQuestion(){
       return question;
    }

    @Column(name = "answer_value")
    public String getAnswerValue(){
       return answerValue;
    }

    public void setAnswerValueId(Long answerValueId){
       this.answerValueId = answerValueId;
    }

    public void setQuestion(Question question){
       this.question = question;
    }

    public void setAnswerValue(){
       this.answerValue = answerValue;
    }
}

Et le DAO:

// QuestionDao.Java
public class QuestionDao {
   public void saveOrUpdateAll(List<Question> list){
      getHibernateTemplate().saveOrUpdateAll(list);
   }
}

Il semble que lorsque j'appelle saveOrUpdateAll, la question est enregistrée, mais les AnswerValue qui sont des enfants de l'objet Question ne le sont pas.

Aucune suggestion?

17
user1732480

vous devez le faire manuellement ou ajouter la propriété cascade à votre annotation, c'est-à-dire Hibernate: Cascade Type

ou Hibernate: Comment utiliser la cascade dans l'annotation?

6
ilcavero

Pour la relation oneToMany, veuillez définir l'annotation de mappage cascade comme:

    Cascade={CascadeType.ALL}

ou

     Cascade={ CascadeType.ALL, CascadeType.DELETE_Orphan }

Dans votre cartographie:

    @ManyToOne(fetch = FetchType.EAGER, 
               cascade = { CascadeType.ALL, CascadeType.DELETE_Orphan })
    @JoinColumn(name = "question_id",referencedColumnName="question_id")
    public Set<AnswerValue> getAnswerValues(){
        return answerValues;
    }
5
Yogendra Singh

Si vous avez une relation un-à-plusieurs entre les entités Question et Réponse, alors pourquoi utilisez-vous:

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "question_id",referencedColumnName="question_id")
public Set<AnswerValue> getAnswerValues(){
    return answerValues;
}

Je pense que vous devriez utiliser ceci à la place:

@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "question_id",referencedColumnName="question_id")
public Set<AnswerValue> getAnswerValues(){
    return answerValues;
}
3
rohith