Vaadin/Hibernate - Table does not update

Hello!

I have coded this Vaadin tutorial: http://vaadin.com/download/book-of-vaadin/vaadin-7/pdf/vaadin-tutorial.pdf
After that I modified it and connected it with Hibernate. Then it still worked. Now I try to get an object from my DB (in my code this objects are called Bestand), change the object (with the help of a Bestellung object, which are childs of Bestand) and write it back in my DB.
My problem is that the objects in my DB are changed (I’ve checked it with the MySQL-Workbench), but the table, built in the tutorial, still shows the old objects without the changes. If I restart my server (respectively my code) the changes are shown in the table, but I want to have the changes immediately without restarting anything.

This is my try:

Bestellung bestellung = new Bestellung("Lager", 0, 5, 0, 0, 0);
           
Transaction transaction = HibernateUtil.getSession().beginTransaction();
          
Bestand bestand = new BestandDAO().getBestandById(1);
bestand.setBierMenge(bestand.getBierMenge()-bestellung.getBierMenge());
     
commit();
 
app.getDataSource().changeBestand(bestand);

Should I add more code or my complete project?
I really need help guys, it would be very nice if anyone would have an idea. I tried a lot and do not have another idea.

Thank you!

Im going to guess because your code doesnt tell what this (app.getDataSource().changeBestand(bestand):wink: does. if the new value setted in the components is “equal” (depends on equal override) to the old one, the component doesnt refresh. Try setting a new blank Bestand before passing the merged one to understand whats going on.

Thank you for your advice. I have not tried to override equal, I will do it now!

The code you mentioned gets me my DataSource in my Main Class and calls the changeBestand-method wit the following code.

    public void changeBestand(Bestand b){
        
        Transaction transaction = HibernateUtil.getSession().beginTransaction();
        
        Bestand bestand = new BestandDAO().getBestandById(b.getEmpID());
        
        
        bestand.setOrt(b.getOrt());
        bestand.setColaMenge(b.getColaMenge());
        bestand.setBierMenge(b.getBierMenge());
        bestand.setWasserMenge(b.getWasserMenge());
        bestand.setWhiskeyMenge(b.getWhiskeyMenge());
        bestand.setVodkaMenge(b.getVodkaMenge());
        
        new BestandDAO().save(bestand);
        
        transaction.commit();
        HibernateUtil.getSession().close();        
        
    }

Now I have overwritten my equals-method, but it still does not work and I have now an display error in my textfields.
This is the code of my Bestand class.

package data;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name = "Bestand")
public class Bestand {
    
    private int EmpID;
    private String ort = "";
    private Integer colaMenge = null;
    private Integer bierMenge = null;
    private Integer wasserMenge = null;
    private Integer whiskeyMenge = null;
    private Integer vodkaMenge = null;
    


    

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
//    @GenericGenerator(name="Person" , strategy="increment")
//    @GeneratedValue(generator="Person")
    public int getEmpID(){
        return EmpID;
    }
    
    public void setEmpID(int empID) {
        EmpID = empID;
    }

    public String getOrt() {
        return ort;
    }

    public void setOrt(String ort) {
        this.ort = ort;
    }

    public Integer getColaMenge() {
        return colaMenge;
    }

    public void setColaMenge(Integer colaMenge) {
        this.colaMenge = colaMenge;
    }

    public Integer getBierMenge() {
        return bierMenge;
    }

    public void setBierMenge(Integer bierMenge) {
        this.bierMenge = bierMenge;
    }

    public Integer getWasserMenge() {
        return wasserMenge;
    }

    public void setWasserMenge(Integer wasserMenge) {
        this.wasserMenge = wasserMenge;
    }

    public Integer getWhiskeyMenge() {
        return whiskeyMenge;
    }

    public void setWhiskeyMenge(Integer whiskeyMenge) {
        this.whiskeyMenge = whiskeyMenge;
    }

    public Integer getVodkaMenge() {
        return vodkaMenge;
    }

    public void setVodkaMenge(Integer vodkaMenge) {
        this.vodkaMenge = vodkaMenge;
    }

    @Override
    public boolean equals(Object obj) {
        Bestand b = (Bestand)obj;
        if(obj == null)
            return false;
        
        if(getOrt().compareTo(((Bestand)obj).getOrt()) == 0)
            if(getBierMenge() == b.getBierMenge())
                if(getColaMenge() == b.getColaMenge())
                    if(getVodkaMenge() == b.getColaMenge())
                        if(getWhiskeyMenge() == b.getWhiskeyMenge())
                            if(getWasserMenge() == b.getWasserMenge())
                                return true;
        
        return false;
    }
    

}

This is still persistence code, show some vaadin code for better understanding of your problem. I just notice you mentioned a table, how do you populate it? is it data binded? you could try

table.refreshRowCache();

This is my main application class.

package barControlApplication;
 
import ui.BestandForm;
import ui.BestandList;
import ui.BestellungForm;
import ui.ListView;
import ui.NavigationTree;
import ui.SearchView;
 
import com.vaadin.Application;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.Panel;
import com.vaadin.ui.SplitPanel;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.VerticalSplitPanel;
import com.vaadin.ui.Window;
 
import data.BestandContainer;
import data.SearchFilter;
 
/**
 * Main application class.
 */
public class BarControlApplication extends Application implements
                               Button.ClickListener, Property.ValueChangeListener, ItemClickListener {
 
                private Button newContact = new Button("Bestand");
                private Button search = new Button("Suchen");
                private HorizontalSplitPanel horizontalSplit = new HorizontalSplitPanel();
                private NavigationTree tree = new NavigationTree(this);
                private BestandList bestandList = null;
                private BestandForm bestandForm = null;
                private ListView listView = null;
               
                private BestellungForm bestellungForm = null;
                private VerticalSplitPanel bestellungView = null;
               
                private BestandContainer dataSource = null;
                private SearchView searchView = null;
 
                // Initialisierungsmethode
                @Override
                public void init() {
                               try {
                                               //als Datasource wird der BestandContainer festgelegt und Hibernate angestoßen
                                               dataSource = new BestandContainer(this).getData();
                               } catch (InstantiationException e) {
                                               e.printStackTrace();
                               } catch (IllegalAccessException e) {
                                               e.printStackTrace();
                               }
                               setMainComponent(getListView());
                               buildMainLayout();
                                /**
                     * Used to get current Hibernate session. Also ensures an open Hibernate
                     * transaction.
                     */
//                           getContext().addTransactionListener(new TransactionListener() {
//            public void transactionEnd(Application application,
//                    Object transactionData) {
//                // Transaction listener gets fired for all contexts
//                //  (HttpSessions) toolkit applications, checking to be this one.
//                if (application == AdressbookApplication.this) {
//                    closeSession();
//                }
//            }
//
//            public void transactionStart(Application application,
//                    Object transactionData) {
//
//            }
//        });
                }
               
                // Methode zum Aufbau des Layouts
                @SuppressWarnings("deprecation")
                private void buildMainLayout() {
                                setMainWindow(new Window("BarControl P1"));
                               //generelles Layout wird erzeugt
                               VerticalLayout layout = new VerticalLayout();
                               layout.setSizeFull();
                               // Toolbar wurde entfernt
                               // funktioniert mittlerweile auch nicht mehr reibungslos
                //            layout.addComponent(createToolbar());
                               layout.addComponent(horizontalSplit);
                               //horizontal split panel bekommt kompletten verfügbaren Platz
                               layout.setExpandRatio(horizontalSplit, 1);
                               //splitter des horizontal split panels wird so platziert, dass links ein 200 Pixel breites Menü
                               //möglich ist
                               horizontalSplit.setSplitPosition(200, SplitPanel.UNITS_PIXELS);
                               horizontalSplit.setFirstComponent(tree);
 
                               getMainWindow().setContent(layout);
                }
 
                //Erzeugt Toolbar!
                //derzeit unbenutzt
                public HorizontalLayout createToolbar() {
                               HorizontalLayout lo = new HorizontalLayout();
                               lo.addComponent(newContact);
                               lo.addComponent(search);
                               newContact.addListener((Button.ClickListener) this);
                               search.addListener((Button.ClickListener) this);
 
                               return lo;
                }
 
                // Erzeugt aktuelle View!!
                private void setMainComponent(Component c) {
                               horizontalSplit.setSecondComponent(c);
                }
 
                // zeigt SearchView
                private void showSearchView() {
                               setMainComponent(getSearchView());
 
                }
 
                // zeigt ListView
                private void showListView() {
                               setMainComponent(getListView());
 
                }
               
                private void showBestellungView() {
                               setMainComponent(getBestellungView());
                }
 
                // neuen Bestand hinzufügen
                private void addNewBestand() {
                               showListView();
                               bestandForm.addBestand();
                }
 
                // Suchen-Funktion
                public void search(SearchFilter searchFilter) {
                               // clear previous filters
                               getDataSource().removeAllContainerFilters();
                               // filter contacts with given filter
                               getDataSource().addContainerFilter(searchFilter.getPropertyId(),
                                                               searchFilter.getTerm(), true, false);
                               showListView();
                }
               
                //Suche-speichern-Funktion
                public void saveSearch(SearchFilter searchFilter) {
                               tree.addItem(searchFilter);
                               tree.setParent(searchFilter, NavigationTree.SEARCH);
                               // mark the saved search as a leaf (cannot have children)
                               tree.setChildrenAllowed(searchFilter, false);
                               // make sure "Search" is expanded
                               tree.expandItem(NavigationTree.SEARCH);
                               // select the saved search
                               tree.setValue(searchFilter);
                }
               
                public void bestandCommit(){
                               bestandForm.commit();
                               System.out.println("Gerufen");
                }
               
//            public void refreshTable() {
//                           personList.refreshRowCache();
//                           personList.requestRepaint();
//                           System.out.println("refreshTable durchlaufen!");
//            }
//
//            public void showNewListView(){
//                           personList = new BestandList(this);
//                           personList.validate();
//                           //personList
////                       listView.setFirstComponent(personList);
//                           listView = new ListView(personList, bestandForm);
//                           setMainComponent(listView);
//            }
//           
//            public void validateAll(){
//                           personList.validate();
//            }
               
                // ------------------------------------------------------------
                // Getter!
 
                //Lazy Getter ListView
                private ListView getListView() {
                               if(listView == null) {
                                               bestandList = new BestandList(this);
                                               bestandForm = new BestandForm(this);
                                               listView = new ListView(bestandList, bestandForm);
                               }
                               return listView;
                }
               
                public void bestellungAusfuehren() {
                               bestandForm.bestellung();
                }
               
                // PersonContainer Getter
                //Hier wird die zugrunde liegende DataSource an die BestandList GUI Klasse übergeben
                public BestandContainer getDataSource() {
                               return dataSource;
                }
               
                public BestandList getPersonList(){
                               return bestandList;
                }
 
                // Lazy SearchView - Getter
                private SearchView getSearchView() {
                               if (searchView == null) {
                                               searchView = new SearchView(this);
                               }
                               return searchView;
                }
               
                // Lazy BestellungForm - Getter
                private VerticalSplitPanel getBestellungView() {
                               if (bestellungView == null) {
                                               bestellungForm = new BestellungForm(this);
                                               bestellungView = new VerticalSplitPanel();
                                               bestellungView.setFirstComponent(bestellungForm);
                                               bestellungView.setSizeFull();
                               }
                               return bestellungView;
                }
                // ------------------------------------------------------------
                // Listener!!!
 
                public void buttonClick(ClickEvent event) {
                               final Button source = event.getButton();
                               if (source == search) {
                                               showSearchView();
                               }
                               if (source == newContact) {
                                               addNewBestand();
                               }
                }
 
                //zeigt in der bestandForm unten das in der bestandListe ausgewählte Item
                public void valueChange(ValueChangeEvent event) {
//                           System.out.println("ValueChange Handler gerufen");
                               Property property = event.getProperty();
                               if (property == bestandList) {
                                               Item item = bestandList.getItem(bestandList.getValue());
                                               if (item != bestandForm.getItemDataSource()) {
                                                               bestandForm.setItemDataSource(item);
                                               }
                               }
                }
 
                //Event Handler für die linke Navigation Tree
                //valueChange wäre theoretisch auch möglich,
                //aber itemClick lässt die auswahl eines bereits ausgewählten Items zu
                public void itemClick(ItemClickEvent event) {
                               if (event.getSource() == tree) {
                                               Object itemId = event.getItemId();
                                               if (itemId != null) {
                                                               if (NavigationTree.BESTAND.equals(itemId)) {
                                                                              // clear previous filters
                                                                              getDataSource().removeAllContainerFilters();
                                                                              //showListView();
               
                                                                              addNewBestand();
                                                               } else if (NavigationTree.SEARCH.equals(itemId)) {
                                                                              showSearchView();
                                                               } else if (NavigationTree.BESTELLUNG.equals(itemId)) {
                                                                              showBestellungView();
                                                               } else if (itemId instanceof SearchFilter) {
                                                                              search((SearchFilter) itemId);
                                                               }
                                               }
                               }
                }
 
}

This is the BestandForm class, which updates the DB normally.

package ui;
 
import java.util.Arrays;
import java.util.List;
 
import org.hibernate.Transaction;
 
import barControlApplication.BarControlApplication;
 
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
 
import data.Bestand;
import data.BestandContainer;
import data.BestandDAO;
import data.Bestellung;
import data.HibernateUtil;
//checked
public class BestandForm extends Form implements ClickListener {
 
                private Button save = new Button("Speichern", (ClickListener) this);
                private Button cancel = new Button("Abbrechen", (ClickListener) this);
                private Button edit = new Button("Bestand ändern", (ClickListener) this);
                private BarControlApplication app;
                private boolean newContactMode = false;
                private Bestand newBestand;
 
                public BestandForm(BarControlApplication app) {
                               this.app = app;
                               // Enable buffering so that commit() must be called for the form
                               // before input is written to the data. (Form input is not written
                               // immediately through to the underlying object.)
                               setWriteThrough(false);
                               HorizontalLayout footer = new HorizontalLayout();
                               footer.setSpacing(true);
                               footer.addComponent(save);
                               footer.addComponent(cancel);
                               footer.addComponent(edit);
                               footer.setVisible(false);
                               setFooter(footer);
                              
                }
 
                public void buttonClick(ClickEvent event) {
                               Button source = event.getButton();
                              
                               if (source == save) {
                                               /*
                                                * If the given input is not valid there is no point in continuing
                                                */
                                               if (!isValid()) {
                                                               return;
                                               }
                                               commit();
                                               if (newContactMode) {
                                                               /* We need to add the new bestand to the container */
                                                               Item addedItem = app.getDataSource().saveBestand(newBestand);
                                                               /*
                                                                * We must update the form to use the Item from our datasource
                                                                * as we are now in edit mode
                                                                */
                                                               setItemDataSource(addedItem);
                                                               newContactMode = false;
                                               }
                                              
                                               // kein neuer Bestand, also Änderung:
                                               else{                                                                                                                  
                                                               //der Cast vom TabellenItem zurück zum Bestand ist etwas tricky
                                                               @SuppressWarnings({ "unchecked", "rawtypes" })
                                                               BeanItem<Bestand> pBI = (BeanItem) app.getPersonList().getItem(app.getPersonList().getValue());
                                                               Bestand bestand =  pBI.getBean();
                                                               //Jetzt wollen wir noch den Datenbestand in der Datenbank anpassen
                                                               app.getDataSource().changeBestand(bestand);
                                               }
                                                              
                                               setReadOnly(true);
                                              
                               } else if (source == cancel) {
                                               if (newContactMode) {
                                                               newContactMode = false;
                                                               setItemDataSource(null);
                                               } else {
                                                               discard();
                                               }
                                               setReadOnly(true);
                                              
                               } else if (source == edit) {
                                               setReadOnly(false);
                                              
                               }
                }
 
                @Override
                public void setItemDataSource(Item newDataSource) {
                               newContactMode = false;
                               if (newDataSource != null) {
                                               List<Object> orderedProperties = Arrays
                                                                              .asList(BestandContainer.NATURAL_COL_ORDER);
                                               super.setItemDataSource(newDataSource, orderedProperties);
                                               setReadOnly(true);
                                               getFooter().setVisible(true);
                               } else {
                                               super.setItemDataSource(null);
                                               getFooter().setVisible(false);
                               }
                }
 
                @Override
                public void setReadOnly(boolean readOnly) {
                               super.setReadOnly(readOnly);
                               save.setVisible(!readOnly);
                               cancel.setVisible(!readOnly);
                               edit.setVisible(readOnly);
                }
 
                public void addBestand() {
                               // Create a temporary item for the form
                               newBestand = new Bestand();
                               setItemDataSource(new BeanItem<Bestand>(newBestand));
                               newContactMode = true;
                               setReadOnly(false);
                }
               
//            public void bestellung() {
//                           Bestellung bestellung = new Bestellung("Lager", 0, 5, 0, 0, 0);
//                          
//                           Transaction transaction = HibernateUtil.getSession().beginTransaction();
//                          
//                           Bestand bestand = new BestandDAO().getBestandById(1);
//                          
//                           bestand.setBierMenge(bestand.getBierMenge()-bestellung.getBierMenge());
//                           System.out.println("Bestand BierMenge: " + bestand.getBierMenge());
//                          
//                           commit();
//
//                           app.getDataSource().changeBestand(bestand);
//            }
               
}

This is my new class to directly update the DB, I tried to do it like it is done in the BestandForm class, but it does not work correctly. Only the DB is updated not my table.

package ui;
 
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
 
import org.hibernate.Transaction;
 
import barControlApplication.BarControlApplication;
 
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Panel;
 
import data.Bestand;
import data.BestandContainer;
import data.BestandDAO;
import data.Bestellung;
import data.HibernateUtil;
 
public class BestellungForm extends Form implements ClickListener {
 
                private Button order = new Button("Bestellung", (ClickListener) this);
                private BarControlApplication app;
 
                public BestellungForm(BarControlApplication app) {
                               this.app = app;
                               // Enable buffering so that commit() must be called for the form
                               // before input is written to the data. (Form input is not written
                               // immediately through to the underlying object.)
                               setWriteThrough(false);
                               HorizontalLayout footer = new HorizontalLayout();
                               footer.setSpacing(true);
                               footer.addComponent(order);
                               footer.setVisible(true);
                               setFooter(footer);        
                }
 
                @SuppressWarnings("unchecked")
                public void buttonClick(ClickEvent event) {
                               Button source = event.getButton();
                              
                               if (source == order) {
 
                                               Bestellung bestellung = new Bestellung("Lager", 0, 5, 0, 0, 0);
                                              
                                              
                                              
                                               Transaction transaction = HibernateUtil.getSession().beginTransaction();
                                              
                                               //voraussichtlich so nicht machbar
//                                           Collection<Bestand> bestaende = new BestandDAO().findByOrt(bestellung.getOrt());
//                                           Object[]ba = bestaende.toArray();
//                                           Bestand bestand = (Bestand) ba[0]
;
                                               Bestand bestand = new BestandDAO().getBestandById(1);
                                              
                                               //Bestand neuerBestand = new BestandDAO().getBestandById(1);
                                              
                                               bestand.setBierMenge(bestand.getBierMenge()-bestellung.getBierMenge());
                                               System.out.println("Bestand BierMenge: " + bestand.getBierMenge());
                                              
                                               //noch nicht klar ob nötig (?)
//                                           transaction.commit();
//                                           HibernateUtil.getSession().close();       
                                              
//                                           commit();
                                              
                                              
                                               commit();
 
                                               app.getDataSource().changeBestand(bestand);
                                              
//                                           app.bestandCommit();
//                                           validate();
//                                           app.validateAll();
                                              
//                                           app.showNewListView();
                                               //new BestandDAO().delete(bestand);
                                               //Item addedItem = app.getDataSource().saveBestand(neuerBestand);
                                              
                                               //andere Option (?)
//                                           app.refreshTable();
                                              
                                               //new BestandDAO().save(bestand);
                                               //HibernateUtil.getSession().save(bestand);    
                                              
                                               app.bestellungAusfuehren();
 
                                              
                                              
                                              
                                              
                               }
                }
               
                @Override
                public void setItemDataSource(Item newDataSource) {
                               //newContactMode = false;
                               if (newDataSource != null) {
                                               List<Object> orderedProperties = Arrays
                                                                              .asList(BestandContainer.NATURAL_COL_ORDER);
                                               super.setItemDataSource(newDataSource, orderedProperties);
                                               setReadOnly(true);
                                               getFooter().setVisible(true);
                               } else {
                                               super.setItemDataSource(null);
                                               getFooter().setVisible(false);
                               }
                }
 
}

And this is my List class. It is a direct child of table.

package ui;
 
import barControlApplication.BarControlApplication;
 
import com.vaadin.data.Property;
import com.vaadin.ui.Table;
 
import data.BestandContainer;
 
public class BestandList extends Table {
               
                               public BestandList(BarControlApplication app) {
                                               setSizeFull();
                                               setContainerDataSource(app.getDataSource());
                                              
                                               /*
                                               * Make table selectable, react immediatedly to user events, and pass
                                               events to the
                                               * controller (our main application)
                                               */
                                               setSelectable(true);
                                               setImmediate(true);
                                               addListener((Property.ValueChangeListener) app);
                                               setNullSelectionAllowed(false);
                                               setVisibleColumns(BestandContainer.NATURAL_COL_ORDER);
                                               setColumnHeaders(BestandContainer.COL_HEADERS_ENGLISH);
                                               //
                                               //enableContentRefreshing(true);
                               }
               
 
}

The listView class is a child of HorizontalSplitPanel and only sets as first component my BestandList and as second component my BestandForm.

First I will try your advice (Thank you!) and will post again.

I added this

app.getDataSource().changeBestand(bestand);
app.bestandCommit(); //calls Commit in BestandForm
commit();
app.tableRefresh(); //calls table.refreshRowCache(); in MainClass.

but it does not work. I also tried it without the two commits respectively with one of the two, but it also does not work.

I googled again for this problem and founded that

refreshRowCache();

was built in Vaadin, because of exactly this problem, but it does not work in my case. So I think I have got a mistake in my code.

I solved the problem. I erased the table, form and listview objects and created new ones. And I had to create a new data source (container) for the table.