0

I fixed this by removing the s.close() calls, so can I just ignore Eclipse complaining about the memory leak? Why does creating a new Scanner object not re-open System.in?


The following error is the full error:

Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at com.qa.jdbc.table.CustomerDAO.deleteCustomerByID(CustomerDAO.java:109)
at com.qa.jdbc.runner.Runner.main(Runner.java:16)

This is my Runner:

package com.qa.jdbc.runner;

import com.qa.jdbc.table.Customer;
import com.qa.jdbc.table.CustomerDAO;

public class Runner {

    public static void main(String[] args) {
        CustomerDAO customerDAO = new CustomerDAO("root", "root");
        Customer customer = new Customer();
        
        customer.createCustomer(customer);
        customerDAO.deleteCustomerByID();
        customerDAO.updateCustomer(customer);
        System.out.println(customerDAO.readAll());
    }
}

Here is the methods in the Customer & customerDAO Class Files that are relevant:

public Customer createCustomer(Customer customer) {
        
        Scanner s = new Scanner(System.in);
        try {
            System.out.println("Enter Customer First Name:");
            customer.setFirstName(s.nextLine());
            System.out.println("Enter Customer Last Name:");
            customer.setLastName(s.nextLine());
            System.out.println("Enter Customer Home Address:");
            customer.setHomeAddress(s.nextLine());
            return customer;
        } finally {
            s.close();
            System.out.println("Scanner Closed!");
        }
    }
public void deleteCustomerByID() {
        Scanner s = new Scanner(System.in);
        int customer_id;
        String deleteQuery = "DELETE FROM customers WHERE customer_id = ?";
        try {
            Connection con = DriverManager.getConnection(jdbcConnectionURL, username, password);
            PreparedStatement ps = con.prepareStatement(deleteQuery);
            
            System.out.println("Enter Customer ID of customer to delete:");
            customer_id = s.nextInt();
            ps.setInt(1, customer_id);
            int rows = ps.executeUpdate();
            System.out.println("Rows affected: " + rows);
        } catch (SQLException e) {
            LOGGER.debug(e.getStackTrace());
        } finally {
            s.close();
            System.out.println("Scanner Closed!");
        }
    }

Would using the hasNextLine() method be the right call here or something else like a switch-case in order to choose what method a user wishes to perform?

Console output after taking user input

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
AceKokuren
  • 41
  • 8
  • The advice to close the scanner is correct in general, but when doing it with a scanner that wraps System.in, you also close System.in. Once closed, it is impossible to reopen it. – Mark Rotteveel Jun 03 '22 at 11:28
  • So is there a better wrapper to use inside Scanner then?! Is there a good way to close it at the end of the programme? – AceKokuren Jun 03 '22 at 12:44
  • Again, just don't close the scanner wrapping System.in. The end of the program will clean it up. As detailed in some of the duplicates I linked, you can use a close-shield around System.in, but that is more a stop-gap/workaround in my opinion. – Mark Rotteveel Jun 03 '22 at 13:03

0 Answers0