2

我想为我的持久实体带来依赖注入,但我不确定如何做到这一点。

我的 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
  }
}
4

1 回答 1

3

持久实体的生命周期通常与托管 bean 的生命周期分离。这就是为什么不鼓励在 JPA 托管实体中使用 DI / CDI 的原因。

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

我认为情况类似于DataNucleus。尤其是这...

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

... 可能非常棘手,因为依赖项在某些星座中代理(阅读:范围),但直接注入到其他星座中。

My guess is that it's much easier if you redesign your model in a way that entities do not rely on DI.

于 2012-07-25T10:55:51.073 回答