I have created simple table called Reservations and this table have following columns: ID, DUE_DATE, PRODUCTS_PAID, RESERVATION_NAME, SALE, TOTAL_SELL_PRICE and CUSTOMER_ID.
Now what I want to do is that I want to iterate through this table where CUSTOMER_ID is given value. Here is my method that collects all those columns data by CUSTOMER_ID:
public Collection<Reservations> findReservation(int cuID) {
EntityManager em = getEntityManager();
Query q = em.createQuery("SELECT r FROM Reservations r WHERE r.customerData.id = :cID");
q.setParameter("cID", cuID);
List results = q.getResultList();
return results;
}
My problem here is that whenever I run iteration loop it won't stop iterating but it continues to iterate. I have only two rows of data in that table. Can you tell me why this iteration continues and won't stop? Obviously I just want to iterate all data inside of that table based on given CUSTOMER_ID value.
I have tried for loops, for each loops and while loops and non of them works. It must be something to do with my code. Here is one while loop that I tested but it won't stop iteration like the rest loops:
for(Iterator itr2 = rd.findReservation(cuID).iterator(); itr2.hasNext();){
rModel.addRow(Arrays.asList(rd.findReservation(cuID).iterator().next().getId(),
rd.findReservation(cuID).iterator().next().getReservationName(),
rd.findReservation(cuID).iterator().next().getCustomerData().getCustomerName(),
rd.findReservation(cuID).iterator().next().getCustomerData().getCustomerType(),
rd.findReservation(cuID).iterator().next().getDueDate(),
rd.findReservation(cuID).iterator().next().getTotalSellPrice(),
rd.findReservation(cuID).iterator().next().getSale(),
rd.findReservation(cuID).iterator().next().getProductsPaid(),
"Print"));
}
If you wonder what is cuID, its just an integer value which is received from table column. This value is customerID. It works well. So it shouldn't effect on the code. All help is appreciated :)
Because you don't call the next on your iterator that you have declared in the loop. Try this instead :
for(Iterator itr2 = rd.findReservation(cuID).iterator(); itr2.hasNext();){
MyObject obj = itr2.next();
rModel.addRow(Arrays.asList(obj.getId(),
obj.getReservationName(),
obj.getCustomerData().getCustomerName(),
obj.getCustomerData().getCustomerType(),
obj.getDueDate(),
obj.getTotalSellPrice(),
obj.getSale(),
obj.getProductsPaid(),
"Print"));
}
You need to do something like this:-
for(Reservations res : rd.findReservation(cuID)){
// Do whatever you want with this object(res)
rModel.addRow(Arrays.asList(res.getId(), res.getReservationName()...);
}
This is clean and simple! No need to use iterator in that weird way you've used, which just keeps getting a new iterator and keeps fetching the first entry from that, hence leading to an infinite loop!
you use two separate iterators. What you do is this:
while (iterator1.hasNext()) {
iterator2.next();
}
obviously you won't exhaust iterator1. Use the same iterator in your loop and in rModel line:
Iterator it = rd.findReservation(cuID).iterator();
while (it.hasNext()) {
// or whatever your type is
Object next = it.next();
rModel.addRow(Arrays.asList(next.getId(),
next.getReservationName(),
next.getCustomerData().getCustomerName(),
next.getCustomerData().getCustomerType(),
next.getDueDate(),
next.getTotalSellPrice(),
next.getSale(),
next.getProductsPaid(),
"Print"));
}
Related
Hello fellow programmers, I want to add in loop multiple lists into HashMap. I dont't know why when its getting to second iteration records are multiplied e.g. there is 10 records for February( monthId = 2) and after whole loop there is 40 of them injected. Below is code:
public HashMap<String,List<Transaction>> convertTransactionsPerMonth(int
userId){
for(int monthId = 1; monthId < 13; monthId++){
ArrayList<Transaction> transactionsFromDatabase = new ArrayList<>
(entityManager
.createQuery("SELECT t FROM Transaction t WHERE
MONTH(t.transactionDate) LIKE :monthId AND t.user.id = :userId",
Transaction.class)
.setParameter("monthId", monthId)
.setParameter("userId", userId)
.getResultList());
transactionsPerMonth.put(Months.getById(monthId),
transactionsFromDatabase);
}
return transactionsPerMonth;
}
When comparing two numbers in sql you use = and not LIKE
"SELECT t FROM Transaction t WHERE
MONTH(t.transactionDate) = :monthId AND t.user.id = :userId"
also it looks like transactionsPerMonthis declared outside of the method and then returned, are you sure it is empty when the method is called? Probably better to declare it as a local variable.
I have this code where the ArrayList was instantiated outside any condition:
List<PatientDto> list = new ArrayList<PatientDto>();
for(Object o : ObjectList){
if(true){
PatientDto patient = new PatientDto(....);
list.add(patient);
}
}
PatientDto dto = list.get(0);
Will I still be able to retrieve the new PatientDto() as I access the list, given that it was instantiated within the if statements?
yes
Patient is inside the scope of your if clause but it can be accessed outside the block if you have access to the reference for the same outside the if clause.
The list has stored a reference of your patient object which will be accessible whereever you can access the list. Hence, you can access your contained object by fetching it from the list.
Yes, since you are inserting it in to the list, you can get it by using index. Or you can iterate after insertion of all the objects later.
for ex:
PatientDto patient = list.get(index);
update :
PatientDto dto = list.get(0);
Yes, that gives the 0th indexed PatientDto from the list, which whatever you put earlier in that place. Since you adding new instances in the loop, they give you the same.
coming to the scope
for(Object o : ObjectList){
if(true){
PatientDto patient = new PatientDto(....);
list.add(patient);
}
}
System.out.println(patient); // err, I dont know what is patient
System.out.println(list.get(0)) // yay here is the patient, use it.
Suppose I have a list of objects (ArrayList objects) and a db table for the objects, I want to find the objects which has not been stored in the my database. The objects are identified by their "id". I can think of two solutions but I do not know which one is more efficient.
The first solution I think of is to construct one db query to get all objects existed in the db, and loop through the existed objects to determine the ones that is not in the db
ArrayList<Integer> ids = new ArrayList<Integer>();
for(MyObject o in objects){
ids.add(o.getId());
}
//I use sugar orm on Android, raw query can be seen as
// "select * from my_object where id in [ id1,id2,id3 ..... ]"
List<MyObjectRow> unwanted_objects = MyObject.find("id in (?,?,?,?,.....)",ids);
//remove the query results from the original arraylist
for(MyObjectRow o in unwanted_objects){
for(MyObject o1 in objects){
if(o1.getId() == o.getId()) objects.remove(o1);
}
}
The second solution is to query existence of every object in db, and add non-existed object to result array
ArrayList<MyObject> result_objects = new ArrayList<MyObject>();
boolean exist = false
for(MyObject o in objects){
exist = MyObject.find("EXIST( select 1 from my_object where id = ?)", o.getId());
if(!exist){
result_objects.add(o);
}
}
The first solution only require one query, but when loop through all founded objects, the complexity become O(n*n)
The second solution constructs n db querys, but it only has a complexity of O(n)
Which one may be better in terms of performance?
I would use option 1 with a change to use a Map<Integer, MyObject> to improve the performance of the removal of query results from the original list:
List<Integer> ids = new ArrayList<Integer>();
Map<Integer, MyObject> mapToInsert = new HashMap<Integer, MyObject>();
for(MyObject o in objects) {
//add the ids of the objects to possibly insert
ids.add(o.getId());
//using the id of the object as the key in the map
mapToInsert.put(o.getId(), o);
}
//retrieve the ids of the elements that already exist in database
List<MyObjectRow> unwanted_objects = MyObject.find("id in (?,?,?,?,.....)",ids);
//remove the query results from the map, not the list
for(MyObjectRow o in unwanted_objects){
mapToInsert.remove(o.getId());
}
//insert the values that still exist in mapToInsert
Collection<MyObject> valuesToInsert = mapToInsert.values();
You don't know the efficiency of the database operations. If the database is a b-tree under the hood that query could take O(log n). If your indices aren't set up correctly, you may be looking at o(n) performance for that query. Your measurement of efficiency here is also ignoring any transaction costs: the cost to initiation a connection with, process the query, and close the connection to the database. This is a 'fixed' cost, and I wouldn't want to do that in a loop if i didn't have to.
Go with the first solution.
I have a list which has object(record) taken from database. I need to add it another list of generic class inside a loop.When ever loop executes the final list contains only the last element.my coding are..
List<modelclass> mdlclasslist=new ArrayList();
for(Class_1 a:class1list) {
Query qr=s.createQuery("from Class_2 where ID= :f and code= :j order by mark desc");
qr.setParameter("f",id);
qr.setParameter("j",code);
List<Class_2> b=new ArrayList();
b=qr.list();
for(Class_2 cls:b) {
modelclass mdl=new modelclass(cls.getID(),cls.getCode(),cls.getMark());
mdlclasslist.add(mdl);
}
}
mdlclasslist contains same object.It is not adding every object the query takes.please advice.
Your Query appears to return the same list over and over again for every Class_1 item because id and code never change. I assuming your code should rather look like this:
Query qr=s.createQuery("from Class_2 where ID= :f and code= :j order by mark desc");
for( Class_1 a : class1list )
{
qr.setParameter( "f", a.id );
qr.setParameter( "j", a.code );
for( Class_2 cls: qr.list() )
{
modelclass mdl=new modelclass(cls.getID(),cls.getCode(),cls.getMark());
mdlclasslist.add(mdl);
}
}
How about debugging and printing out the number of elements in the 2nd list before adding?
Not sure if you want to append the List you retrieve from a DB to the one you initialize beforehand...
However, I would define the 1st List to be of the generic type Class_1 (BTW: read about Java naming conventions) and then use addAll
yourList.addAll(theListFromDB);
try this
listInstance.addAll(anotherListInstavce) ;
First i would check if my source list, the one populated from DB has more than 1 element. If you are using JDBC, its a very common mistake to not move the result set objects further.
Secondly if you need such collection manipulation utilities i suggest take a look at commons-collections ListUtils class.
All the collections have a simple method to add data of one collection to other.
list2.addAll(list1);
You can simply use this method...
Hi i am getting List object that contains pojo class objects of the table. in my case i have to show the table data in reverse order. mean that, for ex
i am adding some rows to particular table in database when i am added recently, the data is storing at last row in table(in database). here i have to show whole content of the table in my jsp page in reverse order, mean that what i inserted recently have to display first row in my jsp page.
here my code was like,
List lst = tabledate.getAllData();//return List<Table> Object
Iterator it = lst.iterator();
MyTable mt = new MyTable();//pojo class
while(it.hasNext())
{
mt=(MyTable)it.next();
//getting data from getters.
System.out.println(mt.getxxx());
System.out.println(mt.getxxx());
System.out.println(mt.getxxx());
System.out.println(mt.getxxx());
}
Use a ListIterator to iterate through the list using hasPrevious() and previous():
ListIterator it = lst.listIterator(lst.size());
while(it.hasPrevious()) {
System.out.println(it.previous());
}
You cannot use an iterator in this case. You will need to use index based access:
int size = lst.size();
for (int i=size - 1; i >= 0; i --)
{
MyTable mt = (MyTable)lst.get(i);
....
}
Btw: there is no need to create a new MyTable() before the loop. This is an instance that will be thrown away immediately and serves no purpose.