1

I am trying to use dependency injection in Java Spring Boot. Receiving Error below in controller in this line. productService.updateProduct(product);

Error: Change 1st parameter of abstract method from Product to Optional

How can this be resolved?

public class Product {
    @Getter @Setter public @Id @GeneratedValue Long productId;
    @Getter @Setter public String productName;
    @Getter @Setter public String productDescription;
    Product() {}

    Product(String productName, String productDescription) {
        this.productName = productName;
        this.productDescription = productDescription;
    }
}

Interface:

public interface IProductService {
    public Product updateProduct(Product product);
}

Service:

@Service
public class ProductService implements IProductService {
    @Override
    public Product updateProduct(Product product){
        product.productName = "test12345";
        return product;
    }
}

Controller:

class ProductController {
    ProductRepository repository;
    @Autowired IProductService productService;

    ProductController(IProductService productService, ProductRepository repository) {
        this.productService = productService;
        this.repository = repository;
    }

    @GetMapping("/products/{id}")
    Product one(@PathVariable Long id) {
        var product = repository.findById(id);
        var finalProduct = productService.updateProduct(product); // error in this line
        return finalProduct;
    }
mattsmith5
  • 540
  • 4
  • 29
  • 67

1 Answers1

0

And check whether your Repository class return Optional<Product>. because findbyId return type of optional. Then your have to use like below.

Optional<Product> product = repository.findById(id);

And Better to add @Autowire @Controller annotation no need constructor.

@Controller
class ProductController {
@Autowired
private ProductRepository repository;

@Autowire
private IProductService productService;

}
S. Anushan
  • 728
  • 1
  • 6
  • 12
  • 1
    or I can use this, repository.findById(id).orElse(null); , thanks – mattsmith5 Jul 11 '21 at 04:36
  • Yes you can use that also. – S. Anushan Jul 11 '21 at 04:41
  • by the way, its interesting I didn't even had to set the Application config with getbean , etc , its like AutoWired did everything https://dzone.com/articles/dependency-injection-in-spring ApplicationContext context = new AnnotationConfigApplicationContext(AutomatedAnnotationConfig.class); Car car = context.getBean(Car.class); car.start(); – mattsmith5 Jul 11 '21 at 04:48
  • 1
    Autowire make it easy everything. It will injecte object from container whenever it required. – S. Anushan Jul 11 '21 at 04:50
  • Field injection like this is [_actively discouraged_](https://stackoverflow.com/questions/39890849/what-exactly-is-field-injection-and-how-to-avoid-it); the constructor is the better approach. (With Lombok, which it appears OP is using, `@AllArgsConstructor` or `@RequiredArgsConstructor` will generate it.) – chrylis -cautiouslyoptimistic- Jul 11 '21 at 05:50
  • Spring boot main concept of dependency injection we can achieve with any type of injection. While doing the Autowire no need initial the object whenever it needed it will inject from context no need additional work. What are you trying to say and what your concerns. – S. Anushan Jul 11 '21 at 05:59
  • And we did not raised any concerns about AllArgsConstructor and RequiredArgsConstructor. – S. Anushan Jul 11 '21 at 06:01