你能在持久化实体中使用依赖注入吗?

时间:2012-07-24 19:52:13

标签: dependency-injection guice cdi datanucleus

我想将依赖注入带到我的持久化实体,但我不确定它是如何完成的。

我的GWT应用程序中的盐渍哈希算法需要Base64实现。 GWT附带旧版commons-codec。由于名称冲突 - 我不使用Maven - 我可以弄清楚如何使用旧的或使用其他实现,如Base64.iharder.net。

在调整了几个备选方案之后,我为每个备选方案创建了一个接口和适配器类。我注入了一个实现。这似乎是一个典型的用例。

创建持久性实体时,一切都运行良好。但是,在存储和检索它们之后,先前注入但未持久化的字段将使用空值进行实例化。

这个问题很有道理。我使用DataNucleus,它添加​​了一个无参数的构造函数。 DataNucleus不会再次注入依赖项。

在从数据存储中检索对象时,如何让我的持久性框架重新注入依赖项?

谢谢。

// salted hash for password storage

@PersistenceCapable
public class SaltedHash implements Serializable {

  private static final long serialVersionUID = 1L;

  private String salt;
  private String hash;

  @NotPersistent
  private final Base64Codec base64Codec;
  @NotPersistent
  private final Sha265Hash sha256Hash;
  @NotPersistent
  private final Random random;

  @Inject
  public SaltedHash(Base64Codec b64, Sha256Hash sha256, Random rnd) {
    base64Codec = b64;
    sha256Hash = sha256;
    random = rnd;
  }

  public void setSecret(String secret) {
    salt = base64Codec.encode(generateSalt());
    hash = base64Codec.encode(sha256Hash.hash(salt + secret));
  }

  public boolean matches(String secret) {
    String maybe = base64Codec.encode(sha256Hash.hash(salt + secret));
    return hash.equals(maybe);
  }

  private byte[] generateSalt() {
    // use random to generate a salt
  }
}

1 个答案:

答案 0 :(得分:3)

持久化实体的生命周期通常与托管bean的生命周期分离。这就是为什么在JPA管理实体中使用DI / CDI是相当沮丧的。

  

根据此定义,JPA实体在技术上受到管理   豆子。但是,实体有自己特殊的生命周期,状态和   身份模型通常由JPA实例化或使用new。   因此,我们不建议直接注入实体类。我们   特别建议不要指定@Dependent以外的范围   到实体类,因为JPA无法持续注入CDI   代理。

我认为情况类似于DataNucleus。特别是这......

  

如何让我的持久性框架重新注入依赖项   从数据存储中检索对象时?

...可能非常棘手,因为依赖关系代表某些星座(读取:范围),但直接注入其他星座。

我的猜测是,如果您以实体不依赖DI的方式重新设计模型,那么会更容易