@Inject does not work in AttributeConverter

I have a simple implementation AttributeConverterin which I am trying to introduce an object that should provide the conversion logic, but @Injectdoes not seem to work for this case. The converter class is as follows:

@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);
    }
}

When triggered, @Converterit throws NullPointerException, because the property is cryptonot initialized from the container. Why is this?

I use Glassfish 4, and in all other cases it @Injectworks just fine.

Is it impossible to use CDI on converters?

Any help would be appreciated :)


- AttributeConverter. , 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. .

+4
4

, CDI - AttributeConverter, , . @FacesConverter. , CDI , API Apache MyFaces CODI @Advaced :) , ​​:

@Advanced
@FacesConverter("cryptoConverter")
public class CryptoJSFConverter implements Converter
{
    private CryptoController crypto = new CryptoController();

    @Inject
    PatientController ptCtrl;

    public Object getAsObject(FacesContext fc, UIComponent uic, String value) 
    {
        if(value != null)
            return crypto.pg_encrypt(value, ptCtrl.getSecretKey());
        else
            return null;
     }


    public String getAsString(FacesContext fc, UIComponent uic, Object object) 
    {
        String res = crypto.pg_decrypt((byte[]) object, ptCtrl.getSecretKey());
        return res;
    }   
}

bean @Named . faces-config.xml ! :

@Named
@SessionScoped
public class PatientController extends PersistanceManager
{
   ...
}

. , /.

, , @FacesValidator, CODI CDI ( ).

0

, CDI beans JPA-, CDI 1.1 Crypto:

Crypto crypto  = javax.enterprise.inject.spi.CDI.current().select(Crypto.class).get()
+4

, CDI JPA Stuff . ( , , ) , :

/**
 * @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);
    }
}

This way you will create a Singleton EJB that is created when the container loads, setting the attribute of the static class at the PostConstruct stage. Then you simply use the static repository instead of the input field (which will still remain NULL when used as a JPA converter).

+1
source

For reference, JPA 2.2 will allow you to use CDI with AttributeConverter, and some vendors already support this (EclipseLink, DataNucleus JPA are the ones that I know that do this).

+1
source

Source: https://habr.com/ru/post/1598966/


All Articles