Null pointer exception occurs when you reference a null object, doesn't it? I intend to create an app that manages a store's data such as purchase (stock purchase), stock list, sales, and customer info. The data is intended to be displayed on the app table as soon as the file dynamicmenu1 is run, without clicking any button, but it only displays hard-coded data instead.
app interface
Data to be displayed from table
at view.dynamicmenu1.simpannotaActionPerformed(dynamicmenu1.java:984)
at view.dynamicmenu1.access$1000(dynamicmenu1.java:37)
at view.dynamicmenu1$11.actionPerformed(dynamicmenu1.java:404)
private void simpannotaActionPerformed(java.awt.event.ActionEvent evt) {
tabmodel.addRow(data); // line 984
try {
/** con = (Connection) Model.koneksidatabase();
java.sql.PreparedStatement prepstmnt = con.prepareStatement(sql);
*/
Statement stmnt = con.createStatement();
String sql = "Insert into tb_pembelian VALUES ('" + textid.getText()+"','"
+textnamabrg.getText()+"','"+textqty.getText()
+"','"+texthrg.getText()+"','"+texttgl.getText()+"','"+textsupplier.getText();
//cek stmnt di 'Model.java' di bagian ArrayList barang().
//Mengapa selalu Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
//at view.dynamicmenu1.simpannotaActionPerformed(dynamicmenu1.java:960)
//at view.dynamicmenu1.access$900(dynamicmenu1.java:21)
//at view.dynamicmenu1$10.actionPerformed(dynamicmenu1.java:378)??????
//NullPointerException??????
stmnt.executeUpdate(sql);
stmnt.close();
JOptionPane.showMessageDialog(null, "Data telah disimpan");
kosongkanform();
} catch ( HeadlessException| SQLException e) {
JOptionPane.showMessageDialog(this, e.getMessage());
}
textid.setText("");
textnamabrg.setText("");
textqty.setText("");
texthrg.setText("");
texttgl.setText("");
textsupplier.setText("");
}
// line 37
public class dynamicmenu1 extends javax.swing.JFrame {
String id_barang;
String nama_barang;
String kuantitas;
String harga_satuan;
String tanggal_beli;
DefaultTableModel tabmodel;
Connection con =null;
Statement stmnt=null;
PreparedStatement prepstmnt;
ResultSet res = null;
String sql = null;
the 3rd null pointer exception error
simpannota.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
simpannotaActionPerformed(evt); // Line 404
}
});
Null pointer errors happen when there isn't anything present.
Have you checked your constructor for proper init for your variables.
Related
In vertx-jdbc-client 3.5.0 ,the sql "DELETE FROM user;INSERT INTO user... " is ok.After update to vertx-jdbc-cient 3.5.2,the sql is fail with the error:
io.vertx.core.VertxException: org.postgresql.util.PSQLException: A result was returned when none was expected.By debugging, I found that the SQL was changed auto to DELETE FROM user RETURNING *;INSERT INTO user ..., then RETURNING * cause update error.
I find the cause:in vert-jdbc-client 3.5.0.
class JDBCConnectionImpl implements SQLConnection {
...
private SQLOptions options;
}
in vert-jdbc-client 3.5.2:
class JDBCConnectionImpl implements SQLConnection {
...
private SQLOptions options = new SQLOptions().setAutoGeneratedKeys(true);
}
then casue
public class Parser {
...
private static boolean addReturning(StringBuilder nativeSql, SqlCommandType currentCommandType,
String[] returningColumnNames, boolean isReturningPresent) throws SQLException {
if (isReturningPresent || returningColumnNames.length == 0) {
return false;
}
if (currentCommandType != SqlCommandType.INSERT
&& currentCommandType != SqlCommandType.UPDATE
&& currentCommandType != SqlCommandType.DELETE) {
return false;
}
nativeSql.append("\nRETURNING ");
...
}
Should I modify the SQL code or set up the JDBC client? Can anyone give me a suggestion?
I just found it's not a issue,because when i code SQLConnection sqlConnection = ...; sqlConnection.setOptions(null); ,then old sql update is ok.So it's a change,i think.
I habe a sqlite database in java (eclipse) with the library sqlite-jdbc-3.16.1.jar.
I have 5 rows in table1: id(ID Integer PRIMARY KEY AUTOINCREMENT), name, row3, row4, row5
I want to insert name, row3 and row4 and the id to increment itself.
public static void insertTest(String name, byte[] contentRow3, byte[] contentRow4) {
String sql = "INSERT INTO table1(name, contentRow3, contentRow4) VALUES(?,?,?)";
try (Connection conn = connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(2, name);
pstmt.setBytes(3, contentRow3);
pstmt.setBytes(4, contentRow4);
System.out.println("Added new Person to DB");
pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
Error : Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
What is the problem here?
Placeholders in Java prepared statements begin at index 1, not 2. I expect that the following corrected code should work:
try (Connection conn = connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, name);
pstmt.setBytes(2, contentRow3);
pstmt.setBytes(3, contentRow4);
System.out.println("Added new Person to DB");
pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
The exception you are getting is complaining that index position 3 is out of bounds. Most likely, under the hood when you did pstmt.setBytes(3, contentRow4) this translated to accessing the fourth array element, which would be index 3 assuming the array indexing is zero based.
I am developing a stand alone application, using sql server compact 3.5 sp2 which runs in process. No Database writes involved. Its purely a reporting application. Read many articles about reusing open db connections in case of sql compact(connection pooling) due to its different behavior from sql server.
Quoting the comments from a quiz opened by Erik Ejlskov Jensen Link, where its discussed an open early close late strategy for sql server compact databases. Based on this, with my limited experience I have implemented a not so complex Connection handling+Data access layer. Basically I am unsure if i am writing it in a recommended way. Please could any one point me in the right direction with rooms for improvement in this connection handling approach i have written?
The DbConnection class
public class FkDbConnection
{
private static SqlCeConnection conn;
private static DataTable table;
private static SqlCeCommand cmd;
~FkDbConnection() { conn = null; }
//This will be called when the main winform loads and connection will be open as long as the main form is open
public static string ConnectToDatabase()
{
try {
conn = new SqlCeConnection(ConfigurationManager.ConnectionStrings["Connstr"].ConnectionString);
if (conn.State == ConnectionState.Closed || conn.State == ConnectionState.Broken)
{
conn.Open();
}
return "Connected";
}
catch(SqlCeException e) { return e.Message; }
}
public static void Disconnect()
{
if (conn.State == ConnectionState.Open || conn.State == ConnectionState.Connecting || conn.State == ConnectionState.Fetching)
{
conn.Close();
conn.Dispose();
//conn = null; //does conn have to be set to null?
}
//else the connection might be already closed due to failure in opening it
else if (conn.State == ConnectionState.Closed) {
conn.Dispose();
//conn = null; //does conn have to be set to null?
}
}
/// <summary>
/// Generic Select DataAccess
/// </summary>
/// <param name="sql"> the sql query which needs to be executed by command object </param>
public static DataTable ExecuteSelectCommand(SqlCeCommand comm)
{
if (conn != null && conn.State == ConnectionState.Open)
{
#region block using datareader
using (table = new DataTable())
{
//using statement needed for reader? Its closed below
using (SqlCeDataReader reader = comm.ExecuteReader())
{
table.Load(reader);
reader.Close(); //is it needed?
}
}
#endregion
# region block using dataadpater
//I read DataReader is faster?
//using (SqlCeDataAdapter sda = new SqlCeDataAdapter(cmd))
//{
// using (table = new DataTable())
// {
// sda.Fill(table);
// }
//}
#endregion
//}
}
return table;
}
/// <summary>
/// Get Data
/// </summary>
/// <param name="selectedMPs"> string csv, generated from a list of selected posts(checkboxes) from the UI, which forms the field names used in SELECT </param>
public static DataTable GetDataPostsCars(string selectedMPs)
{
DataTable dt;
//i know this it not secure sql, but will be a separate question to pass column names to select as parameters
string sql = string.Format(
"SELECT " + selectedMPs + " "+
"FROM GdRateFixedPosts");
using (cmd = new SqlCeCommand(sql,conn))
{
cmd.CommandType = CommandType.Text;
//cmd.Parameters.Add("#fromDateTime",DbType.DateTime);
//cmd.Parameters.Add("#toDateTime",DbType.DateTime);
dt = ExecuteSelectCommand(cmd);
}
return dt;
}
}
The Main UI (Form) in which connection opened, for connection to be open through out. 2 other reporting forms are opened from here. Closing main form closes all, at which point connection is closed and disposed.
private void FrmMain_Load(object sender, EventArgs e)
{
string str = FkDbConnection.ConnectToDatabase();
statStDbConnection.Items[0].Text = str;
}
private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
{
FkDbConnection.Disconnect();
}
Comments, improvements on this connection class much appreciated. See my questions also inline code
Thank you.
Updated classes as per Erik's suggestion. with a correction on ExecuteSelectCommand() and an additional class which will instantiate command objs in "using" and pass data to the UI. I intent to add separate GetDataForFormX() methods since the dynamic sql for each form may differ. Hope this is ok?
Correction to Erik's code:
public static DataTable ExecuteSelectCommand(SqlCeCommand comm)
{
var table = new DataTable();
if (conn != null && conn.State == ConnectionState.Open)
{
comm.Connection = conn;
using (SqlCeDataReader reader = comm.ExecuteReader())
{
table.Load(reader);
}
}
return table;
}
New FkDataAccess class for passing Data to UI
public class FkDataAccess
{
public static DataTable GetDataPostsCars(string selectedMPs)
{
var table = new DataTable();
string sql = string.Format(
"SELECT " + selectedMPs + " " +
"FROM GdRateFixedPosts");
if (FkDbConnection.conn != null && FkDbConnection.conn.State == ConnectionState.Open)
{
using (SqlCeCommand cmd = new SqlCeCommand(sql, FkDbConnection.conn))
{
cmd.CommandType = CommandType.Text;
//cmd.Parameters.Add("#fromDateTime",DbType.DateTime);
table = FkDbConnection.ExecuteSelectCommand(cmd);
}
}
return table;
}
//public static DataTable GetDataXY(string selectedvals)
// and so on
}
Too much code in your data access class, makes it unreadable and hard to maintain
The SqlCeonnection object will be disposed when you close it (and when the app closes)
You cannot dispose the DataTable if you want to use it elsewhere, and it is an completely managed object anyway.
It is a good pattern to limit your classes to a single responsibility
public class FkDbConnection
{
private static SqlCeConnection conn;
~FkDbConnection() { conn = null; }
//This will be called when the main winform loads and connection will be open as long as the main form is open
public static void ConnectToDatabase()
{
// Handle failure to open in the caller
conn = new SqlCeConnection(ConfigurationManager.ConnectionStrings["Connstr"].ConnectionString);
conn.Open();
}
public static void Disconnect()
{
if (conn != null)
{
conn.Close();
}
}
public static DataTable ExecuteSelectCommand(SqlCeCommand comm)
{
var table = new DataTable();
if (conn != null && conn.State == ConnectionState.Open)
{
comm.Connection = conn;
using (SqlCeDataReader reader = comm.ExecuteReader())
{
table.Load(reader);
}
}
return table;
}
private void FrmMain_Load(object sender, EventArgs e)
{
try
{
FkDbConnection.ConnectToDatabase();
statStDbConnection.Items[0].Text = "Connected";
}
catch (Exception ex)
{
//Inform use that we canot proceed, what she can do to remedy, and exit
}
}
private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
{
FkDbConnection.Disconnect();
}
We are using java jdk 1.7.0_45, postgresql jdbc connector postgresql-9.3-1100.jdbc41.jar.
Here is a synopsis of our problem, as much as possible of code pasted below.
This code:
ResultSet rs = DbConn.getInstance().doQuery("Select d.deptId from Depts d");
while (rs.next()){
System.out.println(rs.getInt("d.deptId"));
Produces the error:
org.postgresql.util.PSQLException: The column name d.deptId was not found in this ResultSet.
This code:
ResultSet rs = DbConn.getInstance().doQuery("Select d.deptId from Depts d");
while (rs.next()){
System.out.println(rs.getInt("deptId"));
Produces no error.
Is there a way, besides removing the "d." from the first query, to make the first code snippet not throw the error message?
Here is the source code:
public class JoinTest {
#Test
public void test(){
boolean pass = false;
try {
ResultSet rs = DbConn.getInstance().doQuery("Select d.deptId from Depts d");
String label = rs.getMetaData().getColumnLabel(1); // What do you get?
System.out.println("label = " + label);
while (rs.next()){
System.out.println(rs.getInt("d.deptId"));
pass = true;
}
} catch (SQLException e) {
e.printStackTrace();
pass=false;
}
assertTrue(pass);
}
#Test
public void test2(){
boolean pass = false;
try {
ResultSet rs = DbConn.getInstance().doQuery("Select d.deptId from Depts d");
while (rs.next()){
System.out.println(rs.getInt("deptId"));
pass = true;
}
} catch (SQLException e) {
e.printStackTrace();
pass=false;
}
assertTrue(pass);
}
}
public class DbConn {
private static String url = "jdbc:postgresql://server:port/schema";
private static Properties props = new Properties(); {
props.setProperty("user","userid");
props.setProperty("password","passwprd");
}
private Connection conn;
private DbConn(){}
private static DbConn instance;
public static DbConn getInstance() throws SQLException{
if (instance == null){
instance = new DbConn();
instance.conn = DriverManager.getConnection(url, props);
}
return instance;
}
public ResultSet doQuery(String query) throws SQLException{
Logger.log("DbConn.doQuery: " + query);
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
return rs;
}
}
}
The query:
select d.deptId from Depts d
produces a single-column resultset with the result-alias "deptId". There is no "d.deptId" column. If you want one, you can request that as the column alias instead:
select d.deptId AS "d.deptId" from Depts d
PgJDBC can't do anything about this because it has no idea that the resultset column "deptId" is related to the "d.deptId" in the select-list. Teaching it about that would force it to understand way more about the SQL it processes than would be desirable, and lead to maintenance and performance challenges.
The second one works - why isn't that acceptable?
You can also do this:
System.out.println(rs.getInt(1));
If you change the query you have to change the code, too.
I'm using Play framework 1.2.5 and I would like to optimize my SQL queries by creating stored procedures and using them but I don't know how to do.
To create the stored procedure via the Java code how should I do ? Also, should I do it in an #OnApplicationStart job so that I'm sure the procedures are created and stored when the application starts ?
After, how can I use my stored procedures ? Using which function ? How can I pass the parameters to my procedure ? How can I retrieve the result of my procedure ? (generally the result will be a SELECT query) And finally, is it possible to bind the result of my procedure to a model in the play framework ?
I have a lot of questions but I'm new to stored procedures with play framework and JPA and I would like to be sure I'm using them correctly
Thank you for your help
I don't know how you should create them. Perhaps the OnApplicationStart method is what you need. In my environment the procedures are already in place. We just use Play to invoke them. To invoke stored procedures, you should take a look at the Work interface. By implementing this you can execute statements in the database.
We've created a basic OracleProcedure class:
public class CallOracleProcedure implements Work {
private String anonymousPLSQL;
private String[] parameters;
public CallOracleProcedure(String anonymousPLSQL, String[] parameters) {
this.anonymousPLSQL = anonymousPLSQL;
this.parameters = parameters.clone();
}
/**
* Create a JDBC PreparedStatement and then execute the anonymous
* PL/SQL procedure.
*/
#Override
public void execute(Connection connection) {
PreparedStatement statement = null;
try {
statement = connection.prepareStatement("begin " + anonymousPLSQL + "; end;");
if (parameters != null) {
int i = 1;
for (String param : parameters) {
statement.setString(i++, param);
}
}
statement.executeUpdate();
} catch (SQLException e) {
Logger.error("Error performing anonymous pl/sql statement: '%s', with parameters: '%s' - catched error '%s'", anonymousPLSQL, parameters, e);
} finally {
if (statement != null) {
try {
statement.close();
} catch (Exception e) {
Logger.error("Error closing statement: %s", e);
}
}
}
}
}
For each specific stored procedure you can extend this class and pass the name and parameters to the constructor via super():
public class StoredProcedureCall extends CallOracleProcedure {
public StoredProcedureCall(String param) {
super("package.storedprocedure(?)", new String[] { orgname });
}
}
In your code you can then call it like this:
StoredProcedureCall procedure = new StoredProcedureCall("your parameter");
session.doWork(procedure);
If you need to call a procedure and retrieve a return value you can use a CallableStatement in the execute() method:
public class ProcedureWithReturnValue implements Work {
private final String parameter;
private String returnValue = null;
public ProcedureWithReturnValue (final String parameter) {
this.parameter = parameter;
}
#Override
public void execute(Connection connection) {
CallableStatement statement = null;
try {
statement = connection.prepareCall("begin ? := package.procedure(?); end;");
statement.registerOutParameter(1, OracleTypes.VARCHAR);
statement.setString(2, parameter);
statement.execute();
returnValue = statement.getString(1);
} catch (SQLException e) {
Logger.error("Error getting return value - catched error '%s'", e);
}
}
public String getReturnValue() {
return returnValue;
}
}
Take a look at evolutions (http://www.playframework.com/documentation/1.2.7/evolutions) for creating your stored procedures.