我正在使用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.
问题是,只保留馈线而不是端口。我错过了什么吗?特别是,我应该在哪一边提到级联。鉴于在我的数据库中,端口表引用带有外键的馈线表。
编辑
这段简单的代码对我来说很好用:
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);
}
我不确定为什么您希望它起作用:您正在尝试保存与新创建的端口没有任何连接的馈线的新实例。
通过将级联添加到@OneToMany
并调用save(feeder)
Eclipse 链接(如果存在关联(:
- 插入进纸器的记录。
- 循环访问端口集合并插入相关记录。
但是,正如我所指出的,这个新的馈线实例没有与之关联的端口。
关于您的简单示例,我假设当您说它有效时,新地址和员工都已写入数据库。这是意料之中的,因为您已告知员工地址 ( e1.setAddressFk(a1);
( 并保存了员工。鉴于存在相关的级联选项,则两个实体都应按预期写入数据库。
鉴于此,很明显,如果将必要的级联选项添加到关系的@ManyToOne
端,则调用save(port)
将起作用。
但是,如果要调用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 环境中看到的问题类型。
为了确保内存中数据模型的正确性,您应该封装设置/添加操作。