CrudRepository.save () выглядит каскадно - PullRequest
1 голос
/ 13 марта 2020

Исследование сущностей:

    @Entity
    @Table(name = "Survey")
    public class Survey implements Serializable {

        private Long id;
        private String name;
        private String address;
        private List<Question> questions;

        @Id
        @Column(name = "id")
        public Long getId() {
            return id;
        }

        @Column(name = "name")
        public String getName() {
            return name;
        }

        @Column(name = "address")
        public String getAddress() {
            return address;
        }

        @OneToMany(fetch = FetchType.LAZY, mappedBy = "survey")
        public List<Question> getQuestions() {
            return questions;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public void setName(final String name) {
            this.name = name;
        }

        public void setAddress(final String address) {
            this.address = address;
        }

        public void setQuestions(List<Question> _questions) {
            this.questions = _questions;
        }
    }

Вопрос сущности:

@Entity
@Table(name = "Question")
public class Question {

    private Long id;
    private String question;
    private Survey survey;

    @Id
    @Column(name = "id")
    public Long getId() {
        return id;
    }

    @Column(name = "question")
    public String getQuestion() {
        return question;
    }

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

    public void setId(Long id) {
        this.id = id;
    }

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

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

Вопрос Crud Repo:

 public interface QuestionRepo extends CrudRepository<Question, Long> {
    }

Контроллер:

@RestController
@RequestMapping("/default")
public class DefaultEndpoint {

    @Autowired
    private QuestionRepo questionRepo;


    @PostMapping(value = "/saveQuestion")
    public void saveQuestion(@Param("id") Long id, @Param("question") String question, @Param("survey_id") Long survey_id) {
        Question questionObject = new Question();
        questionObject.setId(id);
        questionObject.setQuestion(question);
        Survey survey = surveyRepo.findById(survey_id).get();
        survey.setName("example");
        questionObject.setSurvey(survey);
        questionRepo.save(questionObject);
    }
}

В фрагменте Контроллера, когда я делаю survey.setName («пример»); . это изменение отражается в базе данных.

Это означает, что операция save () , которая реализована с помощью методов EntityManager MERGE и PERIST, распространяется каскадно на дочернюю сущность, даже если не указан тип Cascade.
Это так должен работать, или я делаю какую-то глупую ошибку?
Большое спасибо!

Ответы [ 2 ]

1 голос
/ 13 марта 2020

Пожалуйста, отметьте аннотацию @ManyToOne, чтобы увидеть, что каскад по умолчанию отсутствует.

public @interface ManyToOne {
   /**
     * (Optional) The operations that must be cascaded to 
     * the target of the association.
     *
     * <p> By default no operations are cascaded.
     */
    CascadeType[] cascade() default {};
}

Каскад не происходит.

Скорее всего, наблюдаемый вами эффект является Комбинация из 2 функций:

Если вы используете веб-приложение Spring Boot по умолчанию регистрирует OpenEntityManagerInViewInterceptor для применения шаблона «Открыть EntityManager в представлении», чтобы обеспечить ленивую загрузку в веб-представлениях. Если вы не хотите, чтобы такое поведение, вы должны установить spring.jpa.open-in-view в false в вашем application.properties.

Грязная проверка хорошо известна, но Open Session In View, как правило, удивляет некоторых devs (например, см. другой связанный эффект в Spring - та же сущность, отсоединенная на @EventListener, но присоединенная в классе @Service )

0 голосов
/ 13 марта 2020

Это грязный механизм проверки. Например, когда вы используете sh постоянный контекст или фиксируете транзакцию, Hibernate проверяет контекст на грязное состояние сущностей и выполняет SQL обновление для синхронизации в памяти с состоянием базы данных. Вы можете проверить это сообщение , чтобы получить более подробную информацию

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...