【问题标题】:JPA, do not want insertable=false, updatable=false, workaround?JPA,不想要 insertable=false,updatable=false,解决方法?
【发布时间】:2013-04-10 04:12:54
【问题描述】:

我是 stackoverflow 和 JPA 的新手,所以我会尽力解释这一点。

在一个实体中,我想通过给出 int 值来设置外键,但我也想通过给出一个对象来设置它。这里有一些代码可以更好地解释它。

@Entity  
public class Thread implements Serializable {

  @ManyToOne  
  @JoinColumn(name = "accountId", referencedColumnName = "id", nullable = false)
  public Account getAccount() {
      return account;
  }

  @Column(name = "accountId")  
  @Basic
  public int getAccountId() {
      return accountId;
  }  
}

我尝试了几种方法,但上面的代码是我想要实现的最佳示例。我知道在这两种方法中的任何一种中设置 insert = false 和 update = false 都会使这段代码在编译和运行时都能正常工作。但我希望能够通过使用 Account 对象和设置实际的 int accountId 来插入 accountId。

这是因为有时,在我的服务器中,我只有 accountId,有时我有 Account 对象。

我也明白最好的解决方案可能是在创建线程和设置 accountId 时使用 account.getId()。但是在我的服务器中能够只使用该对象在逻辑上会很好。

提前致谢!

【问题讨论】:

  • 我只会使用对象而忘记使用 ID。如果您尝试超优化您的应用程序,请使用会话缓存并尝试em.getReference() 以防止数据库命中。

标签: java jpa foreign-keys entity hibernate-onetomany


【解决方案1】:

我认为您在应用程序中遇到了概念问题。在使用 JPA 时,您应该坚持设置实体并且不要使用任何外键值。问题的原因是您的应用程序仅在某个时候提供了 accountId。

这可能是由于不同的原因。如果这是因为仅提供 accountId 的应用程序部分是遗留的,那么我认为拥有一个将 accountId 转换为 Account 实体然后设置该实体的适配器非常好。也不是适配器可以创建 JPA 代理,因此此时不需要实际的数据库访问。我能想到的另一个原因是应用程序在处理过程中的某个时间点丢失了信息。当应用程序在某个地方使用帐户并且仅将其 ID 移交给相关代码时,可能会出现这种情况。然后应该重构这样的代码以移交实体。

在您的特定情况下,您还可以同时使用帐户作为实体和外键作为属性,既可插入又可更新。您只需确保 accountId 属性值与指向由帐户实体表示的行的外键一致。 JPA 提供者应该能够处理这个问题(例如,我知道 OpenJPA 可以)。但是,您对此有点限制。例如,您只能读取 accountId 属性值,因为将其设置为不同的值会导致帐户实体值不一致。

【讨论】:

  • 感谢您的回复!在我研究了更多并记住了您的答案后,我意识到我可以使用 getReference() 来获取代理。不幸的是,我偶然发现了延迟加载的新问题,这似乎不像我理解的那样起作用。我已经发布了 2 个不同的问题,我尝试以 2 种不同的方式来解决这个问题。如果您也想查看它们,这里是链接。 stackoverflow.com/questions/16266256/…stackoverflow.com/questions/16294572/…
猜你喜欢
  • 2011-04-17
  • 1970-01-01
  • 2011-06-17
  • 2020-03-18
  • 2016-03-28
  • 1970-01-01
  • 1970-01-01
  • 2019-04-16
  • 1970-01-01
相关资源
最近更新 更多