使用eclipseLink级联不能在oneToMany中工作

时间:2016-02-08 16:03:59

标签: mysql jpa eclipselink

我正在使用 EclipseLink JPA 2.0

这是我的两个实体:

馈线实体:

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

港口实体:

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

这是我的代码:

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

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

问题是,只有馈线是持久的而不是端口。我错过了什么吗?特别是,我应该在哪一方提到级联。鉴于在我的数据库中, port 表引用带有外键的馈送器

修改

这段简单的代码对我很好:

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

1 个答案:

答案 0 :(得分:1)

我不确定为什么你会期望它能够工作:你试图保存一个新的Feeder实例,它与新创建的Port没有任何关系。

通过将Cascade添加到@OneToMany并调用save(feeder) Eclipse链接,如果存在关联:

  1. 插入Feedder的记录。
  2. 迭代端口集合并插入相关记录。
  3. 正如我已经注意到的,这个新的Feeder实例没有与之关联的端口。

    关于你的简单示例,我假设当你说它工作时,新的Address和Employee都已写入数据库。这是预期的,因为您已告知员工有关地址(e1.setAddressFk(a1);)并保存了员工。鉴于存在相关的Cascade选项,则应按预期将两个实体写入数据库。

    鉴于此,如果必要的级联选项被添加到关系的save(port)侧,那么调用@ManyToOne将会很明显。

    但是,如果要调用save(feeder),则需要修复数据模型。基本上你应该始终确保任何内存数据模型在任何给定的时间点都是正确的,即。如果下面的第一个条件为真,那么第二个条件必须为真。

    Port p = new Port();
    Feeder feeder = new Feeder();
    p.setFeeder(f();
    
    if(p.getFeeder().equals(f){
       //true
    }
    
    if(f.isAssociatedWithPort(p)){
       //bad --> returns false
    }
    

    这显然是最佳做法,但确保内存模型的正确性意味着您不会遇到在JPA环境中看到的问题类型。

    为了确保内存数据模型的正确性,您应该封装设置/添加操作。