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 :)
Related
Hello is there a possibility to pass all nulls to constructor and have correctly new object created?
Lets say I have such class:
public class MobileDataReportSearchCriteria extends BaseSearchCriteria<MobileDataReport> {
private Date reportDateFrom;
private Date reportDateTo;
private long opponentStationId;
private boolean correctness;
public MobileDataReportSearchCriteria() {
}
public MobileDataReportSearchCriteria(Date reportDateFrom, Date reportDateTo, long opponentStationId, boolean correctness) {
this.reportDateFrom = reportDateFrom;
this.reportDateTo = reportDateTo;
this.opponentStationId = opponentStationId;
this.correctness = correctness;
}
}
and now I want to instantiate new object of this class with new MobileDataReportSearchCriteria(null, null, null, null); because those objects in business logic could be nulls. How to do that because when I do that I get NullPointerException. Thank you in advance!
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.
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).
I'm using ORMLite, trying to use the ForeignCollectionKey but I got the following error :
Internal DAO object is null. LazyCollections cannot be used if they have been deserialized.
I've my object named Zone :
public class Zone implements Serializable {
private static final long serialVersionUID = 1L;
public static final String ZONE_ID = "id";
public static final String ZONE_PARENT_ID = "parentZoneId";
#DatabaseField(generatedId=true)
private int id;
#DatabaseField()
String name;
#DatabaseField(foreign=true, foreignAutoRefresh = true)
Zone parentZone;
#ForeignCollectionField(foreignFieldName = "parentZone", eager = true)
private ForeignCollection<Zone> zoneChild;
public Zone() {
// TODO Auto-generated constructor stub
}
public ForeignCollection<Zone> getZoneChild() {
return zoneChild;
}
public void setZoneChild(ForeignCollection<Zone> zoneChild) {
this.zoneChild = zoneChild;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
In a class i'm doing a recursive method to get all my zone child objects :
public void getZone(Zone zone, Dao<Zone, Integer> tempZoneDao){
ZoneListEntity zoneEntity = new ZoneListEntity();
zoneEntity.setName(zone.getName());
zoneEntity.setNiveau(0);
zoneEntity.setZone(zone);
mainZoneList.add(zoneEntity);
List<Zone> childList = new ArrayList<Zone>(zone.getZoneChild());
//set rootZone's children as ZoneListEntity
for(Zone currentZone : childList){
ZoneListEntity zoneGroup = new ZoneListEntity();
zoneGroup.setName(currentZone.getName());
zoneGroup.setZone(currentZone);
System.out.println("Zone : "+currentZone.getName());
getZone(currentZone, tempZoneDao);
}
}
When i'm entering for the first time in my getZone, everything going well. Then when I loop in getZone the application crashes trying to access to the child zone :
List<Zone> childList = new ArrayList<Zone>(zone.getZoneChild());
Do you have any ideas ? Is my model construction right ?
Thanks
Do you have any ideas ? Is my model construction right ? Thanks
So the exception message is trying to explain what is going on. I'm not sure how it can be improved.
Internal DAO object is null. LazyCollections cannot be used if they have been deserialized.
You are trying to access zoneChild which is a ForeignCollection that has been deserialized. Since it has been deserialized all of the underlying database configurations and connections could not be reestablished. I guess this can happen when it stored in an Android Bundle? I'm not sure if this is the only case.
If you need to get the Zone children you are going to have to either call dao.refresh() on the entity after you deserialize it or do the query yourself by doing the zoneDao.
I solved this problem like Gray suggested: pass the primary key attribute in the Bundle and then obtain the object again from the database in the destination Activity:
Example:
Let's suppose I want to pass a Person object and that I've declared Person.name as:
#DatabaseField (columnName ="name")
private String name;
Then:
ActivityA
Intent intent = new Intent(ActivityA.this, ActivityB.class);
Bundle bundle = new Bundle();
bundle.putString("NAME" Person.getName());
intent.putExtras(bundle);
ActivityB
String name = getIntent().getExtras().getString("NAME"));
Person p = getHelper().getPersonDao().queryForEq("name", name);
And there you are, your Collection will be refreshed.
I am implementing a webservice witch is used to attack one DB.
i need to generate ID for objects that i store and i don't know what's the best way to do it.
i need to increment a INT.
Obviously the webservice must to be used for so much people and maybe various at same time.
so, what's is a good solution?
singleton/synchronize??
i think is the only way i know, maybe there are others better.
if u can show me one example it will be very appreciated.
thanks in advance!
Synchronize has horrible overhead. If all you need is an incremental counter, you can use AtomicLong's incrementAndGet(). Put the AtomicLong in a Singleton to have a server-wide access.
Edit: Some code example:
import java.util.concurrent.atomic.AtomicLong;
public class AtomicIdGenerator
{
private static class SingletonHolder
{
public static final AtomicIdGenerator instance = new AtomicIdGenerator();
}
public static AtomicIdGenerator getInstance()
{
return SingletonHolder.instance;
}
private AtomicLong mIdGenerator = null;
private AtomicIdGenerator()
{
mIdGenerator = new AtomicLong();
}
private AtomicLong getGenerator()
{
return mIdGenerator;
}
public long getNewId()
{
return getGenerator().incrementAndGet();
}
}
Usage example is simply:
long tNewId = AtomicIdGenerator.getInstance().getNewId();
This will be thread-safe, and without any overhead from synchronization. If you foresee yourself handling lots of concurrent use cases in the future, the java.util.concurrent package provides lots of battle-proven implementations for your use cases.
Use synchronize block to achieve this. In synchronized block only one thread can enter inside it.
JVM guarantees that Java synchronized code will only be executed by one thread at a time.
You can do something like this. I've done it a while back, it was based on PostgreSql and iBatis, but you can get the idea.
public class Sequence implements Serializable {
private static final long serialVersionUID = 7526471155622776147L;
private String name = null;
private int nextId = 0;
public Sequence () {
}
public Sequence (String name, int nextId) {
this.name = name;
this.nextId = nextId;
}
public final String getName () {
return name;
}
public final void setName (String name) {
this.name = name;
}
public final int getNextId () {
return nextId;
}
public final void setNextId (int nextId) {
this.nextId = nextId;
}
}
public class SequenceSqlMapDao extends SqlMapClientDaoSupport implements SequenceDao {
/**
* This is a generic sequence ID generator that is based on a database
* table called 'SEQUENCE', which contains two columns (NAME, NEXTID).
* <p/>
* This approach should work with any database.
*
* #param name The name of the sequence.
* #return The Next ID
* #
*/
public final synchronized int getNextId(String name) {
Sequence sequence = new Sequence(name, -1);
//Sequence sequence = new Sequence();
sequence = (Sequence) getSqlMapClientTemplate ().queryForObject("getSequence", sequence);
if (sequence == null) {
try {
throw new IllegalArgumentException("Error: SHOOT! A null sequence was returned from the database (could not get next " + name + " sequence).");
} catch (Exception ex) {
Logger.getLogger(SequenceSqlMapDao.class.getName()).log(Level.SEVERE, null, ex);
}
}
Object parameterObject = new Sequence(name, sequence.getNextId() + 1);
getSqlMapClientTemplate ().update("updateSequence", parameterObject);
int nextId = sequence.getNextId();
parameterObject = null;
sequence = null;
return nextId;
}
}
If nothing else this is pretty database agnostic. You'd still have to expose the method in your webservice.
PS - I forgot where I got this from, otherwise I'd give credit to proper source.