0

I'm just starting out with Spring Data and I'm trying to add a custom method to my repositories which requires another bean (which is preferably only created once (i.e. singleton))

The bean is declared in the root-context.xml like so

<bean class="org...CachedQueryTemplateFactory" /> 

With the proper namespace of course. I then try to inject this bean into a CustomRepositoryImpl using @Autowired

@Getter
@Setter
@Component
public class StudyRepositoryImpl implements StudyRepositoryCustom {
    @PersistenceContext private EntityManager d_em;
    @Autowired private QueryTemplateFactory queryTemplateFactory;

    @Override
    public List<Study> findStudies(
            UUID indication,
            List<UUID> variables,
            List<UUID> treatments) {
        QueryTemplate template = this.queryTemplateFactory.buildQueryTemplate("...");
        ...
    }
}

However when running the code I get NullPointerException. When doing the wiring in a @Controller and then passing the reference to the repository it works, but I don't want to DI to happen in the controller. So why is the QueryTemplateFactory null in the StudyRepositoryImpl but not for the @Controller and how can I fix this?

Full code is available on GitHub https://github.com/joelkuiper/trialverse/tree/feature/injectQueryTemplate

Thanks in advance!

JoelKuiper
  • 4,362
  • 2
  • 22
  • 33
  • The only time I've experienced something like this was when my calling class bean isn't managed by Spring. Make sure that you have `` in your config – NeilA Apr 22 '13 at 11:31
  • @NeilA it is actually, I even tried using the component annotation instead of the XML bean config (I'm using the annotation driven spring-mvc) but no avail – JoelKuiper Apr 22 '13 at 11:36
  • Try to put `@Qualifier("CachedQueryTemplateFactory")` on with you `@Autowired` declaration. Spring automatically search for beans that ends with "Impl". Also, I think that your implementation on CachedQueryTemplateFactory must be a `@Service` – Deividi Cavarzan Apr 22 '13 at 12:42
  • Tried that ... still gives me null's. My guess is that the Spring Data JPA messes up the DI somehow, so I guess the best thing I can do is the DI in the calling object, in this case the controller. – JoelKuiper Apr 22 '13 at 13:08

1 Answers1

2

You probably just need to add either :

<context:component-scan base-package="packagewithservices"/>

OR

<context:annotation-config/>

Either of these register a AutowiredAnnotationBeanPostProcessor responsible for wiring in the @Autowired fields. The javadoc that I have linked to has more details.

Biju Kunjummen
  • 49,138
  • 14
  • 112
  • 125
  • Not sure if the OR is exclusive. Anyway both are present, and failing to do so would result in a "No matching bean of type [...] found for dependency..." during boot rather than a NullPointerException during Runtime. Even if not it wouldn't explain why it does work for the controller (same code, different place). – JoelKuiper Apr 22 '13 at 14:18
  • Are you sure it is present, I don't see either of them in your root-context.xml file - https://github.com/joelkuiper/trialverse/blob/feature/injectQueryTemplate/src/main/webapp/WEB-INF/spring/root-context.xml – Biju Kunjummen Apr 22 '13 at 18:00
  • It's in the servlet-context https://github.com/joelkuiper/trialverse/blob/feature/injectQueryTemplate/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml – JoelKuiper Apr 22 '13 at 18:45
  • That alone will not work @JoelKuiper, thing is there are two different application contexts at work here - the root context(holding the services, datasource etc), and the web context(loaded through DispatcherServlet) holding the controllers. For the autowiring to happen in each of these context, you will have to have the `context:...` in both contexts. – Biju Kunjummen Apr 22 '13 at 18:52
  • Ah yes. I'm fairly sure I tried that too so the code on Github might be slightly outdated. I'm kinda surprised that it won't throw a "No qualifiying bean of type.." exception of sorts though. I'll try that! – JoelKuiper Apr 22 '13 at 20:46
  • Ah I added to the rootcontext and it worked. Thanks :D ... I feel rather stupid now! Might be time to read up on the Spring source or something – JoelKuiper Apr 22 '13 at 21:09
  • This is really a good answer!! – Krishna Apr 23 '13 at 11:20