Spring appears fully capable of autowiring the correct type based on generic parameters without the need for @Qualifier
s. However, as soon as I tack on a @Transactional
annotation, it can no longer autowire based on generic parameters. Consider this example, invented only for purposes of illustrating the issue:
interface Product {}
interface Book extends Product {}
interface Toy extends Product {}
interface Store<P extends Product> {}
@Component
class BookStore implements Store<Book> {}
@Component
class ToyStore implements Store<Toy> {}
@Component
class BookDealer {
@Autowired
BookDealer(Store<Book> store) {
...
}
void inventoryBooks() {
... doesn't really matter what this does ...
}
}
Note that the above code wires up fine. The BookStore
class is autowired into the BookDealer
constructor without any issue. I can call inventoryBooks()
and it works fine.
However, if I add a @Transactional
annotation to a method upstream from the call to inventoryBooks()
, e.g. on the client method that calls it, the BookDealer
will no longer autowire, and I must resort to either injecting concrete types, or using a @Qualifier
. The error is that there are two matching beans for the constructor argument of BookDealer
, meaning both the BookStore
and the ToyStore
and Spring can't decide which one is needed. That tells me that Spring can no longer detect the generic types now that some upstream method has been proxied for the @Transactional
. Something like that anyway...
I would like to stick to interfaces and not use @Qualifier
s. Is there a way to do this with @Transactional
, or is it a known limitation of generics and autowiring and things like @Transactional
?