【问题标题】:Loading from one persistance unit and persisting in another从一个持久性单元加载并在另一个持久性单元中持久化
【发布时间】:2011-02-10 10:08:49
【问题描述】:

我遇到了 Hibernate/JPA 的问题,当幕后的魔力让生活变得困难时。我想做的事情非常琐碎,所以应该有解决方案,但我就是找不到。

所以我想从一个持久性单元(数据库)加载一些表并将它们存储到另一个持久性单元(另一个数据库)中。这里没有什么好笑的,只是加载并坚持。

在我的第一次尝试中,我使用 persist 将分离的实体存储在一个新的持久性单元中。它没有用,因为他们已经有了标识符,所以我不得不尝试别的东西。

所以我的第二次尝试是使用 merge 但这导致 Hibernate 为每个实体额外执行一个(至少)select。使用 merge 导致这非常慢,最终对我们不可用。

所以对于我的问题,是否有在不使用 merge 的情况下在新的持久性单元中持久化分离的实体?我已经知道这些表是空的,所以我不需要休眠来帮我检查它......

【问题讨论】:

  • 我想我想在这里做的是使分离的实体瞬态,因此它们可以被持久化而不是合并。有没有人可以做到这一点? Hibernate 如何检测实体是否分离(是否设置了标识符)?如果可能的话,我想保留标识符。
  • 我在 Hibernate 文档“在两个不同的数据存储之间复制对象”中找到了以下部分,因此应该可以使用普通的 Hibernate。但是我仍然没有找到使用 JPA 的方法。

标签: hibernate jboss jpa-2.0 java-ee-6


【解决方案1】:

这应该可行。

Entity e = em1.load(id);
em1.detach(e);
e.setId(0); // or null
em2.persist(e);

当然,您必须让 setId 对这段代码可见。

如果您尝试为所有内容实现复制,那么在实际数据库中执行此操作可能是一个更好的主意(即使用您的 DBMS 具有的任何集群功能)。

编辑:

另一种选择是为您的实体实现(深)复制构造函数。

Entity e1 = em1.load(id);
Entity e2 = new Entity(e1);
em2.persist(e2);

【讨论】:

  • 如果这确实有效,并且您使用的是版本列,那么您可能也希望将其设为空。
  • 重要的是实体被 Hibernate 视为 transient。我知道标识符参与其中,可能是由于历史原因,但它不能是唯一的。如果仅通过标识符将实体视为transient,则不可能持久化实体非生成的标识符(事实并非如此)。那么transient状态必须有一个更复杂的定义吗?
  • 我还可以补充一点,我尝试将 persist 与分离的实体一起使用(通过删除 generate-id 注释)。所有实体都被持久化,但连接没有(所有 FK 为空)...
  • @Peter Eriksson - 您可能也必须分离所有孩子。我仍然建议使用适当的复制系统,而不是试图以这种方式欺骗 Hibernate。
猜你喜欢
  • 1970-01-01
  • 2013-02-15
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 2013-08-18
  • 2011-05-25
  • 1970-01-01
相关资源
最近更新 更多