This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
Essentially, I am creating football database software that uses MySQL and Java (via JDBC). I have created my database connection which works fine, but when I try to call it to another class it does not work. The getter is public and my Connection variable 'conn' is also public. I am getting nullpointers on the getter line of code when I use it in other classes, however, when I tested the getter it doesn't give me a nullpointer. Here are the two classes that I am testing - including the string of code giving me nullpointers:
CLASS 1:
package ns00790_footballproject;
import java.sql.*;
public class DatabaseConnection {
public Connection conn;
public DatabaseConnection() {
try{
String url = "jdbc:mysql://localhost:3306/?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC";
String user = "root";
String password = "";
// 1. Get a connection do database
Connection conn = DriverManager.getConnection(url, user, password);
System.out.println("Connected ok");
// 2. Create a statement
Statement st = conn.createStatement();
st.execute("CREATE DATABASE IF NOT EXISTS FOOTBALL_LEAGUE;" );
st.execute("USE FOOTBALL_LEAGUE");
st.execute("CREATE TABLE TEAMS(" +
" teamID INT (10) NOT NULL AUTO_INCREMENT," +
" teamName VARCHAR (50)," +
" homeWins INT," +
" homeDraws INT," +
" homeLoss INT," +
" awayWins INT," +
" awayDraws INT," +
" awayLoss INT," +
" homeGoalsFor INT," +
" homeGoalsAgainst INT," +
" awayGoalsFor INT," +
" awayGoalsAgainst INT," +
" gamesPlayed INT," +
" PRIMARY KEY (teamID)" +
" );");
st.execute(" CREATE TABLE GAME(" +
" gameID INT (10) NOT NULL AUTO_INCREMENT," +
" homeTeam VARCHAR(50)," +
" teamID INT (10) NOT NULL," +
" awayTeam VARCHAR(50)," +
" homeScore INT," +
" awayScore INT," +
" PRIMARY KEY (gameID));");
st.execute("CREATE TABLE DETAILS(" +
" goalID INT NOT NULL AUTO_INCREMENT," +
" gameID INT (10) NOT NULL," +
" playerID INT (10)NOT NULL," +
" PRIMARY KEY (goalID));");
st.execute("CREATE TABLE PLAYERS(" +
" playerID INT (10)NOT NULL AUTO_INCREMENT," +
" teamID INT (10) NOT NULL," +
" name VARCHAR(50)," +
" goalsScored INT," +
" penaltyCards INT," +
" PRIMARY KEY (playerID));");
st.execute("ALTER TABLE game ADD INDEX (`teamID`)");
st.execute("ALTER TABLE `game` ADD FOREIGN KEY (`teamID`) REFERENCES `teams`(`teamID`) ON DELETE CASCADE ON UPDATE CASCADE;");
st.execute("ALTER TABLE DETAILS ADD INDEX (`playerID`)");
st.execute("ALTER TABLE `DETAILS` ADD FOREIGN KEY (`playerID`) REFERENCES `players`(`playerID`) ON DELETE CASCADE ON UPDATE CASCADE");
st.execute("ALTER TABLE DETAILS ADD INDEX (`gameID`)");
st.execute("ALTER TABLE `DETAILS` ADD FOREIGN KEY (`gameID`) REFERENCES `game`(`gameID`) ON DELETE CASCADE ON UPDATE CASCADE");
st.execute("ALTER TABLE PLAYERS ADD INDEX (`teamID`)");
st.execute("ALTER TABLE `PLAYERS` ADD FOREIGN KEY (`teamID`) REFERENCES `TEAMS` (`teamID`) ON DELETE CASCADE ON UPDATE CASCADE");
}
catch(Exception exc) {
exc.printStackTrace();
}
}
public Connection getConnection(){
return conn;
}
}
CLASS 2: (method that isnt working)
public void viewPlayerByTeam() {
try {
conn.getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = st.executeQuery("SELECT * FROM PLAYERS");
rs.last();
System.out.println("Connected");
System.out.println(rs.getRow());
}catch(SQLException e){
System.out.println("SQL Error");
}
}
The output should be the number of rows currently in the table, which is 4. I am only getting null-pointer errors.
You are initializing wrong conn reference. There are two objects in your code when there should be one. Do not declare conn locally.
In my app, i'm using subquerys of sqlite, the subquery returns 3 values, its ok, but in the main query, returns empty and i need help in this.
*some parts of variables is in portuguese because i'm brazilian.
public List<Table_Anuncio_Empregador> getAllUser_Empregador() {
SQLiteDatabase db = this.getReadableDatabase();
List<Table_Anuncio_Empregador> anuncios = new ArrayList<Table_Anuncio_Empregador>();
SharedPreferences preferences = context.getSharedPreferences("user_preferences", MODE_PRIVATE);
int user_id = preferences.getInt("user_id_conectado",0);
String selectQuery = "SELECT "+KEY_ID+", "+KEY_IMAGEM_ANUNCIO+", "+KEY_TITULO+", "+KEY_DESCRICAO+", "+KEY_CIDADE
+ " FROM " + TABLE_ANUNCIO_EMPREGADOR
+ " WHERE "+ KEY_ID +" IN (SELECT "+KEY_ANUNCIO_EMPREGADOR_ID+" FROM "+ TABLE_ANUNCIO
+" WHERE "+ KEY_ANUNCIO_PERFIL+" = 'empregador' AND "+ KEY_USER_ID+" = "+user_id+")";
Log.e(LOG, selectQuery);
Cursor c = db.rawQuery(selectQuery, null);
if (c.moveToFirst()) {
do {
Table_Anuncio_Empregador anuncio = new Table_Anuncio_Empregador();
anuncio.setAnuncio_empregador_id(c.getInt(c.getColumnIndex(KEY_ID)));
anuncio.setImagem_do_anuncio(c.getBlob(c.getColumnIndex(KEY_IMAGEM_ANUNCIO)));
anuncio.setTitulo(c.getString(c.getColumnIndex(KEY_TITULO)));
anuncio.setDescricao(c.getString(c.getColumnIndex(KEY_DESCRICAO)));
anuncio.setCidade(c.getString(c.getColumnIndex(KEY_CIDADE)));
anuncios.add(anuncio);
} while (c.moveToNext());
}
return anuncios;
}
The LOG shows the query as :-
E/Banco_Helper: SELECT ID, Imagem_anuncio, Titulo, Descricao, Cidade FROM Anuncio_empregador WHERE ID IN (SELECT Anuncio_empregado_info_ID FROM Anuncio WHERE Anuncio_perfil = 'empregador' AND User_ID = 2)
The tables are created using :-
private static final String CREATE_TABLE_ANUNCIO =
"CREATE TABLE IF NOT EXISTS " + TABLE_ANUNCIO + "(" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
KEY_USER_ID + " INTEGER NOT NULL," +
KEY_ANUNCIO_PERFIL + " TEXT NOT NULL," +
KEY_ANUNCIO_EMPREGADOR_ID + " INTEGER," +
KEY_ANUNCIO_PRESTADOR_ID + " INTEGER," +
KEY_CREATED_AT + " DATETIME NOT NULL" + ")";
and :-
private static final String CREATE_TABLE_ANUNCIO_EMPREGADOR =
"CREATE TABLE IF NOT EXISTS " + TABLE_ANUNCIO_EMPREGADOR + "(" + KEY_ID + " INTEGER PRIMARY KEY," +
KEY_TITULO + " TEXT NOT NULL," +
KEY_DESCRICAO + " TEXT NOT NULL," +
KEY_BAIRRO + " TEXT NOT NULL," +
KEY_CIDADE + " TEXT NOT NULL," +
KEY_ESTADO + " TEXT NOT NULL," +
KEY_LOCAL_SERVICO + " TEXT NOT NULL," +
KEY_EXIGENCIAS + " TEXT," +
KEY_IMAGEM_ANUNCIO + " BLOB NOT NULL" + ")";
Equating to :-
CREATE TABLE IF NOT EXISTS Anuncio(
ID INTEGER PRIMARY KEY AUTOINCREMENT,
USER_ID INTEGER NOT NULL,
Anuncio_perfil TEXT NOT NULL,
Anuncio_empregado_info_ID INTEGER,
ANUNCIO_PRESTADOR_ID INTEGER,
CREATED_AT DATETIME NOT NULL
);
And :-
CREATE TABLE IF NOT EXISTS Anuncio_empregador (
ID INTEGER PRIMARY KEY,
Titulo TEXT NOT NULL,
Descricao TEXT NOT NULL,
Bairro TEXT NOT NULL,
Cidade TEXT NOT NULL,
Estado TEXT NOT NULL,
Local_Servico TEXT NOT NULL,
Exigencias TEXT,
Imagem_anuncio BLOB NOT NULL
);
I believe that your issue is with the actual data rather then the query.
That is, the following was used to create and populate the two tables and to also run the query (plus some intermediate queries). The result was that the three expected rows were included and that the three rows that should have been excluded were. That is the query in question ran with the expected results.
The following SQL was used :-
DROP TABLE IF EXISTS Anuncio;
CREATE TABLE IF NOT EXISTS Anuncio(
ID INTEGER PRIMARY KEY AUTOINCREMENT,
USER_ID INTEGER NOT NULL,
Anuncio_perfil TEXT NOT NULL,
Anuncio_empregado_info_ID INTEGER,
ANUNCIO_PRESTADOR_ID INTEGER,
CREATED_AT DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
DROP TABLE IF EXISTS Anuncio_empregador;
CREATE TABLE IF NOT EXISTS Anuncio_empregador (
ID INTEGER PRIMARY KEY,
Titulo TEXT NOT NULL,
Descricao TEXT NOT NULL,
Bairro TEXT NOT NULL,
Cidade TEXT NOT NULL,
Estado TEXT NOT NULL,
Local_Servico TEXT NOT NULL,
Exigencias TEXT,
Imagem_anuncio BLOB NOT NULL DEFAULT X'00010203040506070809'
)
;
INSERT INTO Anuncio_empregador
(Titulo,Descricao,Bairro,Cidade,Estado,Local_Servico,Exigencias)
VALUES
('Mr','Albert','Bloggs','something','something else','xxx','xxxx'),
('Mr','Bert','Bloggs','something','something else','xxx','xxxx'),
('Mr','Charlie','Bloggs','something','something else','xxx','xxxx'),
('Mr','Dave','Bloggs','something','something else','xxx','xxxx'),
('Mr','Eddie','Bloggs','something','something else','xxx','xxxx'),
('Mr','Fred','Bloggs','something','something else','xxx','xxxx'),
('Mr','George','Bloggs','something','something else','xxx','xxxx')
;
SELECT * FROM Anuncio_empregador;
INSERT INTO Anuncio
(USER_ID, Anuncio_perfil,Anuncio_empregado_info_ID,ANUNCIO_PRESTADOR_ID)
VALUES
(1,'empregador',1,100),
(2,'empregador',2,100),
(3,'empregador',3,100),
(4,'not an empregador',1,100),
(5,'not an empregador',2,100),
(6,'not an empregador',3,100)
;
SELECT * FROM Anuncio;
SELECT * FROM Anuncio WHERE Anuncio_perfil = 'empregador';
SELECT ID,Imagem_anuncio,Titulo,Descricao,Cidade
FROM Anuncio_empregador
WHERE ID IN
(
SELECT Anuncio_empregado_info_ID
FROM ANUNCIO
WHERE ANUNCIO_PERFIL = 'empregador' AND USER_ID = user_id
)
;
Note that some liberties were taken, like
using the CURRENT_TIMESTAMP and
using X'00010203040506070809'
saving having to repeat these values which would have no impact upon workings of the SQL.
The resultant Anuncio_empregador table being :-
The resultant Anuncio table being :-
i.e. last 3 rows have been set to be excluded according to the clause WHERE ANUNCIO_PERFIL = 'empregador'
The result of the query in Question
SELECT ID,Imagem_anuncio,Titulo,Descricao,Cidade
FROM Anuncio_empregador
WHERE ID IN
(
SELECT Anuncio_empregado_info_ID
FROM ANUNCIO
WHERE ANUNCIO_PERFIL = 'empregador' AND USER_ID = user_id
)
;
being :-
Note changing AND USER_ID = user_id to AND USER_ID = 2 shows just the 1 row for Bert, as expected.
My question is very simple. I just want to know how to write a create Table statement for MySQL using Java statements where the name of the table is a string.
I know how to insert String values as values of the coloumns using Java. I tried it that way but could not do it. I will show you my code:
String table = "CREATE TABLE table_name'" +
"(SL. No INT not NULL AUTO_INCREMENT, " +
" NAME VARCHAR(100), " +
" YEAR INT not NULL, " +
" IMDB INT not NULL)";
Here instead of table_name I want to input a string variable. The variable name is s2.
Now the Insert into table value is as follows:
myStmt.executeUpdate("insert into l1(id,email,usname,pwd)value('"+(i)+"','"+s1+"','"+s2+"','"+s5+"')");
Here s1,s2,s5 are string values. But this method is not working for Create Table and it is showing syntax error. What is the correct code?
You should remove additional ' sign and change name for SL. No column to somethin else so it looks like
String table = "CREATE TABLE table_name" +
"(slno INT not NULL AUTO_INCREMENT, " +
" NAME VARCHAR(100), " +
" YEAR INT not NULL, " +
" IMDB INT not NULL)"
If your table string is correct you can replace table_name with new name for each table with replace method on string or just use function
public static String getCreateTableQuery(String tableName) {
String table = "CREATE TABLE table_name" +
"(slno INT not NULL AUTO_INCREMENT, " +
" NAME VARCHAR(100), " +
" YEAR INT not NULL, " +
" IMDB INT not NULL)";
String createTableWithNewNameQuery = table.replaceFirst("table_name'", tableName);
return createTableWithNewNameQuery;
}
I try to use HSQLDB embedded in program.
However, when I create table and insert data in the database, error occurs.
Following is part of error message.
java.sql.SQLSyntaxErrorException: unexpected token: MAR required: )
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.executeUpdate(Unknown Source)
It occurs when I insert some data in the database.
This is my CREATE statement.
stmt.execute("CREATE TABLE IF NOT EXISTS readability ( id INTEGER NOT NULL IDENTITY,"
+ "LOC INTEGER DEFAULT NULL, " + "numOfComments INTEGER DEFAULT NULL,"
+ "numOfBlankLines INTEGER DEFAULT NULL," + "numOfBitOperators INTEGER DEFAULT NULL,"
+ "readability double DEFAULT NULL," + "username varchar(255) DEFAULT NULL,"
+ "storedTime datetime DEFAULT NULL," + "methodname varchar(255) DEFAULT NULL,"
+ "classname varchar(255) DEFAULT NULL," + "patternrate double DEFAULT NULL,"
+ "maxNestedControl INTEGER DEFAULT NULL," + "programVolume double DEFAULT NULL,"
+ "entropy double DEFAULT NULL,"
+ "CONSTRAINT username FOREIGN KEY (username) REFERENCES user (username) ON DELETE NO ACTION ON UPDATE NO ACTION"
+ ");");
This is my INSERT statement.
stmt.executeUpdate(
"INSERT INTO readability (LOC, numOfComments, numOfBlankLines, numOfBitOperators,"
+ " readability, username, storedTime, methodname, classname, patternRate, maxNestedControl, programVolume, entropy) VALUES("
+ readability.getLOC() + ", " + readability.getNumOfComments() + ", "
+ readability.getNumOfBlankLines() + ", " + readability.getNumOfBitOperators() + ", "
+ readability.getReadability() + ", '" + readability.getUser().getUsername() + "', "
+ readability.getStoredTime() + ", '" + readability.getMethodName() + "', '"
+ readability.getClassName() + "', " + readability.getPatternRate() + ", "
+ readability.getMaxNestedControl() + ", " + readability.getProgramVolume() + ", "
+ readability.getEntropy() + ")",
Statement.RETURN_GENERATED_KEYS);
The object readability has all attributes used.
Do not concatenate values into a query string. Your code is vulnerable to SQL injection, and it is probably also the cause of the error. Use a prepared statement with parameter placeholders and set the values with the appropriate setters.
Your code would then become something like (leaving out a lot of columns for brevity):
try (PreparedStatement insert = connection.prepareStatement(
"insert into readability (LOC, username) values (?, ?)",
Statement.RETURN_GENERATED_KEYS)) {
insert.setInt(readability.getLOC();
insert.setString(readibility.getUser().getUsername());
insert.executeUpdate();
// handle generated keys...
}
You might also want to consider using an ORM like Hibernate.
I am trying to make a variable Table name through Java.
My code is :
public void createTable(String tableName){
try {
Statement stmt = con.createStatement();
stmt.executeUpdate("CREATE TABLE '"+tableName+"'" +
"(id INTEGER not NULL, " +
" username VARCHAR(255), " +
" pass VARCHAR(255), " +
" age INTEGER, " +
" PRIMARY KEY ( id ))");
}
catch (SQLException e){
e.printStackTrace();
}
}
It gives me a syntax error saying:
Incorrect syntax near 'VariableTableNameIChose'.
Does anyone have any ideas?
It could be one of 2 things or the combination of both.
Maybe the single quotes around the table name are not valid in your database. So do like this:
stmt.executeUpdate("CREATE TABLE "+tableName+" " +
"(id INTEGER not NULL, " +
" username VARCHAR(255), " +
" pass VARCHAR(255), " +
" age INTEGER, " +
" PRIMARY KEY ( id ))");
Or maybe you need a spaces between the table name and the ( following after:
Statement stmt = con.createStatement();
// v this one was missing
stmt.executeUpdate("CREATE TABLE '"+tableName+"' " +
"(id INTEGER not NULL, " +
" username VARCHAR(255), " +
" pass VARCHAR(255), " +
" age INTEGER, " +
" PRIMARY KEY ( id ))");
The table name is an identifier. Identifiers do not use single quotes (in standard SQL).
"CREATE TABLE '"+tableName+"' "
Will result in
CREATE TABLE 'foobar'
which is invalid SQL. You need to remove the single quotes:
"CREATE TABLE "+tableName+" " + ...
As the table name is apparently a user input, you might actually want to use quoted identifiers (although this is in general a bad idea). Identifiers are quoted using double quotes in the SQL standard:
"CREATE TABLE \""+tableName+"\" " + ...