【问题标题】:JPA @ManyToMany relationship saved on only one side when database is reloaded重新加载数据库时,JPA @ManyToMany 关系仅保存在一侧
【发布时间】:2013-11-01 17:35:02
【问题描述】:

我将 JPA 用于带有 EclipseLink 和 Apache Derby 的应用程序。我在@ManyToMany 关系中有两个实体:

@Entity
class HIT<TaskType> {
   ...
   @ManyToMany(targetEntity=Task.class, mappedBy="hits")
   protected List<TaskType> tasks = Lists.newArrayList();
}

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
abstract class Task {
    ...
    @ManyToMany(targetEntity=HIT.class)
    protected List<HIT<?>> hits = Lists.newArrayList();
}

我首先创建实体EventPresenceTask 的两个任务,Task 的子类,并将它们持久化。稍后,我查询 EntityManager 以恢复这些任务并使用它们创建EventPresenceHIT 的实例,HIT 的子类型。创建 HIT 后,它将两个任务添加到其 tasks 列表中,并将自身添加到每个任务的 hits 列表中。然后它被持久化。

创建对象后,我首先在EntityManager 中查询所有HITs 并打印它们,然后在EntityManager 中查询所有Tasks 并打印它们来检查所有内容。我明白了:

EventPresenceHIT{...  #tasks=2}
EventPresenceTask{... # hits=1}
EventPresenceTask{... # hits=1}

正如预期的那样。但是如果我关闭应用程序并重新加载数据库,我会得到:

EventPresenceHIT{... #tasks=0}
EventPresenceTask{... #hits=1}
EventPresenceTask{... #hits=1}

由于在程序的初始运行中对EntityManager 的新查询中一切似乎都是正确的,我担心EntityManger 没有刷新到数据库中(因为程序被 Ctrl-C 终止),所以我将entityManager.close() 放在关闭挂钩中以更加安全,但它没有帮助。

更新:为了明确被持久化和相关的是HITTask 的子类实例,它们本身就是实体。

【问题讨论】:

  • 为什么你有@ManyToMany(targetEntity=BBNHIT.class) 而不仅仅是@ManyToMany@ManyToMany(targetEntity=HIT.class)
  • @JBNizet:对不起,这是一个错字。它应该只是HIT.class。我已经更新了这个问题。如果我删除 targetEntity 属性,数据库创建将在 EclipseLink 代码中以 NullPointerException 崩溃。我认为这可能是因为HIT 是一个泛型类,但我不确定。
  • 打开 eclipselink 日志记录以查看访问任务集合wiki.eclipse.org/EclipseLink/Examples/JPA/Logging时用于读取 HIT 和关联任务的 SQL

标签: java jpa eclipselink derby


【解决方案1】:

愚蠢的错误 - 我忘记在 HIT 类上注释继承策略。在我这样做之后,数据库创建因异常而崩溃。但是,为这两个类切换到 JOINED 继承策略是可行的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    相关资源
    最近更新 更多