OneToMany - 修改集合[删除/更新] - 双向

时间:2014-02-28 09:06:56

标签: hibernate jpa

我有一个关系OneToMany:1工作有N个步骤 我想更新工作的列表步骤。

添加新元素有效,但是当我想要更新或删除元素时,似乎没有。

  1. 更新:不要更新正确的元素
  2. 删除:不删除关系(对于已删除的元素)
  3. 这里是我的实体:(我还没有定义equals和hascode方法)

    工作:

    @Entity
    @Table(name = "T_STEP")
    @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
    @DiscriminatorOptions(force = true)
    @DiscriminatorColumn(name = "BL_DELETE", discriminatorType = DiscriminatorType.INTEGER)
    public class WorkEntity implements Serializable {
    
      @OneToMany(mappedBy = "STEP", cascade = CascadeType.ALL)
      // @OneToMany(cascade = CascadeType.ALL)
      // @JoinColumn(name = "ID_TRA")
      private Set < StepEntityEntity > etapes = new HashSet <>();
    

    步骤:

    @Entity
    @Table(name = "T_STEP")
    @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
    @DiscriminatorOptions(force = true)
    @DiscriminatorColumn(name = "BL_DELETE", discriminatorType = DiscriminatorType.INTEGER)
    public class StepEntity implements Serializable {
    
      @ManyToOne
      @JoinColumn(name = "ID_WORK", updatable = true, insertable = true)
      private WorkEntity work;
    

    在我的数据库中,我有:

    工作   - [ID:01 - ID_WORK:01 - LABEL:stepOne]

    步骤   - [ID:01 - ID_WORK:01 - LABEL:stepOne]   - [ID:02 - ID_WORK:02 - LABEL:stepTwo]

    测试:获取实体并将元素添加到步骤集合中。 当我这样做时:

    // GET ENTITY
    WorkEntity workOne = getEntityManager().find(WorkEntity.clazz, 01);
    
    StepEntity stepThree = new StepEntity("stepThree");
    StepEntity stepFour = new StepEntity("stepFour");
    stepThree.setWork(workOne);
    stepFour.setWork(workOne);
    
    Set <StepEntity> newList = workEntity.getSteps();
    newList.add(stepThree);
    newList.add(stepFour);
    workEntity.getSteps().clear();
    workEntity.getSteps().setSteps(newList);
    

    这项工作: 步骤:

    • [ID:01 - ID_WORK:01 - LABEL:stepOne]
    • [ID:02 - ID_WORK:02 - LABEL:stepTwo]
    • [ID:03 - ID_WORK:03 - LABEL:stepThree] // element add OK
    • [ID:04 - ID_WORK:04 - LABEL:stepTwo] // element add OK

    #TEST 02:添加+更新

    // GET ENTITY
    WorkEntity workOne = getEntityManager().find(WorkEntity.clazz, 01);
    
    StepEntity stepThree = new StepEntity("stepThree");
    StepEntity stepFour = new StepEntity("stepFour");
    stepThree.setWork(workOne);
    
    Set <StepEntity> newList = new HashSet(workEntity.getSteps());
    List <StepEntity> aa = new ArrayList<StepEntity>(workEntity.getSteps()); // to do an easy get
    
    Step keepStepTwo = aa.get(1);
    
    keepStepTwo.setLabel("I changed !");
    newList.add(keepStepTwo);
    newList.add(stepThree);
    newList.add(stepFour);
    
    //init and set
    workEntity.getSteps().clear();
    workEntity.getSteps().setSteps(newList);
    

    我有: 步骤:

    • [ID:01 - ID_WORK:01 - LABEL:我改了!] //而不是被删除
    • [ID:02 - ID_WORK:02 - LABEL:stepTwo] //有意改变......
    • [ID:03 - ID_WORK:03 - LABEL:stepThree]
    • [ID:04 - ID_WORK:04 - LABEL:stepTwo]

    我期待:

    • [ID:01 - ID_WORK: NULL - LABEL:stepOne] //删除关系。
    • [ID:02 - ID_WORK:02 - LABEL:我改了!] //实体更新
    • [ID:03 - ID_WORK:03 - LABEL:stepThree]
    • [ID:04 - ID_WORK:04 - LABEL:stepTwo]

    谢谢,

1 个答案:

答案 0 :(得分:0)

看起来你并不是真的理解Java可以使用引用。您不需要从实体获取步骤集合,构造副本,向副本添加元素以及将实体集合设置为此副本。您需要做的就是在实体的步骤集合中添加一个元素:

entity.getStep(s).add(...);

您还假设实体将始终以相同的顺序位于集合中(步骤1,然后是步骤2)。事实并非如此。首先是因为Set没有任何订单。其次是因为,即使使用List,如果不对列表进行排序,或者使用OrderColumn对其进行排序,列表实际上也是一个包,其中元素的顺序是任意的。

那就是说。主要问题是,再次,您只修改关联的反面,而不修改所有者方。所有者方是Step.work。这就是您需要修改以设置/删除关联。所以,要添加一个新步骤:

Step step = new Step();
step.setWork(work); // mandatory
em.persist(step);
work.getSteps().add(step); // optional, but needed to keep the coherence of the object  graph

更新步骤的标签:

Set<Step> steps = work.getSteps();
Step step1 = findStepHavingLabel(steps, "stepOne");
step1.setLabel("changed");

断开步骤与其工作的关系:

Set<Step> steps = work.getSteps();
Step step1 = findStepHavingLabel(steps, "stepOne");
step1.setWork(null); // mandatory
steps.remove(step1); // optional, but needed to keep the coherence of the object  graph