Java - String NullPointerException - java

I'm making a mysql database connector with java to show all the data.
When I run the code, I get an NullPointerException in my getData() function.
here is my code.
public String[][] getData() {
String values[][];
try {
rs = st.executeQuery("SELECT * FROM adresses");
int i = 0;
while(rs.next()) {
String id = rs.getString("id");
String name = rs.getString("name");
String adress = rs.getString("email_adress");
String catagory = rs.getString("catarogy");
values[i][0] = id;
values[i][1] = name;
values[i][2] = adress;
values[i][3] = catagory;
i++;
}
return values;
} catch (SQLException e) {
e.printStackTrace();
return values;
}
}
When the value of the String values is nothing I get The error. But if I give the String allready a value it says nothing .
public String[][] getData() {
String values[][] = {{"","","",""},
{"","","",""},
{"","","",""},};
try {
rs = st.executeQuery("SELECT * FROM adresses");
int i = 0;
while(rs.next()) {
String id = rs.getString("id");
String name = rs.getString("name");
String adress = rs.getString("email_adress");
String catagory = rs.getString("catarogy");
values[i][0] = id;
values[i][1] = name;
values[i][2] = adress;
values[i][3] = catagory;
i++;
}
return values;
} catch (SQLException e) {
e.printStackTrace();
return values;
}
}
I want more data than that in my data String. how can I let it automatically do that??
Tnx.
PS.
The function is called in my class FrameGUI and has to change to Object
public class FrameGUI extends JFrame {
public JTable dataHolder;
Mysql mysql = new Mysql();
public String[] columnNames = {
"ID", "Name", "Adress", "Catagory"
};
-> public Object[][] data = mysql.getData();
public FrameGUI() {
init();
mysql.getData();
}
}

You do not initialize String values[][] so it is null. You either need to initialize it first or use a more appropriate datastructure like a List.

You should define a class and use a List (e.g. the ArrayList) instead.
e.g. if you want to call it User -
public class User {
private String id;
private String name;
//...
}
and a list
List<User> users = new ArrayList<User>();
and then instantiate the User class for each row and add the new instance to the list -
User currUser = new User();
users.add(currUser);
//set values from result set
The list can grow automatically when needed and the code is much more readable than using the array.

You get an index out of bounds in the first example because a String[][] (or String Matrix) gets initialized as a zero-length array.
In the second instance, you initialized the array to a size of 3x4 - that works so long as you only get 3 results back.
What you really need is a data structure with a dynamic size. Arrays aren't automatically sized dynamically. Try using a collection implementation like ArrayList or LinkedList or Vector.
Also, instead of saving your values to a String[], try creating a bean class that can hold your result. Create a new instance of it for each result that you get back instead of initializing a new array.

Because you didn't initialized your array, that is why you get NPE. Actually I suggest you to use List for your purposes:
public ArrayList<ArrayList<String>> getData() {
ArrayList<ArrayList<String>> values = new ArrayList<>();
try {
rs = st.executeQuery("SELECT * FROM adresses");
while(rs.next()) {
String id = rs.getString("id");
String name = rs.getString("name");
String adress = rs.getString("email_adress");
String catagory = rs.getString("catarogy");
ArrayList<String> list = new ArrayList<>();
list.add(id);
list.add(name);
list.add(adress);
list.add(catagory);
values.add(list);
}
return values;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}

The main problem in you code is you are using arrays to save variable number of data. Arrays is fixed sized after they are created so you can't add (or remove) elements to them dynamically.
Instead of using arrays you should use an ArrayList object which have methods to add more elements. Also instead of creating a multidimensional array it looks like a better idea to create a class for the data you get from you database.
So lets first create a Address class:
public class Address {
public String id, name, adress, catagory;
public Address(String id, String name, String adress, String catagory) {
this.id = id;
this.name = name;
this.adress = adress;
this.catagory = catagory;
}
}
Now you can write you code as:
public List<Address> getData() {
List<Address> values = new ArrayList<Address>();
try {
rs = st.executeQuery("SELECT * FROM adresses");
int i = 0;
while(rs.next()) {
String id = rs.getString("id");
String name = rs.getString("name");
String adress = rs.getString("email_adress");
String catagory = rs.getString("catarogy");
values.add(new Address(id, name, adress, catagory));
}
return values;
} catch (SQLException e) {
e.printStackTrace();
return values;
}
}
The returned list will contain a list of Address objects which have the values from you database. Also, the size of the list is always the same as the content you put into it.

Related

How to insert from an extended class

My information is read in via CSV for "banking information", A person CSV is
5
1,Tony,Stark,C,tonys,naslvj34-t934,stark#hmmm.org;tony#gmail.com;tostark55#yaho.com
2,Patrick,Hart,C,phart2,sdlwgl5034i52,hart#hmmm.org;hart1#who.org
3,Tom,Baker,E,bake95,kweojtnefq567,
4,Kevin,Black,C,keb765,prjhohier99,black#mail.org
5,Alex,Codd,E,alcodd,andlqjr78,codd#DBMS.org;alex#gmail.com
my Account CSV is,
5
1,313001,S,35881.12
2,313002,G,772400.34
3,313003,C,250002.15
4,313004,P,96310.66
5,313005,P,15624.15
1,313006,C,39950.99
In the Account CSV the 2nd token is My "Account type", so S = "Savings" G = "Gold Savings" C = "Checkings" and so on. When reading these in my CSV parser class, an object was made of the types, so A Checking class was made and when the CSV was tokenized when token[2] was equal to "C".
My Persons class is set up as so, excluding my getters and setters
private int personId;
private String firstName;
private String lastName;
private String type;
private String usrname;
private String password;
private ArrayList<String> emails;
public Person(int personId, String firstName, String lastName, String type, String usrname, String password,
ArrayList<String> emails) {
super();
And my Account class is set up as so.
private Person accountHolder;
private int accountNumber;
private double currentBalance;
public Account() {}
public Account(Person accountHolder, int accountNumber, double currentBalance) {
this.accountHolder = accountHolder;
this.accountNumber = accountNumber;
this.currentBalance = currentBalance;
}
This is one of my example account types (there are multiple)
public class CheckingAccount extends Account {
public CheckingAccount(Person p, int i, double d) {
super(p,i, d);
}
This is my database adder
public static void DbAddAccount(Person personId, Account accountHolder){
Connection conn = null;
try {
conn = DriverManager.getConnection(DatabaseInfo.URL, DatabaseInfo.USERNAME, DatabaseInfo.PASSWORD);
} catch (SQLException e) {
System.out.println("Connection Failed");
throw new RuntimeException(e);
}
String accountQuery = "insert into Account (accountId,accountNumber,currentBalance,type,personId) values (?,?,?,?,?);";
PreparedStatement accountPs = null;
ResultSet accountKeys = null;
int accountId = 0;
try {
//These are my prepare Statements for my queries
accountPs = conn.prepareStatement(accountQuery);
accountPs.setInt(1, accountId+ 1 );
accountPs.setInt(2, accountHolder.getAccountNumber());
accountPs.setDouble(3, accountHolder.getCurrentBalance());
accountPs.setString(4, ??????????????????????????????????);
accountPs.setInt(5, personId.getPersonId());
accountPs.executeUpdate();
accountPs.close();
conn.close();
}
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
JDBC is not adding anything when running.
I think your code has following issues:
Account Object:
Object is missing field to store "Account Type"
Setting incorrect account type in DbAddAccount method
At line accountPs.setString(4, ??????????????????????????????????);
you are number of question marks (without enclosing in quote to make string) as account type which appears it is not correct.
series of ??? wont get converted to string without enclosed in quotes.
Even if you enclose in quotes, I think it wont be intended account number;
Solution
for Issue 1; declare account_type in Account Object.
for issue 2; instead of using accountPs.setString(4, ??????????????????????????????????);
use:
accountPs.setString(4, account.getAccountType());

java ArrayList with two columns

I have to update a table with two columns and I have created a class
public class Country {
private String url;
private String search;
public Country(String url, String search) {
this.url = url;
this.search = search;
}
// ...
}
List<Country> countries = new ArrayList<Country>();
countries.add(new Country(urls, txt));
...
Countries has a data {java.com.main#yfxse34567}
Could be {www.google.com, main string...}
How can I put a proper data into countries list
Override the toString() method
Example
List<Country> countries = new ArrayList<Country>() {
#Override
public String toString() {
String result = "{";
for (int index= 0; index < size(); index++){
result = result.concat(this.get(index).url);
if (index != size()-1) {
result = result.concat(", ");
}
}
result = result.concat("}");
return result;
}
};
For me your solution should work, however try to instantiate the parent first and then add the instance ... Something like
Country instanceCountry = new Country();
instanceCountry.setUrl("www.google.com");
instanceCountry.setSearch("xpto");
countries.add(instanceCountry);
Do not forget to generate the Getters and Setters

Why toString method won't get the selected item in JComboBox?

I bind my values from database to JComboBox using ArrayList and converted each array using StringBuilder because StringBuilder accepts any data types so I think this is the most efficient way.
while(rs.next())
{
departmentId = rs.getInt(1);
departmentTypeList = rs.getString(2);
ArrayList<DepartmentList> listDepartment = new ArrayList<DepartmentList>();
listDepartment.add(new DepartmentList(departmentId,departmentTypeList));
StringBuilder builder = new StringBuilder();
for(DepartmentList s : listDepartment)
{
builder.append(s);
}
cbDepartmentType.addItem(builder.toString());
}
private class DepartmentList
{
private int id;
private String department;
private DepartmentList(int id,String department)
{
this.id = id;
this.department = department;
}
private int getId()
{
return id;
}
#Override
public String toString() //Converting to String the (departmentId,departmentTypeList)
{
return department;
}
}
I added a listener on my JComboBox to listen what item is selected. I already converted my class to Object but when I click the JComboBox it gives me a exception java.lang.String Any ways to solve this problem?
if(e.getSource() == cbDepartmentType)
{
DepartmentList item = (DepartmentList) cbDepartmentType.getSelectedItem();
System.out.println("id "+(item.getId()));
}
StackTrace:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.String cannot be cast to position.AddPosition$DepartmentList
at position.AddPosition$ItemHandler.actionPerformed(AddPosition.java:295)
at javax.swing.JComboBox.fireActionEvent(JComboBox.java:1258)
at javax.swing.JComboBox.setSelectedItem(JComboBox.java:586)
at javax.swing.JComboBox.setSelectedIndex(JComboBox.java:622)
Update:
while(rs.next())
{
departmentId = rs.getInt(1);
departmentTypeList = rs.getString(2);
ArrayList<DepartmentList> listDepartment = new ArrayList<DepartmentList>();
listDepartment.add(new DepartmentList(departmentId,departmentTypeList));
cbDepartmentType.addItem(listDepartment.toString());
}
You are adding String to the Combobox
cbDepartmentType.addItem(builder.toString());
And you try to cast the selected item into a DepartementList
DepartmentList item = (DepartmentList) cbDepartmentType.getSelectedItem();
But you get a String. So something like this is try to run.
DepartmentList item = (DepartmentList) "A string";
You can add DepartmentList to the comboxbox directly.
cbDepartmentType.addItem(departement);
This will use the implementation of toString() of DepartementList to print the text in the component.
With this, the selectedItem will be an instance of DepartementList.
Here is the official tutorial of How to use Combo Boxes
EDIT :
Your code should look like :
while(rs.next())
{
departmentId = rs.getInt(1);
departmentTypeList = rs.getString(2);
DepartmentList dep = new DepartmentList(departmentId,departmentTypeList); //Create a department
cbDepartmentType.addItem(dep ); //insert into the combo
}
In your original code, you were using a List to store the instance then recover this instance to parse it into a StringBuilder then insert this represention (a String) into the combobox.
My logic
Department -> Combobox
Yours
List > Departemnt > StringBuilder > Combobox
Try to understand the while loop you had, you will see this was not logic at all.

removing duplicate records in list

Hi while developing one of my web application i am storing the user information in to an ArrayList based on sql query executed, it contain duplicate objects how to remove duplicate objects in list , i already tried some method but it still not working.
This Is My Code Correct me where i am wrong
public ArrayList loadData() throws ClassNotFoundException, SQLException {
ArrayList userList = new ArrayList();
String url = "";
String dbName = "";
String userName = "";
String password = "";
Connection con = null;
Class.forName("org.apache.derby.jdbc.ClientDriver");
con = DriverManager.getConnection(url + dbName, userName, password);
PreparedStatement ps = null;
try {
String name;
String fatherName;
int Id;
String filePath;
int age;
String address;
String query = "SELECT NAME,FATHERNAME,AGE,ADDRESS,ID,FILEPATH FROM USER_INFORMATION ,USER_PHOTO WHERE ID=USER_ID";
ps = con.prepareStatement(query);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
name = rs.getString(1);
fatherName = rs.getString(2);
age = rs.getInt(3);
address = rs.getString(4);
Id = rs.getInt(5);
filePath=rs.getString(6);
/* if(flag)
{
prev=Id;
flag=false;
}
else if(Id==prev)
{
TEMP=TEMP+";"+filePath;
}*/
//PhotoList = PhotoList(Id, con);
UserData list = new UserData();
list.setName(name);
list.setFatherName(fatherName);
list.setAge(age);
list.setAddress(address);
list.setId(Id);
// list.setFilePath(filePath);
userList.add(list);
}
ps.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
ArrayList al = new ArrayList();
HashSet hs = new HashSet();
hs.addAll(userList);
al.clear();
al.addAll(hs);
return al;
}
And My Bean Class contant is
public class UserData {
private String name;
private String fatherName;
private int Id;
//private String filePath;
private int age;
private String address;
public UserData()
{
}
public UserData(String name, String fatherName,int Id, int age,String address)
{
this.name = name;
this.fatherName = fatherName;
this.Id = Id;
//this.filePath=filePath;
this.age=age;
this.address=address;
}
//GETTER AND SETTER..
General Idea: Use Set, not List. But you must override hash and equals of the class.
If you want a Collection of objects that does not have a specific order and you don't want duplicates, it's better for you just to use a Set like for example HashSet, or, if in your set the order is important, the TreeSet.
Just remember to override the hash and equals methods.
if you add this to your bean everything should work:
public int hashCode() {
return (name + fatherName+ Id + filePath + age + address).hashCode();
}
public boolean equals(Object obj) {
return ( hashCode() == obj.hashCode() );
}
Your userdata class does not implement equals or hashcode. This means two instances created with the same values will not be counted as duplicates. This is why the set contains duplicates.
For example
UserData u1 = new UserData("Foo", "bar",1, 1,"baz");
UserData u2 = new UserData("Foo", "bar",1, 1,"baz");
u1 and u2 are not considered equal as they are different objects. Adding an equals and hashcode method should fix this. However even better is adarshr's idea of removing dupes in the SQL.
All duplicates must be removed at an SQL level. Your SQL is suggesting that it could be generating duplicate records.
String query = "SELECT NAME,FATHERNAME,AGE,ADDRESS,ID,FILEPATH FROM USER_INFORMATION ,USER_PHOTO WHERE ID=USER_ID";
What does the clause ID = USER_ID mean? Shouldn't you be passing in that value as an input to your query?
Also, is the column ID a primary key? Otherwise, use a where clause that doesn't generate duplicates.

newbie attempt to use Java ArrayList to store ResultSet obtained from database

I have a database server communicating with a Java application server using JDBC. I want to store data from the database ResultSet into Java variables.
Here's my Java class, HRPeople:
public class HRPeople {
public int elements;
public String[] FirstName;
public String[] LastName;
public String[] Email;
public int[] Salary;
}
I currently use this class to store data from ResultSet, as follows:
query = "SELECT first_name, last_name, email, salary FROM HR.Employees where rownum < 6";
rset = stmt.executeQuery(query);
while (rset.next()) {
returnHRdata.FirstName[ii] = rset.getString("first_name");
returnHRdata.LastName[ii] = rset.getString("last_name");
returnHRdata.Email[ii] = rset.getString("email");
returnHRdata.Salary[ii] = rset.getInt("salary");
ii = ii + 1;
}
The problem with the above scenario is that the primitive arrays require me to know the number of rows in the ResultSet so that I can properly initialize those arrays. So what I want to do is use an ArrayList instead. How would I modify the above scenario to do this?
Here's my initial attempt (is this close)? Is HRPeople.java file shown above even used in this scenario?
query = "SELECT first_name, last_name, email, salary FROM HR.Employees where rownum < 6";
rset = stmt.executeQuery(query);
List<HRPeople> returnHRdata = new ArrayList<HRPeople>();
while (rset.next()) {
returnHRdata.FirstName = rset.getString("first_name");
returnHRdata.LastName = rset.getString("last_name");
returnHRdata.Email = rset.getString("email");
returnHRdata.Salary = rset.getInt("salary");
returnHRdata.add;
}
UPDATE 1:
If I add to the code the following,
return returnHRdata;
I get the following error (any idea why?):
myClass.java:213: incompatible types
found : java.util.List<HRPerson>
required: java.util.ArrayList<HRPerson>
return returnHRdata;
^
1 error
You probably want to first define an HRPerson like this:
public class HRPerson {
public String firstName;
public String lastName;
public String email;
public int salary;
}
Then your main code would look like:
query = "SELECT first_name, last_name, email, salary FROM HR.Employees where rownum < 6";
rset = stmt.executeQuery(query);
List<HRPerson> returnHRdata = new ArrayList<HRPerson>();
while (rset.next()) {
HRPerson person = new HRPerson();
person.firstName = rset.getString("first_name");
person.lastName = rset.getString("last_name");
person.email = rset.getString("email");
person.salary = rset.getInt("salary");
returnHRdata.add(person);
}
List<HRPeople> returnHRdata = new ArrayList<HRPeople>();
while (rset.next()) {
HRPeople people = new HRPeople();
people.FirstName = rset.getString("first_name");
people.LastName = rset.getString("last_name");
people.Email = rset.getString("email");
people.Salary = rset.getInt("salary");
returnHRdata.add(people);
}
You can improve this code by using a lowerCase letter for your first char of your fields and using getters and setters to access them.
Convert this:
public class HRPeople {
public int elements;
public String[] FirstName;
public String[] LastName;
public String[] Email;
public int[] Salary;
}
to:
public class HRPerson {
public String firstName;
public String lastName;
public String email;
public int salary;
}
and:
List<HRPerson> people = new ArrayList<HRPerson>();
Now it should be easy:
while (rset.next()) {
HRPerson person = new HRPerson();
returnHRdata.firstName = rset.getString("first_name");
returnHRdata.lastName = rset.getString("last_name");
returnHRdata.email = rset.getString("email");
returnHRdata.salary = rset.getInt("salary");
people.add(person);
}
Close...
while (rset.next()) {
HRPeople person = new HRPeople();
person.setFirstName(rset.getString("first_name"));
person.setLastName(rset.getString("last_name"));
person.setEmail(rset.getString("email"));
person.setSalary(rset.getInt("salary"));
returnHRdata.add(person);
}
You of course must define the setXXXX methods on the HRPerson class. Oh yeah, and do what Thomasz suggested.
create a class HRPeople, which has firstname, lastname.... attributes, and declare getter, setters method.
then:
List<HRPeople> returnHRdata = new ArrayList<HRPeople>();
HRPeople people = null;
while (rset.next()) {
people = new HRPeople();
people.setFirstName( rset.getString("first_name"));
people.setLastName (rset.getString("last_name"));
...
returnHRdata.add(people);
}
Instead of storing an array of each property in your object, make a single object to describe a given entity in the table.
class HRPerson {
String firstName;
String lastName;
String email;
Integer salary;
}
Create a list of this type, allowing you to store the results.
List<HRPerson> hrPeople = new ArrayList<HRPerson>();
while(rset.next()) {
HRPerson person = new HRPerson();
person.firstName = rset.getString("first_name");
person.lastName = rset.getString("last_name");
person.email = rset.getString("email");
person.salary = rset.getInt("salary");
hrPeople.add(person);
}
Finally, fill it by creating new objects for each row in your table.

Categories