Verknüpfung auflösen für Frontend

DaBe1812

Bekanntes Mitglied
Hi,

ich stehe gerade vor einem Problem für mein Frontend, dass ich nicht weiß, wie ich meine Daten richtig darstellen soll. Erstmal die Datenstrukturen, um die es geht:
Die Entität, die dargestellt werden soll ist ein Auftrag mit dem beispielhaften Aufbau:
Java:
@Entity
@Table(name = "OBJ_ORDER")
public class WindowsOrder implements SearchableEntity {

    @Id
    @Column(name = "UUID", length = 36)
    private String uuid;
    
    @Column(name = "ORDER_NO")
    private Integer orderNo;
    
    @Column(name = "POS_NO")
    private Integer posNo;
    
    @Column(name = "ORDER_TYPE", length = 50)
    @Enumerated(EnumType.STRING)
    private OrderType orderType;
    
    @ManyToOne
    @JoinColumn(name = "TRANSMISSION_TYPE", referencedColumnName = "UUID" )
    private KeyValue transmissionType;
    
    @ManyToOne
    @JoinColumn(name = "INSTITUTE_UUID", referencedColumnName = "UUID" )
    private Institute client;
}
Das "Problem" Daran ist Institute, das sieht nämlich so aus:
Java:
@Entity
@Table(name = "OBJ_CLIENT")
public class Institute {

    @Id
    @Column(name = "UUID", length = 36)
    private String uuid;

    @OneToMany(mappedBy = "institute")
    private Set<InstituteData> timeslices;
}
Denn dies ist nur ein Sammler für die Historie der Institute. Die eigentlichen Werte sind in der Entität InstituteData:
Java:
@Entity
@Table(name = "OBJ_CLIENT_DATA")
public class InstituteData extends TimeSlice{

    @Id
    @Column(name = "UUID", length = 36)
    private String uuid;
    
    @JoinColumn(name = "CLIENT_UUID", referencedColumnName = "UUID")
    private Institute institute;
    
    @Column(name = "CLIENT_STATE",length = 50)
    @Enumerated(EnumType.STRING)
    private InstituteState state;

    @Column(name = "CLIENT_NO",length = 8)
    private String clientNo;

    @Column(name = "CLIENT_NAME",length = 255)
    private String clientName;

    @Column(name = "CLIENT_WORKPLACES")
    private Integer workplaces;
}

Theoretisch kann sich in der Lebenszeit eines Institutes auch der Name ändern.

Für das Frontend soll das ungefähr so aussehen:
HTML:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui">

    <p:tabView>
        <p:tab title="Auftrag">

            <p:panel header="Eingang">
                <p:panelGrid columns="8">
                    <p:outputLabel for="@next" value="Auftrag-Nr." />
                    <p:inputText value="#{proIpsSearchHandler.selectedDetailEntity.orderNo}" required="true">
                        <f:validateLength minimum="5" />
                    </p:inputText>

                    <p:outputLabel for="@next" value="Pos-Nr." />
                    <p:inputText value="#{proIpsSearchHandler.selectedDetailEntity.posNo}" required="true" />

                    <p:outputLabel for="@next" value="Auftragsart" />
                    <p:selectOneMenu value="#{proIpsSearchHandler.selectedDetailEntity.orderType}" required="true">
                        <f:selectItems value="#{windowsOrderHandler.orderTypes}" />
                    </p:selectOneMenu>

                    <p:outputLabel for="@next" value="Eingangsart" />
                    <p:selectOneMenu value="#{proIpsSearchHandler.selectedDetailEntity.transmissionType}" required="false">
                        <f:selectItems value="#{windowsOrderHandler.transmissionTypes}" var="trantype" itemValue="#{trantype}" itemLabel="#{trantype.displayname}"/>
                    </p:selectOneMenu>

                    <p:outputLabel for="@next" value="Mandant" />
                    <p:selectOneMenu value="#{proIpsSearchHandler.selectedDetailEntity.client}" required="false">
                        <f:selectItems value="#{windowsOrderHandler.institues}" var="inst" itemValue="#{inst}" itemLabel="#{inst.clientNo}" itemDescription="#{inst.clientName}"/>
                    </p:selectOneMenu>

                </p:panelGrid>
            </p:panel>

    </p:tabView>

</ui:composition>

Das ist so falsch, habe ich festgestellt, weil ich hier zwei Objekte vermische nämlich Institute als value und InstituteData als SelectItem.

Also im Endeffekt möchte ich in den Selectitems zu jedem Institut nur das aktuellste von allen noch aktiven Instituten haben. Das SQL sieht dann ungefähr so aus:
SQL:
select * from obj_client_data c where CONCAT(c.client_uuid, c.valid_date) in
    (select concat(client_uuid, max(valid_date)) from obj_client_data group by client_uuid)
and client_state = 'PRODUCTIVE';

Wie soll ich das denn jetzt im Hintergrund bauen, damit das so funktioniert? Bzw. muss ich vielleicht nur das Frontend anpassen?
 

DaBe1812

Bekanntes Mitglied
Also das Problem ist doch ein wenig komplizierter als "Getting Started". Wenn ich die Daten nehme, wie sie aus der einfachen Abfrage kommen, dann habe ich da ja lediglich die Objektrefferenz im Frontend. Aber ich komme ja erstmal nicht an z.B. die clientNo, weil dafür müsste ich ja wissen, welcher Client gerade aktuell ist.
Ich sehe gerade, dass ich TimeSlice nicht mit aufgeführt habe, aber da drin ist nur ein Feld für einen Start-Timestamp und den Create-User. Ich möchte also die ClientData, deren client_uuid die ist, die im Order-Objekt hinterlegt ist, und wo der Start-Timestamp der größte von denen ist, die kleiner sind, als jetzt.
Gibt es dafür irgendwie eine Bord-Möglichkeit? Oder ist das Problem tatsächlich Basic und ich sehe es nicht?
 

DaBe1812

Bekanntes Mitglied
Okay, ich habe das Problem jetzt doch ein wenig einfacher angegangen, als ich erst dachte, leider passt das Ergebnis nicht ganz. Also erstmal die Änderungen so weit:
Die Einträge für das Dropdown besorge ich mir jetzt mit der Abfrage:
SQL:
select c from InstituteData c where CONCAT(c.institute.uuid, c.validDate) in (
    select concat(b.institute.uuid, max(b.validDate))
    from InstituteData b
    where b.validDate < CURRENT_TIMESTAMP group by b.institute.uuid
) order by c.clientNo
Im Frontend habe ich den Feldwert geändert auf:
HTML:
<p:selectOneMenu value="#{proIpsSearchHandler.selectedDetailEntity.waaClient}" required="false"
        filter="true" filterMatchMode="contains">
    <f:selectItems value="#{windowsOrderHandler.institutes}" var="inst" itemValue="#{inst}" itemLabel="#{inst.clientNo} - #{inst.clientName}" />
</p:selectOneMenu>
WaaClient baue ich folgendermaßen in die Order ein:
Java:
public InstituteData getWaaClient() {
    return client.getCurrentInstituteData();
}

public void setWaaClient(InstituteData instituteData) {
    this.client = instituteData.getInstitute();
}

Die Methode getCurrentInstituteData im Institut sieht dann folgendermaßen aus.
Java:
public InstituteData getCurrentInstituteData() {
    Optional<InstituteData> current;

    List<InstituteData> tempList = new ArrayList<>(timeslices);

    if(timeslices.size() == 1) {
        return tempList.get(0);
    }

    Comparator<InstituteData> getActual;
    getActual =  new Comparator<InstituteData>() {
        @Override
        public int compare(InstituteData i1, InstituteData i2) {
            if(i1.getValidDate().isAfter(LocalDateTime.now())) return -1;
            if(i2.getValidDate().isAfter(LocalDateTime.now())) return 1;
            if(i1.getValidDate().isAfter(i2.getValidDate())) return 1;
            if(i2.getValidDate().isAfter(i1.getValidDate())) return -1;
            return 0;
        }
    };

    current = tempList.stream().max(getActual);

    if(current.isPresent()) {
        return current.get();
    }
    return null;
}
Die Methode liefert auch genau den Datensatz, den ich an der Stelle erwarte. In der Liste der Datensätze aus windowsOrderHandler.institutes ist der Datensatz auch drin, aber bei der Anzeige wird der erste Satz der Liste angezeigt, nicht der, der im Datensatz hinterlegt ist.
 

Oneixee5

Top Contributor
Du kannst ja value="#{proIpsSearchHandler.selectedDetailEntity.waaClient}" mal ausgeben, dann sieht man ja was da wirklich drin steht. Der erste Eintrag wird meistens angezeigt, weil nichts passendes gefunden wird.

select c from InstituteData c where CONCAT(c.institute.uuid, c.validDate) in ( select concat(b.institute.uuid, max(b.validDate)) from InstituteData b where b.validDate < CURRENT_TIMESTAMP group by b.institute.uuid ) order by c.clientNo
Die Abfrage ist total lost. Nicht nur, dass hier überhaupt kein Index verwendet werden kann, auch das Ergebnis kann falsch sein. Wenn c.institute.uuid auf eine Ziffer endet, dann kann je nach dem Datumsformat in c.validDate etwas falsches herauskommen. Das maximale Datum einer Gruppe kann man mit einer Window-Funktion einfach und vor allem schnell ermitteln. Dann ist meistens auch gar kein Self-Join mehr notwendig. Aber wenn Self-Join, dann wenigstens über die ID der Tabelle. Wenn man für die Window-Funktion Hibernate nicht direkt verwenden will, kann man immer noch eine JPA-Native-Query verwenden.
 

DaBe1812

Bekanntes Mitglied
Den Value habe ich mir auch schon ausgeben lassen, aber mangels toString() Methode kam dabei nur die Objektrefferenz raus.
Habe dann nochmal clientNo und clientName ausgeben lassen und das war wie erwartet das was ich auch in der Datenbank hinterlegt habe. Also an der Stelle schon mal alles gut.
Dass er den ersten Eintrag schreibt, weil er keinen passenden in der Liste findet, hatte ich schon in früheren Fällen, da hatte ich aber auch gravierend was falsch gemacht. Hier verstehe ich es nicht, weil der passende Datensatz ja eigentlich in der Liste ist, ich weiß aber nicht, wie er den Vergleich anstellt, evtl. ist das ja auch ein Referenz-Problem?
Die Abfrage ist total lost.
Okay, wie sich hier JPQL und SQL unterscheiden, weiß ich nicht, aber bei Oracle ist der Timestamp immer gleich lang und die UUID hat immer dieselbe Anzahl Zeichen. Leider habe ich kein Hibernate in dem Projekt, sondern EclipseLink, ist wohl so von der ApplicationServer Seite vorgegeben. Hab zwar ein paar Sachen von Hibernate vermisst, aber bisher die Sache nicht hinterfragt.
Und die Abfrage habe ich als entweder als ähnliches Beispiel damals (an anderer Stelle mache ich das genauso) gefunden, oder sogar mit einem Oracle-Kumpel zusammengebaut.
Aber ich werde mir die Window-Funktion mal anschauen.
 

Oneixee5

Top Contributor
Muss denn in <p:selectOneMenu value="???" nicht die ID rein? Also das was itemValue entspricht? Bei dir glaub ich die UUID. Da darf keine Object-Reference herauskommen.
HTML:
                <p:selectOneMenu id="option" value="#{<hier etwas was itemValue='Option1/2/3' entspricht}>}">
                    <f:selectItem itemLabel="Select One" itemValue=""/>
                    <f:selectItem itemLabel="OptionA" itemValue="Option1"/>
                    <f:selectItem itemLabel="OptionB" itemValue="Option2"/>
                    <f:selectItem itemLabel="OptionC" itemValue="Option3"/>
                </p:selectOneMenu>
 

DaBe1812

Bekanntes Mitglied
Ja, da muss der Value des Feldes rein, in dem Fall also ein InstitutData-Objekt und die Liste ist auch eine Liste von InstitutData, also Objektarten mäßig ist es schon mal gleich.

Hab aber aufgrund der Ladezeiten das Ganze jetzt umgestellt. In dieser Maske werden jetzt nur die Werte aus den Feldern als normales Feld angezeigt. Funktioniert prima und die Ladezeit liegt unter 1s.
Die von dir bemängelte Suche habe ich nochmal angepasst, da ich aber das Window-Prinzip nicht richtig verstanden habe musste ich auf eine NativeQuery zurückgreifen, weil die JPQL-Version führt zu einem Fehler.
SQL:
select a.*
from obj_client_data a,
(
    select client_uuid,
        max(valid_date) as valid_date
    from obj_client_data
    where valid_date < SYSDATE
    group by client_uuid
) b
where a.client_uuid = b.client_uuid
and a.valid_date = b.valid_date
Jetzt können alle Werte so unterschiedlich sein, wie sie wollen, das Matching ist immer eindeutig.

Wegen der Ladezeiten habe ich jetzt ein anderes Problem, aber das hat nichts mit der DB zu tun, deswegen setze ich das in einem anderen Forum fort.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M PostgreSQL Hibernate Verknüpfung zweier Klassen Datenbankprogrammierung 11
G Hibernate ManyToMany Verknüpfung Datenbankprogrammierung 3
sparrow [Hibernate] Die Liste einer Verknüpfung selber setzen Datenbankprogrammierung 2
R Beste Lösung für User Erstellung in mongodb Datenbankprogrammierung 1
I SaaS Applikation: pro Kunde eine Datenbank / Schema oder eine DB für alle Kunden? Datenbankprogrammierung 76
O apache derby in eclipse für Datenbanken einbauen Datenbankprogrammierung 3
Zrebna Empfehlung für ein kostenloses DB-Hosting gesucht Datenbankprogrammierung 6
M Lösungsvorschläge für Multi-User Datenbankprogrammierung 1
M Alle Records Felder kriegen für DB Abfrage Datenbankprogrammierung 14
pkm PostgreSQL Kann mit mybatis einen Parameter für eine postgreSQL-Abfrage nicht übergeben. Datenbankprogrammierung 5
Kirby.exe Denkanstoß für Ranking Datenbankprogrammierung 1
L Oracle Repräsentative Namen für die Column Types Datenbankprogrammierung 9
OnDemand Struktur für Parent / Child Produkt Datenbankprogrammierung 5
N ORM für Sqlite Datenbankprogrammierung 4
I Konzept: Klasse / Entity für Einstellung der Software Datenbankprogrammierung 3
H suche eine Login system Bibliothek für Java Datenbankprogrammierung 5
ruutaiokwu MySQL MariaDB-Client-Zertifkate, nur für einen bestimmten User Datenbankprogrammierung 5
B Datenmodell für Regeln + Bedingungen & Referenz auf andere Tabelle Datenbankprogrammierung 12
O Dokumentation für MariaDB 10.3. Datenbankprogrammierung 2
F MariaDatabase Einstellungen für Verbindungen Datenbankprogrammierung 5
Dimax MySQL Trigger für eine Spalte Datenbankprogrammierung 5
Dimax MySQL Maximale Datenlänge für eine Spalte einer Datenbank in java ermitteln Datenbankprogrammierung 15
platofan23 MySQL Java Programm findet Treiber für mySQL auf Debian-Server nicht? Datenbankprogrammierung 11
B Brauche Tipps für Datenbankdesign Datenbankprogrammierung 8
B Tabelle für "wiederkehrende Rechnungen" Datenbankprogrammierung 12
Danloc Informationen für Datenbankverbindung wo/wie speichern? Datenbankprogrammierung 11
J Warum sind Sockets für einen Live-Chat sinnvoll? Datenbankprogrammierung 8
R Java-Befehle/Operatoren für copy&paste Datenbankprogrammierung 2
X PostgreSQL Datenbankdesign für Vokabeltrainer Datenbankprogrammierung 48
@SupressWarnings() HSQLDB Datenbank für mein Dorfbauspiel "Time of Kings" Datenbankprogrammierung 6
M Idee Umsetzung //NFC Eintrittskarten für Geburtstag Datenbankprogrammierung 2
looparda Architektur für JPA Hibernate Umstieg Datenbankprogrammierung 14
P Datanbank für Java-Programmierung Datenbankprogrammierung 10
M Feedback für neues Buch über "Java und Datenbanken" erwünscht Datenbankprogrammierung 8
J SQLite Ich muss für mein Projekt meine Datenbank Kapseln Datenbankprogrammierung 2
J Tipps für ERM Datenbankprogrammierung 4
P Highlevel-Lösung für Speicherung von Baumstruktur mit unbekannter Tiefe Datenbankprogrammierung 1
F welche Datenbank für Messwerte? Datenbankprogrammierung 4
E Warum werden für Datenbanktabellen Schemanamen festgelegt? Datenbankprogrammierung 1
M DB Schema für Vokabeltrainer Datenbankprogrammierung 2
U SQLite Für mich etwa komplexe Abfrage via 2 Tabellen Datenbankprogrammierung 5
E Kann man, wenn man in DB2 Tabellen erstellt hat für dessen auch einen Command-File erstellen? Datenbankprogrammierung 1
T NoSQL Connection für die Thesis [GWT] Datenbankprogrammierung 1
J SQLite Abfrage ausführen stoppt für Zyklus? Wie es zu lösen? Datenbankprogrammierung 3
S HSQLDB Fehlermeldung für den Bildschirm Datenbankprogrammierung 3
L Datenmodell erstellen für eine Nutzertanalyse Datenbankprogrammierung 1
I Query für Geburtstage Datenbankprogrammierung 6
L Zentrale Datenbank im Internet für Spiele Highscores? Datenbankprogrammierung 1
P Derby/JavaDB Csv Datei für dieses Musterprogramm Datenbankprogrammierung 12
ruutaiokwu code-formatter für t-sql... Datenbankprogrammierung 12
J Plug-In-Framework für Hibernate-Klassen Datenbankprogrammierung 0
T Mehrsprachigkeit für Tabellenfelder Datenbankprogrammierung 6
E MySQL Große Datenmengen reibungslos speichern für Gameserver Datenbankprogrammierung 6
F MSSql oder MongoDB für die Speicherung von POI Datenbankprogrammierung 9
G SQLite SQLite Select für View vereinfachen/optimieren Datenbankprogrammierung 4
P MySQL Historie für ein Objekt anlegen Datenbankprogrammierung 5
P MySQL eine richtige Datenbank für einen routenplaner erstellen Datenbankprogrammierung 2
K JDBC- In Java "stored procedure" erstellen für DB2,OracleSql ... Datenbankprogrammierung 3
J Datenbank für Fragen/ Antworten Datenbankprogrammierung 7
O Datenbankschnittstelle für Java Datenbankprogrammierung 8
L Datenbank für kleinere Anwendungen Datenbankprogrammierung 3
N Query für Derby DB mit Enterbrise Bean Datenbankprogrammierung 4
S ich brauche tipps für JDBC Datenbankprogrammierung 4
I Hibernate - Best Practice für Lazy Loading Datenbankprogrammierung 3
R MySQL Voraussetzungen für eine erfolgreiche Datenbankanbindung mittels JDBC Datenbankprogrammierung 2
GianaSisters SQL Befehl für allgemeine Datenbankexistenz Datenbankprogrammierung 4
B Beispiel für sicheres DBUsername/DBPassword handling Datenbankprogrammierung 4
I Anfänger-Tutorial für Hibernate gesucht Datenbankprogrammierung 3
heart_disease Beratung für Datenbankdesign Datenbankprogrammierung 13
C Embedded DB für Java Datenbankprogrammierung 26
J Unterstützung für verschiedene Datenbanken Datenbankprogrammierung 2
L MySQL Probleme mit PreparedStatement für SQL-Abfrage in Java Datenbankprogrammierung 2
F suche Erstanschub für DB-Zugriff Datenbankprogrammierung 9
F MySQL SQL Abfrage für u.a. Spaltenname key Datenbankprogrammierung 4
T ResultSet befehl für leere Spalte nicht lesen Datenbankprogrammierung 4
F Performance-Tool für Oracle Datenbankprogrammierung 2
T Kleine Tabellen für schnellere abfragen? Datenbankprogrammierung 3
C Split String für SQl query Datenbankprogrammierung 10
A update methode für datenbank Datenbankprogrammierung 2
N Datenbank für Dateien Datenbankprogrammierung 6
N Datenbank für einen Stundenplan Datenbankprogrammierung 4
G welche Datenbanktabellen für folgende Attribute Datenbankprogrammierung 3
R Connection Problem für eine externe DB mit Java (JDBC) Datenbankprogrammierung 9
S JPA (EntityManager für jeden Nutzer?) Datenbankprogrammierung 8
J Buffer Manager für Datenbank Datenbankprogrammierung 4
F SQL Voraussetzung für JDBC? Datenbankprogrammierung 10
R Bei Webformular DropDown Felder JA, NEIN! Was für einen Datentyp verwenden? Datenbankprogrammierung 7
T SSL Zertifikat für mysql datenbankzugriff Datenbankprogrammierung 6
T Debugger für SQL? Datenbankprogrammierung 5
Chtonian Effizientes Query System für Wortnachschlagewerk Datenbankprogrammierung 9
G Tabelle für Zeitraum sperren Datenbankprogrammierung 4
A Struct für Datenbank abfrage? Datenbankprogrammierung 12
O Hibernate für Eclipse Datenbankprogrammierung 5
T JPQL Query für eine Tabellenansicht Datenbankprogrammierung 2
D Sicherheit für Datenbankverbindung Datenbankprogrammierung 19
S Standard für Datenbanken Datenbankprogrammierung 3
R Entfernte MySQL Datenbank für lokale Swing-App Datenbankprogrammierung 8
Landei Mehre Werte für einen Prepared-Statement_Parameter übergeben? Datenbankprogrammierung 3
G Einheitliches Casting für Decimal und Integer-Werte Datenbankprogrammierung 5
G TippSpiel für Bundesliga programieren Datenbankprogrammierung 4

Ähnliche Java Themen

Neue Themen


Oben