I work in Wildfly 8.2.1 Final which runs Weld 2.2.6 Final.
Given
@Entity
public class Fruit{ ... }
@Entity
public class Apple extends Fruit{ ... }
public interface Repository<T extends Identifiable> { ... }
public interface Identifiable { String getId(); }
and
@ApplicationScoped
public class FruitCDIDelegateRepository implements Repository<Fruit>, SearchableRepository<Fruit> { @EJB private FruitRepository repo; }
@Stateless
@LocalBean
@Typed(FruitRepository.class)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class FruitRepository extends PersistenceRepository<Fruit> implements SearchableRepository<Fruit, FruitCriteria> {
The last two Repositories are a construct straight out of the book Continous Enterprise Development in Java by Andrew Lee Rubinger and Aslak Knidsen. It is a workaround to help EJB and CDI work together. In the book they write
This EJB is @Typed to a specific type to avoid being picked up by CDI under Repository due to limitations/error in the CDI EJB interactions. A EJB Beans is always resolved as Repository, which means two EJBs that implements the Repository interface both respond to the InjectionPoint @Inject Repository and making the InjectionPoint ambiguous.
As a WorkAround we wrap the EJB that has Transactional properties in CDI bean that can be used by the Type system. The EJB is to be considered a internal implementation detail. The CDI Type provided by the ConferenceCDIDelegateRepository is the real Repository api.
Other classes should be negligible in this context.
Should I not be able to declare
@Inject
Repository<Apple> repository;
in a class and obtain a FruitRepository
(CDIDelegate
kind)? A similar case
@Inject
Repository<Fruit> repository;
In the same environment yields the expected object.
You can inject the @Statless Repository without wrapper.
@RequestScoped
public class Service {
@Inject
FruitRepository fruitRepository;
public void saveFruit(Fruit fruit){
fruitRepository.save(fuit);
}
}