当前位置: 首页 > 知识库问答 >
问题:

@Inject在AttributeConverter中不工作

贺轶
2023-03-14

我有一个简单的属性转换实现,在这个实现中,我试图注入一个必须提供转换逻辑的对象,但是@Inject似乎不适合这种情况。转换器类看起来像这样:

@Converter(autoApply=false)
public class String2ByteArrayConverter implements AttributeConverter<String, byte[]>
{
    @Inject
    private Crypto crypto;

    @Override
    public byte[] convertToDatabaseColumn(String usrReadable) 
    {
        return crypto.pg_encrypt(usrReadable);
    }

    @Override
    public String convertToEntityAttribute(byte[] dbType)
    {
        return crypto.pg_decrypt(dbType);
    }
}

@Conver被触发时,它会抛出一个NullPointerExctive,因为属性crypto没有从容器中初始化。为什么?

我使用的是Glassfish 4,在所有其他情况下,@Inject都可以正常工作。

不可能在转换器上使用CDI吗?

任何帮助都将不胜感激:)

我的问题的重点更多的是属性转换部分。我明白要让CDI工作,bean必须满足这里描述的条件http://docs.oracle.com/javaee/6/tutorial/doc/gjfzi.html.我还试图通过实现以下构造函数来强制CDI工作:

@Inject
public String2ByteArrayConverter(Crypto crypto) 
{
    this.crypto = crypto;
}

现在我得到了以下例外情况,但这并没有给我任何线索:

2015-07-23T01:03:24.835+0200|Severe: Exception during life cycle processing
org.glassfish.deployment.common.DeploymentException: Exception [EclipseLink-28019] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Deployment of PersistenceUnit [PU_VMA] failed. Close all factories for this PersistenceUnit.
Internal Exception: Exception [EclipseLink-7172] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Error encountered when instantiating the class [class model.converter.String2ByteArrayConverter].
Internal Exception: java.lang.InstantiationException: model.converter.String2ByteArrayConverter
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.createDeployFailedPersistenceException(EntityManagerSetupImpl.java:820)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:760)
...

我甚至尝试使用@Producer或@Decorator来让CDI在那个地方工作,但我仍然认为AttributeConverter有一些特定的东西不允许CDI。所以问题还没有解决。

共有3个答案

齐朝明
2023-03-14

你试图把两个不同的世界结合起来,因为CDI不知道JPA的东西,反之亦然。(一个注释解析器当然不知道另一个)你能做的是:

/**
 * @author Jakob Galbavy <code>jg@chex.at</code>
 */
@Converter
@Singleton
@Startup
public class UserConverter implements AttributeConverter<User, Long> {
    @Inject
    private UserRepository userRepository;
    private static UserRepository staticUserRepository;

    @PostConstruct
    public void init() {
        staticUserRepository = this.userRepository;
    }

    @Override
    public Long convertToDatabaseColumn(User attribute) {
        if (null == attribute) {
            return null;
        }
        return attribute.getId();
    }

    @Override
    public User convertToEntityAttribute(Long dbData) {
        if (null == dbData) {
            return null;
        }
        return staticUserRepository.findById(dbData);
    }
}

这样,您将创建一个在容器启动时创建的单例EJB,并在后构造阶段设置静态类属性。然后,只需使用静态存储库而不是注入字段(当用作JPA转换器时,该字段仍然为空)。

胡飞鹏
2023-03-14

作为参考,JPA 2.2将允许CDI与属性转换器一起使用,一些供应商已经支持这一点(我知道有Eclipse Link、DataNcore us JPA这样做)。

姚海
2023-03-14

不幸的是,您不能将CDI bean注入JPA转换器,但是在CDI 1.1中,您可以通过编程方式注入加密:

Crypto crypto  = javax.enterprise.inject.spi.CDI.current().select(Crypto.class).get()
 类似资料:
  • 我对Java EE(依赖项注入)有点陌生,我不明白为什么@inject给我的是null,但是initialcontext.dolookup确实起作用。 这是我的豆子。它只是一把刀。EntityManager的包装器 --jar(PersonData-EJB模块-包含PersonManager) --war(PersonRest-web模块-包含PersonService)

  • 我在尝试用@Inject搭配JAX-RS。我的问题是@Inject只在Servlets中有效。在JAX资源中,我得到一个空指针,我不知道我做错了什么。我的代码如下所示: Pom.xml文件 豆类.xml 网页.xml包含: <代码> 工人阶级: 服务控制器。startTweetListener()和serviceController。stopTweetListener()工作。没有空指针。 非工人

  • 问题内容: 我是AngularJS的新手,我想了解更多有关默认注入的依赖项的信息。在阅读代码时,我注意到有时依赖项是事先明确声明的,有时则不是。例如: 给出与以下结果相同的结果: 这是如何运作的?Angular是否假设要注入的模块的名称与参数中的变量相同? 同样,奇怪的是,如果您确实指定将要注入的依赖项,则必须以 正确的顺序 指定 所有 依赖项,否则将无法正常工作。例如,这是损坏的代码: 有人可以

  • 问题内容: 我对Angular中的注入感到非常困惑。我不知道在哪里使用它以及为什么。是否仅按此处所述与工厂一起使用? 这是工厂的名称。 问题答案: 这是在代码最小化后(如果选择最小化)支持依赖注入的一种方法。 声明控制器时,该函数采用参数: 压缩代码时,您的函数将如下所示: 由于AngularJS使用函数参数名称来推断DI,因此您的代码会中断,因为AngularJS不了解或。 为了解决此问题,他们

  • Inject 是 AMD 和 CJS 依赖管理器,它以一种 Library Agnosti c 的方式来管理你的依赖。主要特性包括: 基于浏览器的 CommonJS 规范 查看更完整的 CommonJS Support Matrix 跨域检索文件的Cross domain retrieval of files (via easyXDM) 本地存储 (一次加载一个模块) 十分简单 快速配置 // S

  • 我试图让ESLint让我使用对象的Rest/传播。尽管我尽了最大努力,我还是得到了这个错误: 当我悬停在椭圆上时(<代码>...)用红色弯弯曲曲。 我的看起来像这样: 我确信prefs正在被阅读,因为规则、插件和样式指南正在按预期工作。 要启用对象rest/spread,是这里的关键(哈哈),它似乎对其他人有用。然而,它拒绝为我工作。我不知所措 更新:我使用的是Visual Studio代码v1.