Houssem Bdr February 2016

Cascading not working in oneToMany, with eclipseLink

I am working with EclipseLink and JPA 2.0.

Those are my 2 entities:

Feeder entity:

@Entity
@Table(name = "t_feeder")
public class Feeder implements Serializable {
private static final long serialVersionUID = 1L;
//Staff
@OneToMany(cascade = CascadeType.ALL, mappedBy = "idAttachedFeederFk")
private Collection<Port> portCollection;
//staff
}

Port entity:

@Entity
@Table(name = "t_port")
public class Port implements Serializable {
//staff
@JoinColumn(name = "id_attached_feeder_fk", referencedColumnName = "id")
@ManyToOne
private Feeder idAttachedFeederFk;
//staff
}

And this is my code:

Feeder f = new Feeder();
//staff
Port p = new Port();
p.setFeeder(f);

save(feeder); //This is the function that calls finally persist.

The probleme is that, only feeder is persisted and not the port. Am I missing something? And specially, in which side should I mention the cascading exactly. Given that in my database, the port table is referencing the feeder one with a foreign key.

EDIT

This simple piece of code worked fine with me:

public static void main(String[] args) {
    Address a1 = new Address();
    a1.setAddress("madinah 0");

    Employee e1 = new Employee();
    e1.setName("houssem 0");
    e1.setAddressFk(a1);

    saveEmplyee(e1);
}

Answers


Alan Hay February 2016

I am not sure why you would expect it to work: you are attempting to save a new instance of Feeder which has no connection whatsoever to the newly created Port.

By adding the Cascade to the @OneToMany and calling save(feeder) Eclipse link would if there were an association:

  1. Insert the record for the Feeder.
  2. Iterate the Port collection and insert the relevant records.

As I have noted however, this new Feeder instance has no Ports associated with it.

With regard to your simple example I assume when you say it works that both the new Address and Employee have been written to the database. This is expected because you have told the Employee about the Address (e1.setAddressFk(a1);) and saved the Employee. Given the presence of the relevant Cascade option then both entities should be written to the database as expected.

Given this it should then be obvious that calling save(port) would work if the necessary cascade option was added to the @ManyToOne side of the relationship.

However if you want to call save(feeder) then you need to fix the data model. Essentially you should always ensure that any in-memory data model is correct at any given point in time, viz. if the first condition below is true then it follows that the second condition must be true.

Port p = new Port();
Feeder feeder = new Feeder();
p.setFeeder(f();

if(p.getFeeder().equals(f){
   //true
}

if(f.isAssociatedWithPort(p)){
   //bad --> returns false
}

This is obviously best practice anyway but ensuring the correctnes of your in-memory model should mean you do not experience the type of issue you are seeing in a JPA environment.

To ensure the correctness of the in-memory data model you should encapsulate the set/add operations.

public class Port{

    private Feeder feeder;

    p 

Post Status

Asked in February 2016
Viewed 2,718 times
Voted 8
Answered 1 times

Search




Leave an answer