Spring: autowiring DAO into a utility class not wo

2019-08-19 02:03发布

问题:

I have an annotation driven spring mvc project templated after the JBoss web mvc sample. (Spring, Hibernate, JPA 2.0)

I have a utility package where I want to put reusable classes for obviously utility functions. Specifically I have a LogonUtilities class where I want to query a database to get information.

I autowire my DAO there but when I debug the DAO is always null and fails with that exception.

I have read and tried many things - I know I've probably come across the solution already - but missed something and moved on and tried something else. I probably am not googling the correct terms since annotations are new to me. (I've worked with spring & hibernate for years - but with xml)

I've added this to my applicationContext.xml

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

which I thought was all I needed to do.

This is what I currently have in my LogonUtility class - but it doesn't work, keywordDao is always null. I think I could probably get it to work if I wired the DAO to a LogonUtility bean in the applicationContext (the old way) but I would think there's a better way to do it with annotations.

@Service    
public class LogonUtilities {

    @Autowired private KeywordDao keywordDao; 

My application isn't brand new, I probably have ten working controllers and over a dozen working DAOs at this point, including a Keyword Controller and DAO that already does CRUD operations, so I don't think my setups with that stuff is incorrect. I just have some code I want to reuse that pulls from a database.

Thanks in advance.

*in my code it's actually called "TrainingKeyword" not "Keyword" This is the nullPointer error because the DAO is null

10:52:07,673 ERROR [io.undertow.request] (default task-1) UT005023: Exception handling request to /Training/Home: java.lang.NullPointerException

    at util.LogonUtilities.trainingOffices(LogonUtilities.java:59) [classes:]
    at filter.LogonFilter.doFilter(LogonFilter.java:100) [classes:]
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) [spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE]

This is the code where the error happens

//Set TrainingOffices
List<TrainingKeyword> kList1 = keywordDao.getAllTrainingKeywordsByName("Level 200 Training Offices");

回答1:

I solved my problem by listening to your ideas and with help from this question. JPA is not Autowiring

Basically I had already tried everything that worked - but never all together. I was constantly making edits to my code trying to get it to work and always had either something missing or something bad. For anyone with a similar question here are the steps

In my LogonFilter I added

 @Autowired private LogonUtilities lu

In my LogonUtilites class I added

@Autowired private TrainingKeywordDao keywordDao;

There was no need to add the LogonUtility bean to my applicationContext - I took it out and it still works.

Thank you to all that helped - your ideas kept making me rethink what I was doing.



回答2:

You are trying to do a @Autowired private KeywordDao keywordDao; but you not getting any autowiring error. but @Autowired is by default @Autowired(required=true) meaning that these dependencies are by default mandatory, and throw an error if not met.

No autowiring error is received, so the conclusion is that it seems that this class is not being scanned for autowiring at all.

If it would then an error would be thrown. Try to see why the class is not being autowired, here are some common causes:

  • the package where the class is placed is not being scanned, is the name of the classes package util or a subpackage?

  • The scanning is being done in the wrong spring context. Most Spring applications have two contexts, one root context and one servlet dispatcher context. Try to move the component scan <context:component-scan base-package="util"/> from one context to the other, by copying this configuration line from one XML file to the other.



回答3:

Make sure that base-package is the fully qualified path of the service from the root on, and make sure that KeywordDao is annotated with @Repository.