JPA Datenbankabfrage bei jedem Request?!

Dieses Thema JPA - Datenbankabfrage bei jedem Request?! im Forum "Web Tier" wurde erstellt von BuckRogers, 18. Nov. 2014.

Thema: Datenbankabfrage bei jedem Request?! Guten Morgen zusammen, eventuell bin ich da etwas komplett falsch angeganegen. Folgendes Problemchen offenbart...

  1. Guten Morgen zusammen,

    eventuell bin ich da etwas komplett falsch angeganegen.
    Folgendes Problemchen offenbart sich in meinem Progrämmchen:
    Bei jedem Request wird in einer bestimmten Bean immer wieder die Datenbankabfrage ausgeführt, obwohl ich die Action/Methode nicht aufrufe.

    System: JBossAS7.1.1-final, javeEE6, mysql5.5, ejb3.1, JSF mit Primefaces

    server.log
    Code (Text):

    07:42:25,568 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:25,576 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:26,783 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:26,787 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:26,792 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:26,798 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:26,806 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:26,813 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:26,824 INFO  [com.webApplication.navigation.NavigationBean] (http--127.0.0.1-8080-6) selected content: PROFILE
    07:42:29,359 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:29,362 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:29,365 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:29,368 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:29,373 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:29,377 INFO  [com.webApplication.beans.OrderFormBean] (http--127.0.0.1-8080-6) attempting to load orderInfo data from database of user: dentist
    07:42:29,381 INFO  [com.webApplication.navigation.NavigationBean] (http--127.0.0.1-8080-6) selected content: PROFILE

     
    Die orderInfo-Daten werden abgerufen obwohl ich ganz andere Navigation vornehme. In diesem Fall navigiere ich zum user-profile, welches nichts mit der Bestellung etc. zu tun hat.

    Managed Bean zur Bestellung:
    Code (Java):

    @Named
    @RequestScoped
    public class OrderFormBean{

        Logger log = Logger.getLogger(OrderFormBean.class);

        @Inject
        OrderInfoManager orderManager;

        List<OrderInfo> orders;

        public List<OrderInfo> getOrders(HttpServletRequest request){
            HttpSession session = request.getSession();
            log.info("attempting to load orderInfo data from database of user: " +   ((User)session.getAttribute("loggedInUser")).getLoginName());
            orders = orderManager.getOrderByDentistNumber("5678");
            return orders;
        }

        public List<OrderInfo> getOrders() {
            return orders;
        }
    }
     
    OrderManager:
    Code (Java):

    @Stateless
    public class OrderInfoManager {

        @PersistenceContext(unitName = "MySqlDS")
        EntityManager manager;

        public void persistOrderInfo(OrderInfo given) throws OrderException {
            try {
                manager.persist(given);
            } catch (Exception e) {
                throw new OrderException("Unable to persist OrderInfo: " + given.getOrderNum(), e.getCause());
            }
        }

        public List<OrderInfo> getOrderByDentistNumber(String dentistNum) {
            List<OrderInfo> orders;
            try {
                orders = (List<OrderInfo>) manager.createNamedQuery("OrderInfo.byDentistNum").setParameter("dentistNum", dentistNum).getResultList();
            } catch (NoResultException e) {
                return null;
            }
            return orders;
        }

    }
     
    View:
    HTML:

    <p:dataTable value="#{orderFormBean.getOrders(request)}"
                var="o"
                paginator="true"
                rows="10">

        <f:facet name="header">
            Documents of orders
        </f:facet>

        <p:column width="100" headerText="Bestellnummer">
            <h:outputText value="#{o.orderNum}"/>

        </p:column>
        <p:column width="100" headerText="Kunde">
            <h:outputText value="#{o.dentist}"/>

        </p:column>
        <p:column width="100" headerText="Kundennummer">

            <h:outputText value="#{o.dentistNum}"/>

        </p:column>
        <p:column width="100" headerText="Bestellbezeichnung">
            <h:outputText value="#{o.orderDesc}"/>

        </p:column>
        <p:column width="100" headerText="Meterialbezeichnung">
            <h:outputText value="#{o.materialDesc}"/>

        </p:column>
        <p:column width="100" headerText="Patient">
            <h:outputText value="#{o.patientRef}"/>

        </p:column>
        <p:column width="100" style="white-space: nowrap" headerText="Liefertermin">
            <h:outputText value="#{o.deliveryDate}"/>
        </p:column>

        <p:column width="100" headerText="Status">
            <h:outputText value="#{o.orderState}"/>
        </p:column>

        <f:facet name="footer"><h:outputLabel value="#{fn:length(orderFormBean.orders)}"/>
            <h:outputLabel value="#{res['orders.table.footer']}"/></f:facet>
    </p:dataTable>
     
    Ich habe leider keine Ahnung woran das liegt. Andere Abfragen, für andere DataTables, habe ich genauso implementiert und dabei geschieht immer nur eine Abfrage. Eventuell kennt jemand diese Problematik oder kann am Code erkennen was da schief läuft. Es ist zwar kein schwerwiegendes Problem, aber nach eigenem wochenlangem suchen und failen brauche ich nun doch Hilfe bei der Angelegenheit.

    Vielen Dank im Voraus.
     
  2. Vielleicht helfen dir diese Java-Grundlagen weiter --> *Klick*
  3. Joose
    Joose Mitarbeiter
    Du könntest dir zusätzlich zu deiner Logmeldung auch den StackTrace ausgeben lassen (diesen kann man auch ohne Exception abfragen).
    Schon kontrolliert von wo die Methode "getOrders(...)" überall aufgerufen wird?
    Vielleicht hast du bei einem zentralen Baustein mal Testweise diesen Aufruf eingebaut und vergessen diesen wieder zu entfernen?
     
  4. So in etwa?

    Code (Java):

    for (int i=0; i< Thread.currentThread().getStackTrace().length; i++)
        System.out.println(Thread.currentThread().getStackTrace()[i].getMethodName());
     
    Werde ich heute Abend mal machen.. Danke ;)
     
  5. stg
    stg
    Typischer Anfängerfehler: Implementiere in diesem Umfeld NIEMALS Business Logic in getter-Methoden! Beim Aufbau der Seite werden die getter-Methoden unter Umständen tatsächlich mehrmals aufgerufen, das ist ganz normal (speziell bei Listen, über die iteriert wird,a lso z.B. im datatable)
    Initialisiere die Liste (und alles, was sonst nötig ist) einmalig in einer PostConstruct Methode oder ähnlichem.

    Dass bei jedem Request eine Abfrage gesendet ist, ist natürlich normal, da deine Bean im RequestScope ist und somit nur für jeden single request verfügbar ist.

    Wenn noch was unklar istl, frag nochmal nach. Ich kann gerade nur zwischen Tür und Angel antworten...
     
  6. Danke,

    ich werde erstmal eine andere Herangehensweise umsetzen und mich dann noch einmal melden ob das Problem gelöst ist oder nicht.
     
  7. Der Stacktrace war nicht hilfreich.
    Habe dann einfach weiter gecodet und neue Seiten, Klassen und Abrufe implementiert. Als ich dann nach ein paar stunden mal deployte, füllten die Abfragen auf orderInfo bereits mehr als eine Bildschirmseite LOG!

    Irgendetwas läuft da gehörig schief. Habe auch mal alle Filter ausgeschaltet, leider ohne Erfolg. Eventuell liegt es an der Seitennavigation, denn die OrderInfo-seite ist immer mein erster Aufruf. Ich werde es erforschen. :p
     
  8. Also ich habe da einen Workaround gefunden, auf die Schnelle. Zwar keine Dauerlösung, aber so werde ich die ständigen Requests los. Es hat bestimmt etwas mit der getterMethode auf sich, wie stg meinte.

    Hier der Workaround:

    HTML:
    <p:commandButton    id="updateOrders"
                       title=".Aktualisieren"
                       actionListener="#{orderFormBean.updateOrders(request)}"
                       update="orderTable"/>
    <p:dataTable    id="orderTable"
                   value="#{orderFormBean.orders}"
                   var="o"
                   paginator="true"
                   rows="10">
    Dabei zieht sich getOrders() nur die Liste und updateOrders(Request) stochert die DB ab. Also recht unschön gelöst. aber so kann ich mal wieder zum testen deployen ohne dass die Platte wegen LogFiles volläuft ^^.
     
    Zuletzt bearbeitet: 19. Nov. 2014
  9. KOSTENLOSES Java-Grundlagen Training im Wert von 39 € Sichere dir hier den kostenlosen Zugriff auf umfangreiches Java-Know How und starte richtig durch!