【问题标题】:Cascading not working in oneToMany, with eclipseLink使用 eclipseLink 级联在 oneToMany 中不起作用
【发布时间】:2016-02-08 16:03:59
【问题描述】:

我正在使用 EclipseLinkJPA 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 表使用外键引用 feeder 表。

编辑

这段简单的代码很适合我:

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

【问题讨论】:

  • 是的,您错过了这样一个事实,即 Feeder 在保存之前对这个新的 Port.Call feeder.getPortCollection().add(p) 一无所知,它会起作用。我还建议按照此处概述的方式封装这些操作。 stackoverflow.com/questions/19840832/…
  • 但是feeder还没管理好!
  • 对不起,我不明白。我给出的答案是正确的。
  • 它给了我一个空指针异常,我认为这很正常,因为 feeder 还没有 portCollection,可能是这样吗?
  • 如果由于某种奇怪的原因你不能初始化一个新的集合(我可以保证这不会从 JPA 的角度破坏任何东西)那么你唯一的选择是在 @ManyToOne 上添加一个级联并调用 save(端口),因为新端口知道它的馈线(但反之亦然)。

标签: mysql jpa eclipselink


【解决方案1】:

我不确定您为什么希望它能够工作:您正在尝试保存一个与新创建的端口没有任何连接的 Feeder 的新实例。

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

  1. 插入 Feeder 的记录。
  2. 迭代 Port 集合并插入相关记录。

然而,正如我所指出的,这个新的 Feeder 实例没有与之关联的端口。

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

鉴于此,如果将必要的级联选项添加到关系的 @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 环境中遇到的问题类型。

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

【讨论】:

  • 很遗憾你浪费了我很多时间!
  • 也许你可以详细说明。提供的答案是正确的。抱歉,我浪费时间试图提供帮助。
  • 我测试了很多次,还是不行。怎么可能 feeder == null 然后你调用 feeder.removePort(port)!
  • 最初的问题是关于为什么没有保存您的关联。对此进行了明确的解释和回答。其余部分是关于如何封装这些操作的粗略大纲。如果那部分有任何拼写错误,那么它就是基本的 Java,我也看不到任何 Java 开发人员怎么会浪费超过 30 秒的时间来修复这些错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-21
  • 2018-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
相关资源
最近更新 更多