Compare field from previous row in JDBC ResultSet - java

I've researched can't find any relevant info. I have a result set that give me back distinct tagId's their can be multiple tagIds for same accountId's.
while(result_set.next()){
String tagId = result_set.getString("tagId");
String accountId = result_set.getString("accoundId");
// plenty of other fields being store locally
}
I need to store first accoundId(which is being done) & every subsequent iteration compare it with the previous Id to check for equality or not(if so same account).
I tried this and it failed horribly, after first iteration they'll continually be equal & I must be DUMB bc i though as long as I compare them before assignment global guy(previousId) should be holding the prior value.
String previousId = null;
while(result_set.next()){
String tagId = result_set.getString("tagId");
String accountId = result_set.getString("accoundId");
previousId = accountId;
}
Anyway I wanted my workflow to go something as follows:
while(result_set.next()){
if (previousId = null) {
// this would be the first iteration
}
else if (previousId.equals(accountId) {
// go here
} else {
// go here
}
}

If I've understood you well, this should work..
String previousId = null;
while(result_set.next()){
String tagId = result_set.getString("tagId");
String accountId = result_set.getString("accoundId");
if (previousId == null) {
// this would be the first iteration
} else if (previousId.equals(accountId) {
// go here
} else {
// go here
}
previousId = accountId;
}

Related

Spring-hibernate debug

I have a very strange problem. I'm trying to show in a basket the price of products. When I run the code and add a product to the basket, I can see the name of the product but I can't see its price. When I click back to a previous page and add another product, I am able to see its price. There is no error message.
Also, when I try to debug this program, everything works. The problem appears only when I'm not debugging. The problem is closely connected with these two variables as indicated below. I think that these variables are 0 which is later printed on the screen. But I don't know why they are sometimes 0 and sometimes not. I also tried to set breakpoints on:
dataService.getQuantityOfDays();
dataService.getQuantityOfBreakfasts();
When I assign values to these two variables in Data class everything is ok (not 0).
Controller code:
#RequestMapping("/basket/{roomName}")
public String createBasket(Model model, #PathVariable("roomName") String roomName){
Floor currentFloor = floorService.getCurrentFloor();
User currentUser = userService.getCurrentUser();
this.roomName = roomName;
if(currentFloor != null){
Room currentRoom = roomService.getRoomByName(roomName, currentFloor);
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String name = auth.getName();
if(currentUser == null){
userService.setCurrentUser(userService.getUserByName(name)); // wykona sie jesli nie zakladamy konta w danej sesji
}
Basket basketToSave = new Basket(userService.getCurrentUser());
BasketItem basketItem = new BasketItem(currentRoom);
int quantityOfDays = dataService.getQuantityOfDays(); //<--problem
int quantityOfBreakfast = dataService.getQuantityOfBreakfasts(); //<--problem
int priceForOneBreakfast = 17;
int priceForOneDay = currentRoom.getPriceForOneDay();
int wholePrice = quantityOfDays * priceForOneDay + quantityOfBreakfast * priceForOneBreakfast;
basketItem.setPrice(wholePrice);
basketItem.setQuantityOfDays(quantityOfDays);
basketItem.setQuantityOfBreakfast(quantityOfBreakfast);
Set<BasketItem> basketItemList = new HashSet<BasketItem>();
basketItemList.add(basketItem);
basketService.countBasketPrice(basketItemList, basketToSave);
basketToSave.setBasketItems(basketItemList);
basketItem.setBasket(basketToSave);
currentRoom.setBasketItemList(basketItemList);
boolean ifWasAnUpdate = basketService.save(basketToSave); // metoda save oprócz zapisu lub nadpisania zwraca co się wydarzyło (true - jesli nadpisywaliśmy koszyk)
if(ifWasAnUpdate){
basketItem.setBasket(basketService.get(basketToSave.getUser())); // jeżeli dodaje coś do koszyka (a nie tworzę go od nowa), muszę ustawić basketItemowi
} // koszyk, który już istnieje, a nie ten, który stworzyłem wcześniej w klasie BasketController.
// W tym celu pobieram go z bazy.
basketItemService.save(basketItem);
}
model.addAttribute("basket", basketService.get(currentUser));
model.addAttribute("days", dataService.getQuantityOfDays());
return "basket";
}
EDIT:
It's a repository code.
#Repository
public class DataRepositoryImpl implements DataRepository {
private int quantityOfDays;
private int quantityOfBreakfasts;
public void setQuantityOfDaysAndBreakfasts(String text) {
List<Integer> listOfIndexes = new ArrayList<Integer>();
for(int i=0;i<text.length();i++){
if(text.charAt(i) != '1'){
listOfIndexes.add(i);
}
}
char znak = text.charAt(listOfIndexes.get(0));
this.quantityOfDays = Character.getNumericValue(text.charAt(listOfIndexes.get(0))); // <- I put breakpoint here
this.quantityOfBreakfasts = Character.getNumericValue(text.charAt(listOfIndexes.get(1))); // <- I put breakpoint here
}
public int getQuantityOfDays() {
return this.quantityOfDays;
}
public int getQuantityOfBreakfasts() {
return this.quantityOfBreakfasts;
}
}
A problem can be also in basket save. Firslty when I can see only zeros I persist basket, then I'm only updating it.
Save & update methods:
public boolean save(Basket basketToSave) {
List<Basket> listOfAllBaskets = getAll();
boolean save = true;
boolean ifWasAnUpdate = false;
for(Basket basket: listOfAllBaskets){
if(basketToSave.getUser().equals(basket.getUser())){
save = false;
}
}
if(save){
emManager.persist(basketToSave);
}else{
updateBasket(basketToSave);
ifWasAnUpdate = true;
}
return ifWasAnUpdate;
}
public void updateBasket(Basket basket) {
Basket basketFromDatabase = get(basket.getUser());
basketFromDatabase.setBasketItems(basket.getBasketItems());
basketFromDatabase.setPrice(basket.getPrice());
emManager.merge(basketFromDatabase);
}
EDIT
I'm calling setQuantityOfDaysAndBreakfasts(text) earlier in this apllication. In this controller I'm only setting these values to basketItem class. I'll change this controller. Here another controller where I call setQuantityOfDaysAndBreakfasts(text).
#RequestMapping(value = "/room/rest", method = RequestMethod.POST, consumes = {"application/json"})
public void data(#RequestBody Data request){
String text = request.getText();
dataService.setQuantityOfDaysAndBreakfasts(text);
}
You are calling setQuantityOfDaysAndBreakfasts() after you get the value from your dataService. The value for quantityOfDays and quantityOfBreakfasts are only set when that method is called.
There are several things you should also examine.
As #NathanHughes points out, it's best to put your complex logic in your service layer and leave the controller to simply route requests. This is also true of your repository class. You should keep this very simple as the next developer reading your code is not going to expect to find any logic that doesn't simply read or write to your data source. (See Single Responsibility Principle.) It will also reduce code duplication in the future and as a result, reduce your time maintaining and fixing bugs.
For example, this code:
List<Integer> listOfIndexes = new ArrayList<Integer>();
for(int i=0;i<text.length();i++){
if(text.charAt(i) != '1'){
listOfIndexes.add(i);
}
}
char znak = text.charAt(listOfIndexes.get(0));
Should be refactored to a separate method entirely that can be made static and would not belong in that class.

Receiving "null" in Place of Correct Values

I'm currently using Jersey REST to create a webpage that has a list of birds and taxonomy number, with a link to a page specifically about the bird in question. While my links work between the two pages, and my Bird Name and Taxonomy Number appear, I can't get the order or family name to appear. Following is the code in question.
#Path("/birdslist")
public class BirdsList extends Birds {
#GET
#Path("/all")
#Produces("text/html")
public String all() {
Iterator iterator = birdnames.keySet().iterator();
String page = "<html><title>All Birds</title><body>";
page += "<p>This is the list of all birds. <br> Click the taxonomy number of the bird you wish to view in detail.</p>";
while(iterator.hasNext()){
Object key = iterator.next();
String value = birdnames.get(key);
HashSet fam = family.get(key);
HashSet ord = order.get(key);
}
for (String key : birdnames.keySet()) {
page += String.format("<p>Name:%s <br> Taxonomy Number:<a href=%s>%s</a></p>",birdnames.get(key),key,
key);
getBird(key);
}
page += "</body></html>";
return page;
}
#GET
#Path("{key}")
#Produces("text/html")
public String getBird(#PathParam("key") String key) {
String page = "<html><title>Bird #: {key}</title><body>";
page += String.format("<p>This page contains info on the %s</p>",birdnames.get(key));
page += String.format("<p>Name:%s <br> Taxonomy Number:%s <br> Family:%s <br> Order:%s</p>",birdnames.get(key),key,family.get(key),order.get(key));
page += "<p>Please click <a href=all>here</a> to return to the list of all birds.</p>";
page += "</body></html>";
return page;
}
}
The family and order are saved in a HashSet that is inside of a hashmap, while bird name is in a hashmap. It was written over from a csv file and converted into hashmaps. Following is that code.
public class Birds {
HashMap<String,String> birdnames;
HashMap<String,HashSet<String>> family;
HashMap<String,HashSet<String>> order;
/**
Constructor reads the CSV of all birds
*/
public Birds() {
// long path to eBirds assuming Maven "mvn exec:java" is many levels up
String fileName = "src/main/java/com/example/rest/eBirds.csv";
boolean firstLine = true;
this.birdnames = new HashMap<String,String>();
this.family = new HashMap<String,HashSet<String>>();
this.order = new HashMap<String,HashSet<String>>();
try {
BufferedReader R = new BufferedReader(new FileReader(fileName));
String line;
while (true) {
line = R.readLine();
if (line == null) break;
if (firstLine) { // ignore the first line, it's not a bird
firstLine = false;
continue;
}
String[] fields = line.split(",");
if (!fields[1].equalsIgnoreCase("species")) continue; // ignore all but species records
birdnames.put(fields[0],fields[4]); // add this bird to name table
// extract the order name from fields[6]
String ordername = fields[6];
if (!order.containsKey(ordername)) { // if needed, create first-time order set
order.put(ordername,new HashSet<String>());
}
order.get(ordername).add(fields[0]); // new order member by number for lookup
// extract the family name from fields[7] -- removing quotes first if needed
String famname = fields[7].replace("\"","");
if (!family.containsKey(famname)) { // if needed, create first-time family set
family.put(famname,new HashSet<String>());
}
family.get(famname).add(fields[0]); // new family member by number for lookup
}
}
catch (IOException e) { System.out.println("Stack trace: " + e); }
}
...
}
I've never used HashSets before, that was part of the given info to us. Our assignment was to create a list page and pages specific to each bird and link between the two. I just can't get these last two values to appear correctly. Can anyone help?
Here you use the same key for all values, birdnames, family and order:
while(iterator.hasNext()){
Object key = iterator.next();
String value = birdnames.get(key);
HashSet fam = family.get(key);
HashSet ord = order.get(key);
}
But you initialize them with different keys:
// extract the order name from fields[6]
String ordername = fields[6];
if (!order.containsKey(ordername))
{ // if needed, create first-time order set
order.put(ordername, new HashSet<>());
}
order.get(ordername).add(fields[0]); // new order member by number for lookup
Here the key would be fields[6] and not the birdnames key.
If you want to keep using the same key, you could do the following for the orders:
if (!order.containsKey(fields[0]))
{
order.put(fields[0], new HashSet<>());
}
order.get(fields[0]).add(fields[6]);
Then you can use:
HashSet ord = order.get(key);
And you will receive all the orders for that bird name.
If you don't want to change that and still use the same key you could do something like the following, but that is highly discouraged as it destroys the purpose of using a map in the first place:
Set<String> ord = new HashSet<>();
for (String tmp : order.keySet())
{
if (order.get(tmp).contains(key))
ord.add(tmp);
}
Here ord would contain all the orders for the "key".
As you can see, you need to do much more redundant work, if you don't switch value and "key".

Why doesn't this .equals() work?

I'm working in Eclipse (Android). In the following blocks, EmployeeInt and RestaurantInt are data types and query() opens a connection to the database and parses the results. When I print the query results, I get identical strings, but the boolean is still false. I've tried trimming the strings, but that didn't help.
public boolean verifyEmployee(String email, String password) {
ArrayList<EmployeeInt> employeeEmailID = query("SELECT employeeID FROM employees WHERE emailAddress = \'"+email+"\'");
ArrayList<EmployeeInt> employeePasswordID = query("SELECT employeeID FROM employees WHERE password = \'"+password+"\'");
String stringEmployeeEmailID = employeeEmailID.toString();
String stringEmployeePasswordID = employeePasswordID.toString();
if(stringEmployeeEmailID.equals(stringEmployeePasswordID)) {
return true;
} else {
return false;
}
}
Executing the above gives me false, while executing the following block (virtually identical) gives me true.
public boolean verifyRestaurant(String email, String password) {
ArrayList<RestaurantInt> restaurantEmailID = query("SELECT restaurantID FROM restaurants WHERE emailAddress = \'"+email+"\'");
ArrayList<RestaurantInt> restaurantPasswordID = query("SELECT restaurantID FROM restaurants WHERE password = \'"+password+"\'");
String stringRestaurantEmailID = restaurantEmailID.toString();
String stringRestaurantPasswordID = restaurantPasswordID.toString();
if(stringRestaurantEmailID.equals(stringRestaurantPasswordID)) {
return true;
} else {
return false;
}
}
Can anyone point out my mistake?
EDIT
I changed it to this and it worked:
public boolean verifyEmployee(String email, String password) {
ArrayList<EmployeeInt> employeeEmailID = query("SELECT * FROM employees WHERE emailAddress = \'"+email+"\'");
ArrayList<EmployeeInt> employeePasswordID = query("SELECT * FROM employees WHERE password = \'"+password+"\'");
int intEmployeeEmailID = employeeEmailID.get(0).getID();
int intEmployeePasswordID = employeePasswordID.get(0).getID();
if(intEmployeeEmailID==intEmployeePasswordID) {
return true;
} else {
return false;
}
}
I know I could also use return (condition), but I would like to add some messages if the login fails, something like:
System.err.println("email address and password do not correspond");
I'm not making an app to publish, it's merely for an assignment. Thanks for the help!
You are calling toString() on an ArrayList. Two different ArrayList objects will return two different toString() strings. You probably meant to get the first element of the ArrayList, and convert THAT to a string.
Example
EmployeeInt is your custom object. In my example, I assume it has some int field that can be retreived with getID().
ArrayList<EmployeeInt> idList = query("SELECT employeeID FROM employees WHERE emailAddress = \'"+email+"\'");
int ID = idList.get(0).getID();
stringEmployeeEmailID = String.valueOf(ID);
This may be easier to read than code:
query() returns an ArrayList
We extract the first element of the ArrayList - this is the part you left out
We get the ID of that element
We convert it to a String

Storing the details in list and then on inspecting storing in different list

I have a pojo like this..
public class abcObject {
private long id;
private long version;
private DateTime created ;
private String status;
}
and its corresponding hbm as internally it data is being stored in the table through hibernate now please advise as the status can have values like pass or failNow i have to filter the value whether it is pass or fail as rite now i can check its value by inspecting and depending upon that I have to put them into the seprate list, I have done through this way
List<abcObject> successful = new ArrayList <abcObject>();
List<abcObject> exception = new ArrayList <abcObject>();
List<abcObject> failure = new ArrayList <abcObject>();
//getting the list from the database into the parameter allabcObjects
List<abcdObject> allabcObjects = abcHome.getabcObjects(fileIdentifier);
if (abcObjects !=null && abcObjects.size() > 0) {
for (abcObject f : allabcObjects) {
}
Now please advise as I am using the for loop to iterate over each object then how by inspecting that is f.getstatus() method and if it is fail then it should stote all the details in fail list and if it it is success then it should store in successful list , please advise how to achieve this
Just compare object with your strings
List<abcObject> successful = new ArrayList <abcObject>();
List<abcObject> exception = new ArrayList <abcObject>();
List<abcObject> failure = new ArrayList <abcObject>();
//getting the list from the database into the parameter allabcObjects
List<abcdObject> allabcObjects = abcHome.getabcObjects(fileIdentifier);
if (abcObjects !=null && abcObjects.size()>0)
{
for (abcObject f : allabcObjects) {
if( "pass".equalsIgnoreCase(f.getStatus()) ) {
successful.add( f );
} else if ( "failNow".equalsIgnoreCase(f.getStatus()) {
failure.add( f );
}
}
}
Just to point out some things. Even better would be to create static final string, for your success / fail string like this:
private static final String SUCCESS = "success";
private static final String FAIL = "failNow";
....
if( SUCCESS.equalsIgnoreCase(f.getStatus()) ) {
successful.add( f );
} else if ( FAIL.equalsIgnoreCase(f.getStatus()) {
failure.add( f );
}
Comparing SUCCESS with f.getStatus(), instead of inverse, gives us certainty that there won't be NullPointerException if somehow f would be null
Your for loop would read:
for (abcObject f : allabcObjects) {
String status = f.getstatus();
if(status.equals("fail")){
failure.add(f);
}
else{
otherList.add(f);
}
}
You'll also need to declare the otherList, i.e.
List<abcObject> otherList = new ArrayList<abcObject>();
This assumes that your getstatus() method returns a String "fail" if it fails.

if statement OR logic oddity

I'm calling this function from a jUnit test case with the following information:
// abbr = "US";
// Countries = array of two objects one with iso2 = "us"
public Country getCountryFromAbbr(String abbr) {
abbr = abbr.toLowerCase();
for (int i = 0; i < Countries.size(); i++) {
Country country = Countries.get(i);
String iso2 = country.ISO2.toLowerCase();
String iso3 = country.ISO3.toLowerCase();
if (iso2.equals(abbr) || iso3.equals(abbr)) {
return country;
}
}
return null;
}
When I debug, the second object with ISO2 of us iso2.equals(abbr) is true and the other is false. However, country is not returned and the debugger finishes the loop and returns null.
I'm confused as true || false is true. Am I missing something?
Here's the mock of the countries:
List<Country> Countries = new ArrayList<Country>();
Country country = new Country();
country.CountryId = 1;
country.CountryName = "Great Britian";
country.ISO2 = "GB";
country.ISO3 = "GBR";
Countries.add(country);
Country usa = new Country();
usa.CountryId = Studio.USA_COUNTRY_ID;
usa.CountryName = "United States of America";
usa.ISO2 = "US";
usa.ISO3 = "USA";
Countries.add(usa);
return Countries;
EDIT:
I'm using Eclipse and debugging using my Droid X 2.3.3
Does it work fine with simple if condition?
if (iso2.equals(abbr)) {
return country;
}
if(iso3.equals(abbr)){
return country;
}
This looks like a job for Enum! (whoooooosh!)
public enum Country {
GREAT_BRITAIN("GB", "GBR"),
USA("US", "USA");
private String iso2;
private String iso3;
private Country(String iso2, String iso3){
this.iso2 = iso2;
this.iso3 = iso3;
}
public static Country getCountry(String a){
for (Country c : Country.values()){
if (c.iso2.equalsIgnoreCase(a) || c.iso3.equalsIgnoreCase(a)){
return c;
}
}
return null; // no country found!
}
}
If Country is immutable (you're not going to change any values inside it), then this is a neat way of doing it - and you can add id and name as attributes as well. And expose getters if you need access to those attributes.
Your current method accesses Countries as an instance variable, instead of as an argument to the method, so it's possible there are side-effects there.

Categories

Resources