DB和应用程序之间的双向OneToMany关系不同步

时间:2017-07-18 09:49:50

标签: spring hibernate jpa spring-boot one-to-many

运行我的spring启动应用程序时,使用调试器,应用程序中的对象与数据库中的信息不同。数据库中的信息是正确的 - 应用程序错误。据我所知,由于我保存对象时触发的选择语句,应用程序对象已损坏。我认为这是hibernate脏检查的副作用。但是我把这留给你判断。

我遇到问题的代码处理需求,可以分配到条款,模型"何时做什么"。术语是抽象的。具体类别是例如发布,阶段。要求也是抽象的,取决于大小,具体类别可以是例如Epic,UserStory。但是,赋值和取消分配条款要求的getter和setter在抽象类中。要求和条款可以彼此独立存在。

我有以下设置:Spring启动,MySql,JavaFX UI + Controller类,它使用@Controller注释,许多实体,每个实体都注释了@Entity。控制器使用自动服务的服务,每个服务都使用@Service注释。这些服务使用自动装配的存储库,每个存储库都扩展了CrudRepository。所以我没有明确地使用任何EntityManager,而只使用save(),findAll()等。

我按照https://www.sogehtsoftware.de/blog/post/javafx-persistence-teil-3-jpa-lazy-loading中解释的方法来建模我的OneToMany / ManyToOne关系,看起来像这样

..

@Entity
@Inheritance
@Access(AccessType.FIELD)
public abstract class Requirement implements Serializable {

    .. several fields ..

    @ManyToOne
    private Term term;

    .. constructors, getter and setter of other fields ..

    public Term getTerm() {
        return term;
    }

    public void setTerm(Term newTerm) {

        String txt = newTerm==null?"null":newTerm.debug();
        logger.debug(txt);

        if(term != null) {
            term.delRequirement(this);
        }
        this.term = newTerm;
    }
}

..

@Entity
@Inheritance
@Access(AccessType.FIELD)
public abstract class Term implements Serializable {

    .. several fields ..

    /*
    * see https://www.sogehtsoftware.de/blog/post/javafx-persistence-teil-3-jpa-lazy-loading
    */
    @Transient
    private List<Requirement> requirements;
    @Transient
    private ObservableList<Requirement> observableRequirements = FXCollections.observableArrayList();   // an observable mirror of field requirements

    .. constructors, getter and setter of other fields ..

    public ObservableList<Requirement> getObservableRequirements() {
        return observableRequirements;
    }

    @Access(AccessType.PROPERTY)
    @OneToMany(mappedBy="term", fetch = FetchType.LAZY)
    private List<Requirement> getRequirements() {
        return requirements;
    }

    @SuppressWarnings("unused")     // Used by JPA
    private void setRequirements(List<Requirement> requirements) {

        logger.debug(requirements.size() + " reqs to " + this.debug());

        this.requirements = requirements;
        observableRequirements.setAll(FXCollections.observableArrayList(requirements));
    }

    public void addRequirement(Requirement requirement) {

        logger.debug(requirement.debug() + " to " + this.debug());

        requirements.add(requirement);
        observableRequirements.add(requirement);
        requirement.setTerm(this);
    }

    public void delRequirement(Requirement requirement) {

        logger.debug(requirement.debug() + " from " + this.debug());

        if(requirements.contains(requirement)) {
            if(!requirements.remove(requirement)) {
                logger.error("Removal of requirement from list failed! Term: " + this.toString());
            }
            if(!observableRequirements.remove(requirement)) {
                logger.error("Removal of requirement from observable list failed! Term: " + this.toString());
            }

            requirement.setTerm(null);
        }
    }
}

我在启动时使用CommandLineRunner填充应用程序和数据库以及一些测试数据。这很完美。当我从Term中取消分配Requirement并保存时,Term的数据库和Requirements List对象最初都是正确的。控制器的代码如下所示:

protected void unassignRequirement(Requirement requirement, Term term {

    logger.debug("Enter: " + requirement.debug() + "; " + term);

    if(term == null) {
        return;
    }

    ChronoUnit chronoUnit =  requirement.getDefaultEffortUnit();

    if(term != null) {
            term.delRequirement(requirement);
            chronoUnit = term.getDefaultTimeUnit();
    }

    logger.debug("Calling save on requirement");
    reqService.save(requirement);

    requirementsTreeView.refresh();  // show the requirement in a different color to indicate that it is assigned
    updateEffortInfo(assignedRequirementsListView.getItems(), chronoUnit);

    logger.debug("Leave: " + requirement.debug());

    // Interestingly, when I stop here for debugging requirement.getTerm() returns null as it should be
}

但此后立即,如果我检查需求的内容,getTerm()将返回先前的Term assoziation,就像它从未设置为null一样。

用户点击取消分配按钮后,这是跟踪(由于空间限制而缩短):

 DEBUG  PlanningPaneController.getSelectedAssignedRequirements:422: Enter getSelectedUnassignedRequirement 
DEBUG  PlanningPaneController.getSelectedTerm:429: Enter getSelectedTerm 
DEBUG  PlanningPaneController.unassignRequirement:359: Enter: 1@Epic: administrate the requirements; Term: first release; first release; null 
DEBUG  Term.delRequirement:283: 1@Epic: administrate the requirements; Term: first release from 1@Release: first release; 2 requirements; 5 children as root element 
DEBUG  PlanningPaneController$4.changed:264: Enter getAssignRequirementsChangeListener::changed: As a System Engineer, I want handle technical risks, such that to prioritize the development order 
DEBUG  Requirement.setTerm:336: null 
DEBUG  Term.delRequirement:283: 1@Epic: administrate the requirements; Term: first release from 1@Release: first release; 1 requirements; 5 children as root element 
DEBUG  PlanningPaneController.unassignRequirement:380: Calling save on requirement 
Hibernate: select epic0_.id as id2_2_0_, epic0_.default_effort_unit as default_3_2_0_, epic0_.parent_id as parent_i8_2_0_, .. (cut)
Hibernate: select product0_.id as id1_1_1_, product0_.identifier as identifi2_1_1_, product0_.parent_id as parent_i3_1_1_, .. (cut)
Hibernate: select term0_.id as id2_5_2_, term0_.begin as begin3_5_2_, term0_.default_time_unit as default_4_5_2_, .. (cut)
Hibernate: select term0_.id as id2_5_2_, term0_.begin as begin3_5_2_, term0_.default_time_unit as default_4_5_2_, term0_.end as end5_5_2_, .. (cut)
Hibernate: select children0_.parent_id as parent_14_5_0_, children0_.id as id2_5_0_, children0_.id as id2_5_1_, children0_.begin as begin3_5_1_, .. (cut)
Hibernate: select children0_.parent_id as parent_14_5_0_, children0_.id as id2_5_0_, children0_.id as id2_5_1_, children0_.begin as begin3_5_1_, .. (cut)
Hibernate: select requiremen0_.term_id as term_id11_2_0_, requiremen0_.id as id2_2_0_, requiremen0_.id as id2_2_1_, requiremen0_.default_effort_unit as default_3_2_1_, ..  (cut)
.. several setRequirements of Terms ..
DEBUG  Term.setRequirements:264: 2 reqs to 1@Release: first release; 0 requirements; 5 children as root element 
Hibernate: select children0_.parent_id as parent_i8_2_0_, children0_.id as id2_2_0_, children0_.id as id2_2_1_, children0_.default_effort_unit as default_3_2_1_, .. (cut)
Hibernate: select children0_.parent_id as parent_i8_2_0_, children0_.id as id2_2_0_, children0_.id as id2_2_1_, children0_.default_effort_unit as default_3_2_1_, .. (cut)
Hibernate: select effortesti0_.parental_requirement_id as parenta10_0_0_, effortesti0_.id as id1_0_0_, effortesti0_.id as id1_0_1_, effortesti0_.best_case_estimate as best_cas2_0_1_, .. (cut)
Hibernate: select status0_.parental_requirement_id as parental5_3_0_, status0_.id as id1_3_0_, status0_.id as id1_3_1_, status0_.creation_time as creation2_3_1_, status0_.owner as owner3_3_1_, .. (cut)
Hibernate: select children0_.parent_id as parent_i8_2_0_, children0_.id as id2_2_0_, children0_.id as id2_2_1_, children0_.default_effort_unit as default_3_2_1_, .. (cut)
Hibernate: select effortesti0_.parental_requirement_id as parenta10_0_0_, effortesti0_.id as id1_0_0_, effortesti0_.id as id1_0_1_, effortesti0_.best_case_estimate as best_cas2_0_1_, .. (cut)
Hibernate: select status0_.parental_requirement_id as parental5_3_0_, status0_.id as id1_3_0_, status0_.id as id1_3_1_, status0_.creation_time as creation2_3_1_, status0_.owner as owner3_3_1_, status0_.parental_requirement_id as parental5_3_1_, status0_.state as state4_3_1_ from requirement_status status0_ where status0_.parental_requirement_id=?
Hibernate: select children0_.parent_id as parent_i8_2_0_, children0_.id as id2_2_0_, children0_.id as id2_2_1_, children0_.default_effort_unit as default_3_2_1_, children0_.parent_id as parent_i8_2_1_, children0_.product_id as product_9_2_1_, children0_.team_id as team_id10_2_1_, children0_.term_id as term_id11_2_1_, children0_.req_what as req_what4_2_1_, children0_.req_when as req_when5_2_1_, children0_.req_who as req_who6_2_1_, children0_.req_why as req_why7_2_1_, children0_.dtype as dtype1_2_1_, product1_.id as id1_1_2_, product1_.identifier as identifi2_1_2_, product1_.parent_id as parent_i3_1_2_, product2_.id as id1_1_3_, product2_.identifier as identifi2_1_3_, product2_.parent_id as parent_i3_1_3_, team3_.id as id1_4_4_, team3_.capacity_per_day as capacity2_4_4_, team3_.identifier as identifi3_4_4_, term4_.id as id2_5_5_, term4_.begin as begin3_5_5_, term4_.default_time_unit as default_4_5_5_, term4_.end as end5_5_5_, term4_.goal as goal6_5_5_, term4_.identifier as identifi7_5_5_, term4_.my_number as my_numbe8_5_5_, term4_.my_state as my_state9_5_5_, term4_.my_type as my_type10_5_5_, term4_.owner as owner11_5_5_, term4_.parent_id as parent_14_5_5_, term4_.predecessor_id as predece15_5_5_, term4_.publishing_date as publish12_5_5_, term4_.successor_id as success16_5_5_, term4_.version as version13_5_5_, term4_.product_id as product17_5_5_, term4_.dtype as dtype1_5_5_, term5_.id as id2_5_6_, term5_.begin as begin3_5_6_, term5_.default_time_unit as default_4_5_6_, term5_.end as end5_5_6_, term5_.goal as goal6_5_6_, term5_.identifier as identifi7_5_6_, term5_.my_number as my_numbe8_5_6_, term5_.my_state as my_state9_5_6_, term5_.my_type as my_type10_5_6_, term5_.owner as owner11_5_6_, term5_.parent_id as parent_14_5_6_, term5_.predecessor_id as predece15_5_6_, term5_.publishing_date as publish12_5_6_, term5_.successor_id as success16_5_6_, term5_.version as version13_5_6_, term5_.product_id as product17_5_6_, term5_.dtype as dtype1_5_6_, term6_.id as id2_5_7_, term6_.begin as begin3_5_7_, term6_.default_time_unit as default_4_5_7_, term6_.end as end5_5_7_, term6_.goal as goal6_5_7_, term6_.identifier as identifi7_5_7_, term6_.my_number as my_numbe8_5_7_, term6_.my_state as my_state9_5_7_, term6_.my_type as my_type10_5_7_, term6_.owner as owner11_5_7_, term6_.parent_id as parent_14_5_7_, term6_.predecessor_id as predece15_5_7_, term6_.publishing_date as publish12_5_7_, term6_.successor_id as success16_5_7_, term6_.version as version13_5_7_, term6_.product_id as product17_5_7_, term6_.dtype as dtype1_5_7_, term7_.id as id2_5_8_, term7_.begin as begin3_5_8_, term7_.default_time_unit as default_4_5_8_, term7_.end as end5_5_8_, term7_.goal as goal6_5_8_, term7_.identifier as identifi7_5_8_, term7_.my_number as my_numbe8_5_8_, term7_.my_state as my_state9_5_8_, term7_.my_type as my_type10_5_8_, term7_.owner as owner11_5_8_, term7_.parent_id as parent_14_5_8_, term7_.predecessor_id as predece15_5_8_, term7_.publishing_date as publish12_5_8_, term7_.successor_id as success16_5_8_, term7_.version as version13_5_8_, term7_.product_id as product17_5_8_, term7_.dtype as dtype1_5_8_, product8_.id as id1_1_9_, product8_.identifier as identifi2_1_9_, product8_.parent_id as parent_i3_1_9_ from requirement children0_ left outer join product product1_ on children0_.product_id=product1_.id left outer join product product2_ on product1_.parent_id=product2_.id left outer join team team3_ on children0_.team_id=team3_.id left outer join term term4_ on children0_.term_id=term4_.id left outer join term term5_ on term4_.parent_id=term5_.id left outer join term term6_ on term4_.predecessor_id=term6_.id left outer join term term7_ on term4_.successor_id=term7_.id left outer join product product8_ on term4_.product_id=product8_.id where children0_.parent_id=?
Hibernate: select effortesti0_.parental_requirement_id as parenta10_0_0_, effortesti0_.id as id1_0_0_, effortesti0_.id as id1_0_1_, effortesti0_.best_case_estimate as best_cas2_0_1_, effortesti0_.creation_date as creation3_0_1_, effortesti0_.fraction_of_parent as fraction4_0_1_, effortesti0_.owner as owner5_0_1_, effortesti0_.parental_requirement_id as parenta10_0_1_, effortesti0_.realistic_case_estimate as realisti6_0_1_, effortesti0_.remaining_effort_estimate as remainin7_0_1_, effortesti0_.time_unit as time_uni8_0_1_, effortesti0_.worst_case_estimate as worst_ca9_0_1_ from effort_estimate effortesti0_ where effortesti0_.parental_requirement_id=?
Hibernate: select status0_.parental_requirement_id as parental5_3_0_, status0_.id as id1_3_0_, status0_.id as id1_3_1_, status0_.creation_time as creation2_3_1_, status0_.owner as owner3_3_1_, status0_.parental_requirement_id as parental5_3_1_, status0_.state as state4_3_1_ from requirement_status status0_ where status0_.parental_requirement_id=?
Hibernate: select effortesti0_.parental_requirement_id as parenta10_0_0_, effortesti0_.id as id1_0_0_, effortesti0_.id as id1_0_1_, effortesti0_.best_case_estimate as best_cas2_0_1_, effortesti0_.creation_date as creation3_0_1_, effortesti0_.fraction_of_parent as fraction4_0_1_, effortesti0_.owner as owner5_0_1_, effortesti0_.parental_requirement_id as parenta10_0_1_, effortesti0_.realistic_case_estimate as realisti6_0_1_, effortesti0_.remaining_effort_estimate as remainin7_0_1_, effortesti0_.time_unit as time_uni8_0_1_, effortesti0_.worst_case_estimate as worst_ca9_0_1_ from effort_estimate effortesti0_ where effortesti0_.parental_requirement_id=?
Hibernate: select status0_.parental_requirement_id as parental5_3_0_, status0_.id as id1_3_0_, status0_.id as id1_3_1_, status0_.creation_time as creation2_3_1_, status0_.owner as owner3_3_1_, status0_.parental_requirement_id as parental5_3_1_, status0_.state as state4_3_1_ from requirement_status status0_ where status0_.parental_requirement_id=?
Hibernate: select requiremen0_.product_id as product_9_2_0_, requiremen0_.id as id2_2_0_, requiremen0_.id as id2_2_1_, requiremen0_.default_effort_unit as default_3_2_1_, requiremen0_.parent_id as parent_i8_2_1_, requiremen0_.product_id as product_9_2_1_, requiremen0_.team_id as team_id10_2_1_, requiremen0_.term_id as term_id11_2_1_, requiremen0_.req_what as req_what4_2_1_, requiremen0_.req_when as req_when5_2_1_, requiremen0_.req_who as req_who6_2_1_, requiremen0_.req_why as req_why7_2_1_, requiremen0_.dtype as dtype1_2_1_, requiremen1_.id as id2_2_2_, requiremen1_.default_effort_unit as default_3_2_2_, requiremen1_.parent_id as parent_i8_2_2_, requiremen1_.product_id as product_9_2_2_, requiremen1_.team_id as team_id10_2_2_, requiremen1_.term_id as term_id11_2_2_, requiremen1_.req_what as req_what4_2_2_, requiremen1_.req_when as req_when5_2_2_, requiremen1_.req_who as req_who6_2_2_, requiremen1_.req_why as req_why7_2_2_, requiremen1_.dtype as dtype1_2_2_, team2_.id as id1_4_3_, team2_.capacity_per_day as capacity2_4_3_, team2_.identifier as identifi3_4_3_, term3_.id as id2_5_4_, term3_.begin as begin3_5_4_, term3_.default_time_unit as default_4_5_4_, term3_.end as end5_5_4_, term3_.goal as goal6_5_4_, term3_.identifier as identifi7_5_4_, term3_.my_number as my_numbe8_5_4_, term3_.my_state as my_state9_5_4_, term3_.my_type as my_type10_5_4_, term3_.owner as owner11_5_4_, term3_.parent_id as parent_14_5_4_, term3_.predecessor_id as predece15_5_4_, term3_.publishing_date as publish12_5_4_, term3_.successor_id as success16_5_4_, term3_.version as version13_5_4_, term3_.product_id as product17_5_4_, term3_.dtype as dtype1_5_4_ from requirement requiremen0_ left outer join requirement requiremen1_ on requiremen0_.parent_id=requiremen1_.id left outer join team team2_ on requiremen1_.team_id=team2_.id left outer join term term3_ on requiremen1_.term_id=term3_.id where requiremen0_.product_id=?
Hibernate: select children0_.parent_id as parent_i8_2_0_, children0_.id as id2_2_0_, children0_.id as id2_2_1_, children0_.default_effort_unit as default_3_2_1_, children0_.parent_id as parent_i8_2_1_, children0_.product_id as product_9_2_1_, children0_.team_id as team_id10_2_1_, children0_.term_id as term_id11_2_1_, children0_.req_what as req_what4_2_1_, children0_.req_when as req_when5_2_1_, children0_.req_who as req_who6_2_1_, children0_.req_why as req_why7_2_1_, children0_.dtype as dtype1_2_1_, product1_.id as id1_1_2_, product1_.identifier as identifi2_1_2_, product1_.parent_id as parent_i3_1_2_, product2_.id as id1_1_3_, product2_.identifier as identifi2_1_3_, product2_.parent_id as parent_i3_1_3_, team3_.id as id1_4_4_, team3_.capacity_per_day as capacity2_4_4_, team3_.identifier as identifi3_4_4_, term4_.id as id2_5_5_, term4_.begin as begin3_5_5_, term4_.default_time_unit as default_4_5_5_, term4_.end as end5_5_5_, term4_.goal as goal6_5_5_, term4_.identifier as identifi7_5_5_, term4_.my_number as my_numbe8_5_5_, term4_.my_state as my_state9_5_5_, term4_.my_type as my_type10_5_5_, term4_.owner as owner11_5_5_, term4_.parent_id as parent_14_5_5_, term4_.predecessor_id as predece15_5_5_, term4_.publishing_date as publish12_5_5_, term4_.successor_id as success16_5_5_, term4_.version as version13_5_5_, term4_.product_id as product17_5_5_, term4_.dtype as dtype1_5_5_, term5_.id as id2_5_6_, term5_.begin as begin3_5_6_, term5_.default_time_unit as default_4_5_6_, term5_.end as end5_5_6_, term5_.goal as goal6_5_6_, term5_.identifier as identifi7_5_6_, term5_.my_number as my_numbe8_5_6_, term5_.my_state as my_state9_5_6_, term5_.my_type as my_type10_5_6_, term5_.owner as owner11_5_6_, term5_.parent_id as parent_14_5_6_, term5_.predecessor_id as predece15_5_6_, term5_.publishing_date as publish12_5_6_, term5_.successor_id as success16_5_6_, term5_.version as version13_5_6_, term5_.product_id as product17_5_6_, term5_.dtype as dtype1_5_6_, term6_.id as id2_5_7_, term6_.begin as begin3_5_7_, term6_.default_time_unit as default_4_5_7_, term6_.end as end5_5_7_, term6_.goal as goal6_5_7_, term6_.identifier as identifi7_5_7_, term6_.my_number as my_numbe8_5_7_, term6_.my_state as my_state9_5_7_, term6_.my_type as my_type10_5_7_, term6_.owner as owner11_5_7_, term6_.parent_id as parent_14_5_7_, term6_.predecessor_id as predece15_5_7_, term6_.publishing_date as publish12_5_7_, term6_.successor_id as success16_5_7_, term6_.version as version13_5_7_, term6_.product_id as product17_5_7_, term6_.dtype as dtype1_5_7_, term7_.id as id2_5_8_, term7_.begin as begin3_5_8_, term7_.default_time_unit as default_4_5_8_, term7_.end as end5_5_8_, term7_.goal as goal6_5_8_, term7_.identifier as identifi7_5_8_, term7_.my_number as my_numbe8_5_8_, term7_.my_state as my_state9_5_8_, term7_.my_type as my_type10_5_8_, term7_.owner as owner11_5_8_, term7_.parent_id as parent_14_5_8_, term7_.predecessor_id as predece15_5_8_, term7_.publishing_date as publish12_5_8_, term7_.successor_id as success16_5_8_, term7_.version as version13_5_8_, term7_.product_id as product17_5_8_, term7_.dtype as dtype1_5_8_, product8_.id as id1_1_9_, product8_.identifier as identifi2_1_9_, product8_.parent_id as parent_i3_1_9_ from requirement children0_ left outer join product product1_ on children0_.product_id=product1_.id left outer join product product2_ on product1_.parent_id=product2_.id left outer join team team3_ on children0_.team_id=team3_.id left outer join term term4_ on children0_.term_id=term4_.id left outer join term term5_ on term4_.parent_id=term5_.id left outer join term term6_ on term4_.predecessor_id=term6_.id left outer join term term7_ on term4_.successor_id=term7_.id left outer join product product8_ on term4_.product_id=product8_.id where children0_.parent_id=?
Hibernate: select effortesti0_.parental_requirement_id as parenta10_0_0_, effortesti0_.id as id1_0_0_, effortesti0_.id as id1_0_1_, effortesti0_.best_case_estimate as best_cas2_0_1_, effortesti0_.creation_date as creation3_0_1_, effortesti0_.fraction_of_parent as fraction4_0_1_, effortesti0_.owner as owner5_0_1_, effortesti0_.parental_requirement_id as parenta10_0_1_, effortesti0_.realistic_case_estimate as realisti6_0_1_, effortesti0_.remaining_effort_estimate as remainin7_0_1_, effortesti0_.time_unit as time_uni8_0_1_, effortesti0_.worst_case_estimate as worst_ca9_0_1_ from effort_estimate effortesti0_ where effortesti0_.parental_requirement_id=?
Hibernate: select status0_.parental_requirement_id as parental5_3_0_, status0_.id as id1_3_0_, status0_.id as id1_3_1_, status0_.creation_time as creation2_3_1_, status0_.owner as owner3_3_1_, status0_.parental_requirement_id as parental5_3_1_, status0_.state as state4_3_1_ from requirement_status status0_ where status0_.parental_requirement_id=?
Hibernate: select releases0_.product_id as product17_5_0_, releases0_.id as id2_5_0_, releases0_.id as id2_5_1_, releases0_.begin as begin3_5_1_, releases0_.default_time_unit as default_4_5_1_, releases0_.end as end5_5_1_, releases0_.goal as goal6_5_1_, releases0_.identifier as identifi7_5_1_, releases0_.my_number as my_numbe8_5_1_, releases0_.my_state as my_state9_5_1_, releases0_.my_type as my_type10_5_1_, releases0_.owner as owner11_5_1_, releases0_.parent_id as parent_14_5_1_, releases0_.predecessor_id as predece15_5_1_, releases0_.publishing_date as publish12_5_1_, releases0_.successor_id as success16_5_1_, releases0_.version as version13_5_1_, releases0_.product_id as product17_5_1_, term1_.id as id2_5_2_, term1_.begin as begin3_5_2_, term1_.default_time_unit as default_4_5_2_, term1_.end as end5_5_2_, term1_.goal as goal6_5_2_, term1_.identifier as identifi7_5_2_, term1_.my_number as my_numbe8_5_2_, term1_.my_state as my_state9_5_2_, term1_.my_type as my_type10_5_2_, term1_.owner as owner11_5_2_, term1_.parent_id as parent_14_5_2_, term1_.predecessor_id as predece15_5_2_, term1_.publishing_date as publish12_5_2_, term1_.successor_id as success16_5_2_, term1_.version as version13_5_2_, term1_.product_id as product17_5_2_, term1_.dtype as dtype1_5_2_, term2_.id as id2_5_3_, term2_.begin as begin3_5_3_, term2_.default_time_unit as default_4_5_3_, term2_.end as end5_5_3_, term2_.goal as goal6_5_3_, term2_.identifier as identifi7_5_3_, term2_.my_number as my_numbe8_5_3_, term2_.my_state as my_state9_5_3_, term2_.my_type as my_type10_5_3_, term2_.owner as owner11_5_3_, term2_.parent_id as parent_14_5_3_, term2_.predecessor_id as predece15_5_3_, term2_.publishing_date as publish12_5_3_, term2_.successor_id as success16_5_3_, term2_.version as version13_5_3_, term2_.product_id as product17_5_3_, term2_.dtype as dtype1_5_3_, term3_.id as id2_5_4_, term3_.begin as begin3_5_4_, term3_.default_time_unit as default_4_5_4_, term3_.end as end5_5_4_, term3_.goal as goal6_5_4_, term3_.identifier as identifi7_5_4_, term3_.my_number as my_numbe8_5_4_, term3_.my_state as my_state9_5_4_, term3_.my_type as my_type10_5_4_, term3_.owner as owner11_5_4_, term3_.parent_id as parent_14_5_4_, term3_.predecessor_id as predece15_5_4_, term3_.publishing_date as publish12_5_4_, term3_.successor_id as success16_5_4_, term3_.version as version13_5_4_, term3_.product_id as product17_5_4_, term3_.dtype as dtype1_5_4_ from term releases0_ left outer join term term1_ on releases0_.parent_id=term1_.id left outer join term term2_ on term1_.predecessor_id=term2_.id left outer join term term3_ on term1_.successor_id=term3_.id where releases0_.product_id=?
Hibernate: update requirement set default_effort_unit=?, parent_id=?, product_id=?, team_id=?, term_id=?, req_what=?, req_when=?, req_who=?, req_why=? where id=?
DEBUG  PlanningPaneController.updateEffortInfo:279: Enter updateEffortInfo: 1 requirements; ChronoUnit: Years 
DEBUG  PlanningPaneController.unassignRequirement:386: Leave: 1@Epic: administrate the requirements; Term: null  <<< CORRECT !!

User selects Requirement from TreeView - no other interaction

DEBUG 05:32:25 PlanningPaneController$3.changed:234: Enter getRequirementSelectionChangeListener::changed: 1@Epic: administrate the requirements; Term: first release  <<< WRONG !!
DEBUG 05:32:25 PlanningPaneController.getSelectedTerm:429: Enter getSelectedTerm 

如果您需要其他信息或代码,请与我们联系。

我还需要做什么,在应用程序中也有正确的对象?

1 个答案:

答案 0 :(得分:0)

这听起来像是jpa的级联规则的问题。当持久化要求时,它可能不会持续更改术语,因此刷新后链接仍然存在。

考虑以下选项: