Using multiple constructors with ArrayList don't work - java

I was using multiple constructor from the same class, but a few days ago I got a 'rare' problem. The constructor initializes all the fields =(
I have Ejercicio.java class
public class Ejercicios {
int Id_Ejercicio;
String Descripcion;
String Finalidad;
String Duracion;
//Constructor
public Ejercicios() {
super();
}
//Constructor with 2 fields
public Ejercicios(int id_Ejercicio, String descripcion) {
super();
Id_Ejercicio = id_Ejercicio;
Descripcion = descripcion;
}
//Constructor with 4 fields
public Ejercicios(int id_Ejercicio, String descripcion, String finalidad, String duracion) {
super();
Id_Ejercicio = id_Ejercicio;
Descripcion = descripcion;
Finalidad = finalidad;
Duracion = duracion;
}
}
And the Lista_Ejercicios.java class
public class List_Ejercicios {
ArrayList<Ejercicios> lejer;
public List_Ejercicios() {
super();
}
}
And my principal class where I try to use these differents constructors
public Response Principal(SQLQuery){
List<Ejercicios> listaEJER = new ArrayList<Ejercicios>();
dbCon = new ConexionBD();
ResultSet rslt;
try {
conn = (Connection) ConexionBD.setDBConnection();
rslt = dbCon.getResultSet(SQLQuery, conn);
while(rslt.next()){
listaEJER.add(new Ejercicios( rslt.getInt(1),rslt.getString(2) ));
}
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//finally block code
return Response.ok(listaEJER.toArray()).build();
}
I was using 'Advanced Rest Client' for Chrome and I don't have an idea why I receive the 4 fields instead 2 like I especified in the constructor
...
{
descripcion: "Jump as high as you can"
id_Ejercicio: 1
finalidad: null
duracion: null
}
...
I have in trouble, these constructors work two weeks ago I don't have any clue why currently its running doesn't work.

They did not work two weeks ago. You've changed something. When you declare a field in your class, that field is always there. If you don't initialise it in your constructor, it will be auto-initialised. For classes, this default value is null, whereas for primitives it is 0, false etc. However, this behaves exactly the same as if you had initialised it to that value in the constructor - myEjercicios.Finalidad (use naming conventions please) will be null, as it is an auto-initialised object of type String.
As for fixing this issue, it shouldn't be hard to write some code to not print values that are null. If you want a different set of fields, however, you must declare two different classes (perhaps one extending the other).

Related

get all values from one class to anothed class method

I have an class IntegrationWithDB in which i have to method getConnection()and selectFromDB().
In the selectFromDb() i have a result set , i want to get the result
set vales in another class method
Actually it did but it only shows the last value of dataBase table.
Note i have made getter and setter method in IntegrationWithDB class and use in selectFromDB() method.
public void selectFromDB() {
try {
if (this.conn == null) {
this.getConnection();
}
if (this.stmt == null) {
this.stmt = this.conn.createStatement();
}
int success = 0;
this.query = "select * from contacts order by node_id";
this.rs = this.stmt.executeQuery(query);
// something is wrong in the while loop
while (rs.next()) {
setId(rs.getInt("node_id")); // i made getter and setter for id, name, parent and for level
setNam(rs.getString("node_name"));
setParnt(rs.getString("node_parent"));
setLvl(rs.getInt("node_parent"));
}
if (success == 0) {
this.conn.rollback();
} else {
this.conn.commit();
}
} catch (Exception ex) {
ex.printStackTrace();
}
and in another class test i have method displayList() in this method i write the following code
public class test {
IntegrationWithDbClass qaz = new IntegrationWithDbClass();
public void displayList ( ) {
qaz.getConnection();
qaz.selectFromDB();
for(int i = 0; i< 5; i++){
System.out.println(" "+qaz.getId());
System.out.println(" "+qaz.getNam());
}
}
when i initilize the displayList() method in the main method , it shows the following result
5
red
how can i get all the five values?
First of all you have to create what is commonly referred to as an Entity class. This is the class that represents a single row in your database. This should ideally be separate from the code that interacts with the database connection.
So first step, create a class named Contact, and in it put the 4 fields you have, id, name, parent and level, with the respective getter methods. If you do not expect these to change by your program make them immutable, it is the good practice to ensure consistency. So something like:
public class Contact {
private final int id;
private final String name;
private final String parent;
private final String level;
public Contact(String id, String name, String parent, String level) {
this.id = id;
this.name = name;
this.parent = parent;
this.level = level;
}
public int getId() {
return id;
}
//... put the rest of the getter methods
}
Then in your IntegrationWithDB class (I would rename this to something more meaningful like ContactRepository) you can change that method you have to:
public List<Contact> getContacts() {
// ... your database connection and query code here
this.rs = this.stmt.executeQuery(query);
List<Contact> contacts = new LinkedList<Contact>();
while (rs.next()) {
int id = rs.getInt("node_id");
String name = rs.getString("node_name");
String parent = rs.getString("node_parent");
String level = setLvl(rs.getInt("level"));
contacts.add(new Contact(id, name, parent, level));
}
//... the rest of your database handling code, don't forget to close the connection
return contacts;
}
Then from displayList() you just have to call getContacts() which gives you a list of Contact objects to iterate through.
I assume that currently you're storing those properties in int/string variables. In every iteration of the loop you're overwriting the values. What you need to do is to store them in some collection like ArrayList and in each iteration add() to this collection.

Proper Constructors to Run all Methods in Java

I have this class and need to know which constructor is needed to create an object that may immediately use all its methods without error
public class Robot {
private boolean fuelEmpty = true;
private int roboID;
private String greeting;
private String securityProtocol;
//insert robot constructor here
public void destroyAllHumans(){
while (fuelEmpty == false) {
//robot begins to destroy all humans
}
}
public int getRoboID(){
return roboID;
}
public void greet(){
System.out.println(greeting);
}
public void setSecurityProtocol(String proto){
securityProtocol = proto;
}
}
For example should look like this:
public Robot(int id, String greet) {
roboID = id;
greeting = greet;
}
or this:
public Robot(int id, String greet) {
roboID = id;
greeting = greet;
fuelEmpty = false;
}
or:
public Robot(boolean full, int id, String greet, String proto) {
roboID = id;
greeting = greet;
fuelEmpty = full;
securityProtocol = proto;
}
Which of these (or something else different) is needed so that all the other methods can run without an error?
You can overload the constructor as much as you need, the important thing is
the object gets properly instantiated after you create a new one...
a way can be:
public Robot() {
this(false, 0, "", "");
}
public Robot(int id) {
this(false, id, "", "");
}
public Robot(boolean fuelEmpty, int roboID, String greeting, String securityProtocol) {
this.fuelEmpty = fuelEmpty;
this.roboID = roboID;
this.greeting = greeting;
this.securityProtocol = securityProtocol;
}
so look how all other constructors will at the end call internally the
public Robot(boolean fuelEmpty, int roboID, String greeting, String securityProtocol)
that will give you the waranty that no matter which constructor is invoked, the Robot is fully created and can invoke all those methods without crashing
The solution works like this:
you look at each of your methods
you check which fields each method is using
you check more closely, if the method breaks when that field has its default value (like null for Objects, or false for booleans)
When you do that for all methods, you get a list of those fields that you need to initialize somehow. Then you could go forward and define a corresponding constructor.
But of course, that is the wrong approach.
The real answer goes like this: you don't put fields into a class because you can. You add them because they are required so that this class can implement the requirements (responsibilities) that you want it to implement. Meaning: you focus on the methods that your class should provide. Then you clarify which fields you need in order to implement these methods.
In other words: you have exactly those fields in your class that your class needs. If you have fields in there that go unused - then you get rid of them.

Map query results to POJO constructor in Java

I have a set of SQL queries and a corresponding POJO object with a constructor.
Ex.
Student student = new Student(rs.getString("FNAME"), rs.getString("LNAME"), rs.getString("GRADE"));
Currently I'm mapping the column in result set to a field manually. I would like to make this generic so I can do something like new Student(rs.getRow()) and then I can map it via some kind of configuration file. There could be N number of fields in select query and order doesn't necessarily match with order defined in the constructor.
I would like to have control over the SQL since it could have lot of joins so I am not sure if an ORM would work here. I strictly want something that could map the resultset columns to a field.
I would like to add annotations in my Student class for mapping
public class StudentRowMapper implements RowMapper<YourStudentPojo> {
#Override
public YourStudentPojo mapRow(final ResultSet rs, final int arg1) throws SQLException {
final YourStudentPojo item = new YourStudentPojo();
item.setFName(rs.getString("FNAME"));
return item;
}
Similar to this FName, you can set the other values in your pojo. No need for constructor. Just if you make changes in Pojo then corresponding changes must be done in this method.
This does seem like a textbook example of a place to use JPA or a similar ORM technology.
However, if you are set on just doing this with annotations, you can create your own annotations - http://www.mkyong.com/java/java-custom-annotations-example/ is a pretty good tutorial on doing so.
You'd create your own #DatabaseField annotation that you'd annotate the fields of the object with, specifying the corresponding Database field. You'd then, in the constructor, take your class (Class klass = this.getClass()), get the declared fields on it (klass.getDeclaredFields()), and for each of those, look at the declared annotations (field.getDeclaredAnnotations()). For each of those, if they are your custom databasefield annotation, make a note of the mapping. Once you have gone through all fields, you'll have a map of fields to database columns, which you can then go ahead and set using reflection (the Field object you have has a set method on it, you'll call that with "this" (the object being constructed) and the value you got with the result set.
Might be an interesting exercise, but I still think you'd be better off with JPA or one of the lighter weight ORMs like SimpleORM.
You can do with java reflection .
For example we will take your sql query is like this.
SELECT FirstName 'FNAME', LastName 'LNAME', Grade 'GRADE' FROM Employee
So you will get the output as the following
FNAME LNAME GRADE
John Dan A+
Then in your java code you will need to reflection to achieve the rest
Suppose your Student class is like this
public class Student {
private String LNAME;
private String FNAME;
private String GRADE;
public String getLNAME() {
return LNAME;
}
public void setLNAME(String lNAME) {
LNAME = lNAME;
}
public String getFNAME() {
return FNAME;
}
public void setFNAME(String fNAME) {
FNAME = fNAME;
}
public String getGRADE() {
return GRADE;
}
public void setGRADE(String gRADE) {
GRADE = gRADE;
} }
And you can set the corresponding values in the Student class using the following code.
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
try {
//configuring the columns in the sql statement and class
String[] ColumnArray = new String[]{"LNAME","FNAME","GRADE"};
// making a hashmap to emulate the result set of sql
HashMap<String, String> rs = new HashMap<String, String>();
rs.put("FNAME", "John");
rs.put("LNAME", "Dan");
rs.put("GRADE", "A+");
//reflection of the
Class cls = Class.forName("Student");
Object c = cls.newInstance();
Method[] mtd = cls.getMethods();
for (String column : ColumnArray) {
Method method = cls.getMethod("set"+column, String.class);
method.invoke(c, new Object[]{rs.get(column)});
}
//casting the class to employee
Student student = (Student) c;
//Printing the output
System.out.println(student.getFNAME());
System.out.println(student.getLNAME());
System.out.println(student.getGRADE());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}}
Please let me know if your facing any issue. Happy to help you.
It's not perfect but look at this:
public class Student {
private String name;
private Integer age;
//etc.
public Student() {
//default constructor
}
public Student(final ResultSet rs) throws Exception {
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
for (int i = 1; i < columnCount + 1; i++ ) {
String name = rsmd.getColumnName(i);
if (Student.getField(name)) {
Student.getField(name).set(rs.getString(name));
}
}
}
}
You should also map field to colum type, in example I used only getString.
If result of your query going to be some domain object like Student (nevermind how many joins in FROM statement) then ORM would work fine and maybe it's good solution. If you are going to extract some complex data structure then you can take a look at some Spring features like RowMapper.
You can make use of GSON serialized object mapping.
refer
Check with HIbernate SQLQuery addScalar() Example here http://www.journaldev.com/3422/hibernate-native-sql-example-addscalar-addentity-addjoin-parameter-example
This will exactly give total result-set as POJO object. You can later iterate through it for data.
Let me know if this helps you.
Assume your STUDENT table is as follows.
__________________________
|STUDENT_ID | AGE | NAME |
--------------------------
| | | |
| | | |
--------------------------
Your have to have a control over your SQL query. It's return columns must be renamed according to POJO class's variable names. So the SQL query would be like as follows.
SELECT AGE AS age, NAME AS name from STUDENT;
Finally, the POJO class's constructor is as follows. It will iterate through all the private variables inside the class, and check whether those columns are available in the ResultSet.
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.ResultSet;
public class Student
{
private int age;
private String name;
public int getAge()
{
return age;
}
public void setAge( int age )
{
this.age = age;
}
public String getName()
{
return name;
}
public void setName( String name )
{
this.name = name;
}
public static void main( String[] args )
{
new Student( null );
}
public Student( ResultSet rs )
{
Field[] allFields = this.getClass().getDeclaredFields();
for ( Field field : allFields )
{
if ( Modifier.isPrivate( field.getModifiers() ) )
{
String fieldName = field.getName();
String methodName = "set" + fieldName.substring( 0, 1 ).toUpperCase() + fieldName.substring( 1 );
try
{
Method setterMethod = this.getClass().getMethod( methodName, field.getType() );
setterMethod.invoke( this, rs.getObject( fieldName ) );
}
catch ( Exception e )
{
e.printStackTrace();
}
}
}
}
}

Handling Queries for Multiple Tables

I am working on a project that utilizes a database with several relations. We are working with tables such as:
Customers(id, f_name, l_name)
CreditCards(cardNum, expDate, securityCode)
BillingInfo(id, f_name, l_name, address, city, zip)
etc...
Using Java Database Connectivity, my question is, is there a common way one performs queries on these relations?
Even before getting to the "guts" of this project, I envision being able to call some method void insert(int id, String f_name, String l_name), a member method of a hypothetical CustomerQueryHandler class. This class would of course be accompanied by other methods such as a delete and update method.
I figured I'd start with an abstract class called QueryHandler:
import java.sql.*;
public abstract class QueryHandler {
protected String jdbcUrl = null;
protected String userid = null;
protected String password = null;
protected Connection conn;
QueryHandler(String url_in, String id_in, String pass_in) {
this.jdbcUrl = url_in;
this.userid = id_in;
this.password = pass_in;
try {
this.ds = new OracleDataSource();
} catch (SQLException e) {
e.printStackTrace();
}
ds.setURL(this.jdbcUrl);
try {
conn = ds.getConnection(userid, password);
} catch (SQLException e) {
e.printStackTrace();
}
}
public abstract void insert(/*not sure of signature*/);
public abstract void update(/*not sure of signature*/);
public abstract void delete(/*not sure of signature*/);
/* OTHER METHODS BELOW */
}
There would be a derived class for each table and each derived class would implement its own version of insert, update, and delete:
public class CustomersQueryHandler extends QueryHandler {
public CustomersQueryHandler(String url_in, String id_in, String pass_in) {
super(String url_in, String id_in, String pass_in);
}
...
This is actually the point where I became very confused because, does it make sense for this to be a superclass, even though each subclass will have its own parameter list for the aforementioned methods?

Populate a table by using Single pattern in Java

I have created following singleton design pattern in my java program
private int OwnerId;
private String OwnerName;
private String OwnerNic;
private String OwnerAddress;
private int OwnerTele;
private String OwnerEmail;
private String OwnerDate;
private static OwnerML instance = new OwnerML();
// make the coosntructor private so that this class cannot be instantiated
private OwnerML(){}
// get the only object available
public static OwnerML getInstance() {
return instance;
}
public int getOwnerId() {
return OwnerId;
}
public void setOwnerId(int OwnerId) {
this.OwnerId = OwnerId;
}
I have used a separate method to call the view method
public ArrayList<OwnerML> SelectOwnerData()
{
ArrayList<OwnerML> OwnerList = new ArrayList<OwnerML>();
try {
Connection con = DB.connect();
String selectQ = "select * from owners";
PreparedStatement ps2 = con.prepareStatement(selectQ);
ResultSet rs = ps2.executeQuery();
while (rs.next())
{
OwnerML OwnerData =OwnerML.getInstance();
OwnerData.setOwnerId(rs.getInt(1));
OwnerData.setOwnerName(rs.getString(2));
OwnerData.setOwnerNic(rs.getString(3));
OwnerData.setOwnerAddress(rs.getString(4));
OwnerData.setOwnerTele(rs.getInt(5));
OwnerData.setOwnerEmail(rs.getString(6));
OwnerList.add(OwnerData);
}
rs.close();
ps2.close();
con.close();
By using following method I'm calling it in my interface
ArrayList<OwnerML> ownerList = new OwnerCL().SelectOwnerData();
Object obj[][] = new Object[ownerList.size()][6];
int x = 0;
for (OwnerML t : ownerList) {
obj[x][0] = t.getOwnerId();
obj[x][1] = t.getOwnerName();
obj[x][2] = t.getOwnerNic();
obj[x][3] = t.getOwnerAddress();
obj[x][4] = t.getOwnerTele();
obj[x][5] = t.getOwnerEmail();
x++;
}
ownerTbl.setModel(new javax.swing.table.DefaultTableModel(obj,new Object[]{
"OwneID", "Name", "Nic", "Address", "Tele", "Email", "Date", "VehicleID", "Type", "Model", "Year", "RegNumber"
}));
The problem I am facing at the moment is that it always repeats the data in the last row.
I would be very thankful if anyone could help me with this.
There is one mayor flaw in your design.
I guess OwnerML class is supposed to be the container for the data. It does not make sense to implement it as a Singleton.
Every time you call OwnerML.getInstance() while populating the OwnerList list with results from the database, you are referencing the same class' instance (it's the very nature of Singleton).
As a result you will always have a list with multiple references to the same object (singleton).
You should forget about using Singleton as a data container (let's call it Data Transfer Object - DTO).
In fact Singleton is rarely useful for anything (notably exceptions are: logging subsystem, handler of singular hardware resource, and maybe Spring-ish bean factory).
In short:
make the OwnerML constructor public and then replace
OwnerML OwnerData =OwnerML.getInstance();
with
OwnerML OwnerData = new OwnerML();
===EDIT===
#Anton 's comment was first, and he's right. I should type faster next time :)

Categories

Resources