Spring, @Autowired NullPointerException

0

Cześć! Tworzę aplikację webową za pomocą Springa 5, ale niestety mam problem, bo gdy tworzę obiekt za pomocą IoC, zwraca mi w miejsce tego obiektu null.
AccountDAOImpl

package main.com.java.dao.implementation;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import main.com.java.dao.interfaces.AccountDAO;
import main.com.java.entity.Account;;import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

@Repository
public class AccountDAOImpl implements AccountDAO{

    @Autowired
    private SessionFactory sessionFactory;

    public Session createCurrentSession(SessionFactory sessionFactory){
        Session session = sessionFactory.getCurrentSession();
        return session;

    }

    @Override
    @Transactional
    public List<Account> getAccountList() {     
        Query<Account> theQuery = createCurrentSession(sessionFactory).createQuery("from Account", Account.class);      
        List<Account> accountsList = theQuery.getResultList();

        return accountsList;
    }

    @Override
    public Account getAccountById(int id) {
        try {           
            return createCurrentSession(sessionFactory).get(Account.class, id);     
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    @Override
    public void addAccount(Account theAccount) {
        try {
            Session currentSession = sessionFactory.getCurrentSession();
            currentSession.saveOrUpdate(theAccount);
            currentSession.clear();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public void updateAccount(Account theAccount) {
        try {
            createCurrentSession(sessionFactory).saveOrUpdate(theAccount);
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }

    @Override
    public void removeAccount(Account theAccount) {
        try {
            createCurrentSession(sessionFactory).remove(theAccount);
        } catch (Exception e) {
            e.printStackTrace();
        } 

    }

    @Override
    public void saveAccount(Account theAccount) {
        // get hibernate session
        Session currentSession = sessionFactory.getCurrentSession();

        //save the account 
        currentSession.saveOrUpdate(theAccount);
        currentSession.clear();
    }

    @Override
    public List<String> getAccountNumberList(){

        CriteriaBuilder builder = sessionFactory.getCurrentSession().getCriteriaBuilder();
        CriteriaQuery<String> query = builder.createQuery(String.class);
        System.out.print("query = " + query);
        Root<Account> root = query.from(Account.class);
        query.select(root.get("accountNumber"));
        Query<String> theQuery = createCurrentSession(sessionFactory).createQuery(query);

        return theQuery.getResultList();
    }

}

AccountServiceImpl

package main.com.java.service.domain.implementation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import main.com.java.dao.interfaces.AccountDAO;
import main.com.java.entity.Account;
import main.com.java.service.domain.interfaces.AccountService;

import java.util.List;

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    AccountDAO accountDAO;

    @Override
    @Transactional
    public void addAccount(Account theAccount) {
        accountDAO.addAccount(theAccount);
    }

    @Override
    @Transactional
    public List<String> getAccountNumberList(){
        System.out.print("AccountServiceImpl");
        return accountDAO.getAccountNumberList();
    }

}

AccountNumberGenerator

package main.com.java.service.business.generators;

import main.com.java.service.domain.interfaces.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Random;

@Service
public class AccountNumberGenerator {

    @Autowired
    AccountService accountService;

    @Transactional
    public String generateAccountNumber(){
        String potentialAccountNumber = generatePotentialAccountNumber();
        if(checkIsAccountNumberIsFree(potentialAccountNumber)){
           return potentialAccountNumber;
        }else{
            while(checkIsAccountNumberIsFree(potentialAccountNumber)){
                potentialAccountNumber = generatePotentialAccountNumber();
            }
            return generatePotentialAccountNumber();
        }
    }

    private String generatePotentialAccountNumber(){
        String checksum = generateChecksum();
        String bankNumber = "12853321";
        String clientNumber = generateClientNumber();
        String accountNumber = "";

        StringBuilder stringBuilder = new StringBuilder(accountNumber);
        stringBuilder.append(checksum).append(bankNumber).append(clientNumber);

        return stringBuilder.toString();
    };

    private  boolean checkIsAccountNumberIsFree(String potentialAccountNumber){
        List<String> occupiedAccountNumberList = accountService.getAccountNumberList();
        for (String occupiedAccountNumber : occupiedAccountNumberList) {
            if(potentialAccountNumber.equals(occupiedAccountNumber)){
                return Boolean.FALSE;
            }
        }
        return Boolean.TRUE;

    };

    private static String generateChecksum(){
        Random random = new Random();
        String checksum = "";
        StringBuilder stringBuilder = new StringBuilder(checksum);

        for (int i =0; i<2; i++){
            stringBuilder.append(random.nextInt(10));
        }
        checksum = stringBuilder.toString();
        return checksum;
    };

    private String generateClientNumber(){
        Random random = new Random();
        String clientNumber = "";
        StringBuilder stringBuilder = new StringBuilder(clientNumber);

        for (int i =0; i<16; i++){
            stringBuilder.append(random.nextInt(10));
        }
        clientNumber = stringBuilder.toString();
        return clientNumber;
    }

}

NullPointerException wyrzuca w metodzie checkIsAccountNumberIsFree() w klasie AccountNumberGenerator w linijce:

List<String> occupiedAccountNumberList = accountService.getAccountNumberList();

Wykorzystując debuggera, zauważyłem że accountService zwraca null.

Czy mógłby ktoś pomóc?

3

Wygląda na to że AccountNumberGenerator nie został stworzony jako bean - jestes pewien, że twoj @ComponentScan obejmuje pakiet main.com.java.service.business.generators?

By the way, wstrzykuj przez konstruktor zamiast przez pole - wtedy stawiasz breakpointa w konstruktorze i już podczas uruchamiania apki widzisz czy
a) w ogóle wchodzi do konstruktora
b) zostaje dobry serwis wstrzyknięty

1
Pinek napisał(a):

Wygląda na to że AccountNumberGenerator nie został stworzony jako bean - jestes pewien, że twoj @ComponentScan obejmuje pakiet main.com.java.service.business.generators?

By the way, wstrzykuj przez konstruktor zamiast przez pole - wtedy stawiasz breakpointa w konstruktorze i już podczas uruchamiania apki widzisz czy
a) w ogóle wchodzi do konstruktora
b) zostaje dobry serwis wstrzyknięty

Zmieniłem typ wstrzykiwania, na ten za pomocą konstruktora. Pokazało mi, że w controllerze, chciałem utworzyć obiekt za pomocą "new". Dzięki za pomoc. :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0