Search code examples
javaspringspring-bootjavabeansautowired

Spring boot javabean that could not be found


I have POJO classes which are for 90% accessed using services and repositories, but in those 10% cases I want a service to have a attribute of a POJO and in those cases the autowiring fails.

At runtime I get "Parameter 0 of constructor in com.ripple.trading.impl.Trader required a bean of type 'com.ripple.repositories.pojo.Wallet' that could not be found." This is the Trader class:

  @Service
public class Trader implements ITrade {
    private Wallet wallet;
    private List<Quantity> balance;
    private Advice latestAdvice;


@Autowired
private OrderService orderService;
@Autowired
private HistoryService historyService;
@Autowired
private CurrencyService currencyService;

private Advice lastAdvice;

public Trader(Wallet wallet, Advice advice){
    this.lastAdvice = Advice.HOLD;
    this.wallet = wallet;
    this.balance = WalletFetcher.getWalletByAddress(this.wallet.getAddress());
    this.latestAdvice = advice;
}
}

This is the wallet

@Document
public class Wallet extends BaseModel implements Serializable{

private String address;
private String encryptedSecret;
private String name;


/**
 * Instantiates a new Wallet.
 *
 * @param address         the address
 * @param encryptedSecret the encrypted secret
 */
@PersistenceConstructor
public Wallet(String address, String encryptedSecret, String name) {
    this.address = address;
    this.encryptedSecret = encryptedSecret;
    this.name = name;
}

/**
 * Gets address.
 *
 * @return the address
 */
public String getAddress() {
    return address;
}

/**
 * Sets address.
 *
 * @param address the address
 */
public void setAddress(String address) {
    this.address = address;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

/**
 * Gets encrypted secret.
 *
 * @return the encrypted secret
 */
public String getEncryptedSecret() {
    return encryptedSecret;
}

/**
 * Sets encrypted secret.
 *
 * @param encryptedSecret the encrypted secret
 */
public void setEncryptedSecret(String encryptedSecret) {
    this.encryptedSecret = encryptedSecret;
}
}

And this is my main application

@EnableOAuth2Sso
@ComponentScan
@EnableMongoRepositories(value = "com.ripple.repositories.mongo")
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
public class RippleSpringApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(RippleSpringApplication.class);
}

/**
 * The entry point of application.
 *
 * @param args the input arguments
 */
public static void main(String[] args) {
    SpringApplication.run(RippleSpringApplication.class, args);
}
}

My guess is the autowiring, maybe break the application down in smaller pieces until it works again. It's an issue that previously had occurred and refactoring fixed it, but the reason behind it, why did it fixed it, was it the right solution. That's what I'm after now.

My applicationclass is in the root package so ComponentScan shouldn't be the problem.


Solution

  • Class Wallet is not a Spring configured bean. It's just a class (a spring-data-mongodb document).

    If your Spring component has a single constructor, Spring automatically considers this constructor for autowiring and will look for beans matching the constructor argument types to provide when calling that constructor.

    That is why you're receiving that error.

    If you want Trader to be a "service" consider not making Wallet and Advice it's fields because that essentially introduces state into what should be stateless. If you have methods in Trader that do something with the Wallet and Advice consider passing those as parameters to those methods. Something like:

    @Service
    public class Trader {
      /// ... your autowired dependecies
    
      public BigDecimal getBalance(Wallet wallet) { 
        return WalletFetcher.getWalletByAddress(wallet.getAddress()); 
      }
    }