Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java CDI: Decorator with multiple generic params

I have the following structure:

@Decorator
public abstract class MyDecorator<T extends BaseEntity, Q extends QueryParams> implements EntityService<T, Q> {

    @Any
    @Inject
    @Delegate
    EntityService<T, Q> delegate;

    @Override
    public T save(T entity) { ... }

} 

This is the EntityService interface declaration:

public interface EntityService<T extends BaseEntity, Q extends QueryParams> {

    T save(T entity);

    void deleteById(Integer id);

    void deleteAllById(List<Integer> ids);

    void delete(T entity);

    void deleteAll(List<T> entities);

    T findById(Integer id);

    QueryResultWrapper<T> query(Q parameters);

    Long count(Q parameters);

}

Unfortunately, the decorator save method never get called when it should, although no errors are shown ... The only way I got it working was like this:

@Decorator
public abstract class MyDecorator<T extends BaseEntity> implements EntityService<T> { ... }

Without the Q extends QueryParams generic param.

The MyDecorator is declared inside beans.xml.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
   bean-discovery-mode="all" version="1.1">

    <decorators>
        <class>fortuna.backend.comum.decorators.MyDecorator</class>
    </decorators>

</beans>

Any clues?

like image 442
Marcos J.C Kichel Avatar asked Feb 03 '17 18:02

Marcos J.C Kichel


People also ask

Can a generic class have multiple generic parameters Java?

Yes - it's possible (though not with your method signature) and yes, with your signature the types must be the same.

Can a generic class have multiple generic parameters?

A Generic class can have muliple type parameters.


1 Answers

Managed to solve the issue. My problem was that I was using QueryParams directly in most of the endpoints/services implementations, for instance:

public class PersonService extends EntityService<Person, QueryParams> { ... }

In fact, QueryParams don't actually extends QueryParams, it is the class itself! That's why the PersonService wasn't triggering MyDecorator at all!

Being so I created an interface called IQueryParams and used that instead, like that:

public abstract class MyDecorator<T extends BaseEntity, Q extends IQueryParams> implements EntityService<T, Q> {

Now PersonService save method does trigger the MyDecorator.

like image 89
Marcos J.C Kichel Avatar answered Oct 07 '22 14:10

Marcos J.C Kichel