Question

I Have a relation OneToMany : 1 Work have N Steps And I want to update the work's list step.

Add new element works, but when I want to update or delete element it not seems to.

  1. update : do not update the right element
  2. delete : do not delete the relation (for the element that was removed)

Here my entities : (I have not defined equals and hascode methods)

WORK :

@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 <>();

STEPS :

@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;

In my Database I have :

Work - [ID : 01 - ID_WORK : 01 - LABEL : stepOne]

Steps : - [ID : 01 - ID_WORK : 01 - LABEL : stepOne] - [ID : 02 - ID_WORK : 02 - LABEL : stepTwo]

Test : get the entity and add element to step collection. When I do :

// 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);

That's work : Steps :

  • [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 : add + update

// 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);

AND I HAVE : Steps :

  • [ID : 01 - ID_WORK : 01 - LABEL : I changed !] // instead to be deleted
  • [ID : 02 - ID_WORK : 02 - LABEL : stepTwo] // intead to be changed ...
  • [ID : 03 - ID_WORK : 03 - LABEL : stepThree]
  • [ID : 04 - ID_WORK : 04 - LABEL : stepTwo]

AND I EXPECTED :

  • [ID : 01 - ID_WORK : NULL - LABEL : stepOne] // relationship deleted.
  • [ID : 02 - ID_WORK : 02 - LABEL : I changed !] // entity updated
  • [ID : 03 - ID_WORK : 03 - LABEL : stepThree]
  • [ID : 04 - ID_WORK : 04 - LABEL : stepTwo]

Thanks,

No correct solution

OTHER TIPS

It seems you're not really understanding that Java works with references. You don't need to get the collection of steps from the entity, construct a copy, add elements to the copy and set the collection of the entity to this copy. All you need to do is add an element to the collection of steps of the entity:

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

You also assume that the entities will always be in the collection in the same order (step1, then step2). That's not the case. First of all because a Set doesn't have any order. Second because, even with a List, if you don't sort the list, or order it using an OrderColumn, the list is in fact a bag, where the order of the elements is arbitrary.

That said. The main problem is, once again, that you're modifying only the inverse side of the association, without modifying the owner side. The owner side is Step.work. That's what you need to modify to set/remove the association. So, to add a new step:

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

To update the label of a step:

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

To disconnect a step from its work:

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top