1

实体调查:

    @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 回购:

 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("example"); . 这种变化反映在数据库上。

这意味着即使没有指定 Cascade 类型,使用 EntityManager 方法 MERGE 和 PERIST 实现的save()操作也会级联到子实体。
这是它应该如何工作,还是我犯了一些愚蠢的错误?
非常感谢 !

4

2 回答 2

1

请检查@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 个特征的组合:

如果您正在运行 Web 应用程序,Spring Boot 默认注册 OpenEntityManagerInViewInterceptor 以应用“在视图中打开 EntityManager”模式,以允许在 Web 视图中延迟加载。如果您不希望这种行为,您应该spring.jpa.open-in-view在 application.properties 中设置为 false。

Dirty Checking 是众所周知的,但 Open Session In View 往往会让一些开发人员感到惊讶(例如,查看Spring 中的另一个相关效果 - 相同的实体在 @EventListener 上分离但附加在 @Service 类中

于 2020-03-13T19:36:13.330 回答
0

这是脏检查机制。例如,当您刷新持久性上下文或提交事务时,Hibernate 会检查上下文中实体的脏状态并执行 SQL 更新以将内存中的状态与数据库状态同步。您可以查看此帖子以获取更多详细信息

于 2020-03-13T19:12:20.740 回答