2017-02-03 3 views
14

Ich habe die folgende Struktur:Java CDI: Decorator mit mehreren Generika params

@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) { ... } 

} 

Dies ist die EntityService Interface-Deklaration:

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

} 

Leider ist der Dekorateur speichern Methode nie aufgerufen werden, wenn es sein sollte , obwohl keine Fehler angezeigt werden ... Der einzige Weg, wie ich es funktionierte, war wie folgt:

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

Ohne den Q extends QueryParams generischen Parameter.

Die MyDecorator ist innerhalb beans.xml deklariert.

<?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> 

Irgendwelche Hinweise?

+0

Möglicherweise müssen Sie noch mehr Informationen bereitstellen. Ich habe versucht, einen kurzen Ausschnitt mit dem oben genannten zu machen, und es funktionierte einfach für mich (mit Weld, von dem ich vermute, dass Sie es auch verwenden). Auch in Ihrer Frage sprechen Sie von 'EntityService', Sie zeigen jedoch ein Code-Snippet mit 'CrudService'. Ist das ein Tippfehler oder gibt es eine andere generische Klasse dazwischen? – Siliarus

+0

Ein Tippfehler, sorry, nur behoben. Wie auch immer, welche Art von zusätzlichen Informationen kann ich anbieten? –

+1

Können Sie Ihre beans.xml-Datei bereitstellen? – hya

Antwort

1

Verwaltet, um das Problem zu lösen. Mein Problem war, dass ich mit QueryParams direkt in den meisten der Endpunkte/Services-Implementierungen, zum Beispiel:

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

In der Tat QueryParams nicht wirklich extends QueryParams, es ist die Klasse selbst! Deshalb hat die PersonService überhaupt keine MyDecorator ausgelöst!

ist, so habe ich eine Schnittstelle namens IQueryParams und verwendet, dass stattdessen wie folgt aus:

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

Jetzt PersonService Speichermethode funktioniert die MyDecorator auslösen.

0

Sie dies tun ->

EntityService<T extends BaseEntity, Q extends QueryParams> 

Wenn diese Schnittstelle nehmen zwei Objekt, ein T erstreckt BaseEntity, andere Q erstreckt QueryParams, Beziehungsweise können Sie direkt über die spezifischen Arten statt setzen versuchen. Genau wie folgt aus:

an die Schnittstelle (hier das wichtigste ist, so allgemein wie posible zu sein, so, Sie wählen zwei Namen, wie A, B, oder in Ihrem Fall):

public interface EntityService<T, Q> { 

T Save(T param); 

void otherMethod(Q param); 

}

zum Dekorateur (hier an dieser Stelle können Sie die Arten wählen, so dass nicht necesary ist "generic" zu sein):

public abstract class MyDecorator implements EntityService<BaseEntity, QueryParams>{ 

@Any 
@Inject 
@Delegate 
EntityService<BaseEntity, QueryParams> delegate; 
//If I understood well the problem, this just work and solve your problem, 
//or else... I'm sorry, you can give me more data so I could help you 
//a little more 

//Check here, I give a concrete type for T abstract generic type, in 
//your case BaseEntity 
@Override 
public BaseEntity save(BaseEntity entity) { 
    BaseEntity retSomething; //this is ilustrative 
    super.save(entity); //save your entity as you know how. 
    return retSomething; //I really don't know why your save method has a 
         //return statament, but, if you need it, check the 
         //return type 
} 

@Override 
public void otherMethod(QueryParams param) { 
    // Check here, in the interface the name was Q, now here you only 
    // can use as param an QueryParams type object 

} 

}

+0

Hallo Damian, vor allem vielen Dank für Ihre Antwort. Aber was ist mit der '@ Delegate'-Instanz? Es muss den spezifischen Typ, nicht nur den Supertyp kennen, um richtig eingespritzt zu werden. @Damian Lattenero –

+0

Ok, ich werde meine ursprüngliche Antwort ändern, um auch diese Frage zu beantworten. –

+0

Und Entschuldigung, die Antwort ist Ja, die @Delegate Instanz MUSS den konkreten (ist schöner Wort als spezifisch) Typ kennen. Lassen Sie mich wissen, wenn das funktioniert –