简体   繁体   中英

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM