-1

I've created a utilities class that will house some functionality that doesn't belong in standard controllers, such as syncing and ingesting API data. I have a very simple Repository class that extends CrudRepository:

//TransactionCategoryRepository.java
@Repository
public interface TransactionCategoryRepository extends CrudRepository<TransactionCategory, Integer> {
}

Then I have a service class which is also very straightforward at the moment:

//TransactionCategoryService.java
@Service
public class TransactionCategoryService {

    private TransactionCategoryRepository transactionCategoryRepository;

    @Autowired
    public TransactionCategoryService(TransactionCategoryRepository repository) {
        this.transactionCategoryRepository = repository;
    }

    public void saveTransactionCategory(TransactionCategory transactionCategory) {
        transactionCategoryRepository.save(transactionCategory);
    }

My utilities class leverages the TransactionCategoryService and I've attempted to include it with @Autowired:

//Utilities.java
@Controller
public class PlaidUtilities {

    private Logger logger = LoggerFactory.getLogger(PlaidUtilities.class.getSimpleName());

    private PlaidClient mPlaidClient;

    @Autowired
    TransactionCategoryService mTransactionCategoryService;

    @Autowired
    TransactionRepository mTransactionCategoryRepository;
....

When I use mTransactionCategoryService to save a new entity, I get the null pointer exception. IntelliJ previously threw warnings on my @Autowired annotations that the member classes needed to be declared in spring beans. Adding the @Controller annotation made these go away, though I'm not sure if that is the right thing to do; I tried this because this is the only difference between this class and another class which @Autowires in exactly the same way but does not have this problem.

The other classes that use Autowired in this way are in a package called controllers which is in the root directory. This Utilities class is in a package called util which is also in the root directory.

What have I done wrong in this setup/configuration?

justinraczak
  • 776
  • 2
  • 9
  • 24
  • And `@Autowired` field cannot be `null`. If an `@Autowired` dependency cannot be resolved at startup your application will blow up on startup. So my guess is that you are actually creating a new instance of the service in the controller and use that instead of the auto wired one (or reassigning the field in a different way overriding the auto wired dependency). – M. Deinum Jan 15 '18 at 21:19
  • how does you application config class look like? – Alex P. Jan 15 '18 at 23:31
  • @M.Deinum Thank you for your comment. I'm new to Spring and so don't understand how this relates to my problem. I did read the question you marked this a duplicate of, but the answer's implementation is how I've implemented. I apologize if I'm missing something obvious, but I don't see what I'm supposed to change based on your comment or that answer. However, I experimented with moving the method into a different related controller and the error stopped. Good that it works, not good that I still don't understand why it wasn't working to begin with. – justinraczak Jan 17 '18 at 17:24
  • @AlexP. I don't have anything in an application config class. I do have one bean config class that I use for setting up data source, session factory, and hibernate, but I don't think any of that is relevant to that issue. I can post if it's helpful, just let me know. – justinraczak Jan 17 '18 at 17:26
  • @justinraczak yeah I mean that one. It is actually important. It would be helpfull if you update your question. Please also add the packages of the classes so we can tell in which package each class is in – Alex P. Jan 17 '18 at 18:05
  • As I stated an `@Autowired` field simply cannot be `null` your application wouldn't even start if a dependency doesn't resolve. Hence you are creating new instances of classes yourself instead of using the spring managed instances. Which is also what the answer to the duplicated question is telling you, – M. Deinum Jan 17 '18 at 19:11
  • It could be either what @M.Deinum said or your `@ComponentScan` in your java config is not scanning the correct package(s). – Alex P. Jan 18 '18 at 08:16
  • If that would be the case the application wouldn't start due to not being able to auto wire the dependencies. – M. Deinum Jan 18 '18 at 14:13

1 Answers1

-2

You forget to autowire the repository in your service layer.

//TransactionCategoryService.java
@Service
public class TransactionCategoryService {
    @Autowired //MISSING THIS
    private TransactionCategoryRepository transactionCategoryRepository;

    @Autowired
    public TransactionCategoryService(TransactionCategoryRepository repository) {
        this.transactionCategoryRepository = repository;
    }

    public void saveTransactionCategory(TransactionCategory transactionCategory) {
        transactionCategoryRepository.save(transactionCategory);
    }
Mike Tung
  • 4,735
  • 1
  • 17
  • 24
  • 1
    He has `@Autowired` on the constructor and assigns the field. Also in Spring 4.3 and up you don't need `@Autowired` on a constructor anymore in the case of a single constructor, Spring will automatically use the available constructors. – M. Deinum Jan 15 '18 at 21:18