我正在使用 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);
}
答案 0 :(得分:1)
我不确定为什么你会期望它能够工作:你试图保存一个新的Feeder实例,它与新创建的Port没有任何关系。
通过将Cascade添加到@OneToMany
并调用save(feeder)
Eclipse链接,如果存在关联:
正如我已经注意到的,这个新的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环境中看到的问题类型。
为了确保内存数据模型的正确性,您应该封装设置/添加操作。