0

I am currently programming a three layer architecture banking application as a student project. As I understood the Dao pattern, I implemented it and want to handle the database interaction with it, but I actually can not, because my dao class can not access the database singleton getInstanceDB. The dao class is an implementation of an interface. The classes are all in the same package. It seems to be an visablity problem, because the Singleton is not callable in any other class than itself. Here is the code.

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;

    public class Database {
        private static Database instance;
        private Connection conn;
        private Statement stmt;

        private Database() {
            try {
                Class.forName("oracle.jdbc.driver.OracleDriver");
                conn = DriverManager.getConnection("jdbc:oracle:thin:@oracle.leuphana.de:1521:oradb1", "...", "...");
                stmt = conn.createStatement();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        // Thread-Safe Singleton
        public static synchronized Database getInstanceDB() {
            if (instance == null) {
                instance = new Database();
            }
            return instance;
        }
    }
// Select Data by CustomerID
    @Override
    public ResultSet select(Kunde kunde) {
        if (kunde == null)
            throw new IllegalArgumentException("given id is null");

        if (kunde.getId() < 0)
            throw new IllegalArgumentException("given id has an invalid value");

        String query = "SELECT * FROM customer WHERE customer_id=" + Integer.toString(kunde.getId());
        ResultSet rs  = null;
        try {
            Connection conn = getInstanceDB().getConnection();
            Statement stmt = conn.createStatement();
            rs =  stmt.executeQuery(query);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return rs;
    }

I am new to stackoverflow, I hope this thread is ok, if you need more information just ask me ^^

EDIT: Error: The method getInstanceDao() is undefined for the type KundeDao getConnection() see the answer, it's the same except the catch part

Thanks for the quick and helpful answers.

1stNox
  • 19
  • 5
  • 1
    what error do you get? – Stultuske Jun 02 '20 at 09:24
  • 1
    Withour error message I just can guess: Maybe ```Database.getInstanceDB().getConnection();``` instead of ```getInstanceDB().getConnection();``` ? – TomStroemer Jun 02 '20 at 09:30
  • your database connectivity logic is a bit wrong. you are making a private constructor to create a db connection and after the instance created, you are trying to access the getConnection() which you never created to share for public. – Natsu Jun 02 '20 at 09:35
  • 1
    Lessons to a new poster: please make your code *complete* see [mcve]. You have left out essential parts like the definition of `getConnection` and whether the calling method is in the same class or another one. The code needs to be complete enough for us to compile and try to run. Also, if you get an error message, always include it in your qustion, formatted as code (not an image). Please fix those problems using the [edit] link. – RealSkeptic Jun 02 '20 at 09:37
  • The error is: "the method getInstanceDB() is undefined for the type KundeDao". @TomStroemer That was the solution, thank you. Ok, I already suspected that my db logic is wrong, I am currently trying to understand how OJDBC works. In my opinion the documentation is a bit barely. – 1stNox Jun 02 '20 at 09:41
  • This isn't going to work anyway. You can't get by with just one Connection, and you certainly can't get by with just one Statement. You need a connection pool, and a local connection every time you need one, and a local statement ditto. – user207421 Jun 02 '20 at 09:51
  • Is it not possible to manage database interactions with one connection? Otherwise the performance would get worse, because multiple user have multiple connections and as a consequence of this the database would have to response to x*n connections instead of to n, or not? Makes sense that I need local statements. As I mentioned ealier, do not forget I am currently approaching this theme, pls. – 1stNox Jun 02 '20 at 10:01

1 Answers1

-1

I think your logic is kinda wrong. Try something like this.

public Connection getConnection() {
    try {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        conn = DriverManager.getConnection("jdbc:oracle:thin:@oracle.leuphana.de:1521:oradb1", "...", "...");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return conn;
}

then create your Database instance and call getConnection() method like this.

Database dbInstance = Database.getInstanceDB();

public void anyMethod(){
    try {
        Connection conn = dbInstance.getConnection();
        Statement stmt = conn.createStatement();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

Note: To open close connections you should use try-with-resources for more convenient approach.

Natsu
  • 443
  • 3
  • 10
  • These exceptions should be thrown, not caught. The second example should use try-with-resources any time in the last several years. The whole idea of instance members for Connection and Statmeent is radically incorrect, – user207421 Jun 02 '20 at 09:53
  • @user207421 Actually i didn't change OP code. I just moved which he provided into a different method to point out the issue. I also accept what you said about try-wtih-resources. – Natsu Jun 02 '20 at 09:58
  • Ok, I did not know this, we just learned this kind of operation as best practices this semester. Is a connection pool best practices, u mentioned this ealier @user207421 – 1stNox Jun 02 '20 at 10:03
  • @1stNox normally you have to create a connection and close it in finally, or try-with-resources approach which is recommended. – Natsu Jun 02 '20 at 10:07
  • @Natsu If I understand u correctly, I should discard the Database class and just use functions with opening and closing connections? The alternative is to create a Connection pool and Resources? I just read a bit about Resources and it seems to be best practices or not? – 1stNox Jun 02 '20 at 10:13
  • @1stNox check this out. https://stackoverflow.com/a/16331963/13528037 – Natsu Jun 02 '20 at 10:15