JSF Nochmal ACL -+- Neue Entity aus anderen Entitys erstellen

Diskutiere Nochmal ACL -+- Neue Entity aus anderen Entitys erstellen im Web Tier Forum; Guten Tag zusammen !! Ich hab hier im Forum ja schon echt super Hilfe für mein Projekt bekommen da muss ich erstmal echt ein Lob aussprechen...

  1. FINF_AW_Alex
    FINF_AW_Alex Neues Mitglied
    Guten Tag zusammen !!

    Ich hab hier im Forum ja schon echt super Hilfe für mein Projekt bekommen da muss ich erstmal echt ein Lob aussprechen :toll:

    Ich habe gerade ein kleines Problem.
    Ich habe mehrere Entity Objekte (ACL,Benutzer,Gruppe,Methode)

    Ein ACL Objekt besteht aus jeweils einem Eintrag der Objekte (Methode, Gruppe, Benutzer).

    Die Einträge (Benutzer,Gruppe) können "null" sein, der Eintrag Methode hingegen nicht.

    Die Darstellung der Tabellen in Tables oder Selectboxen klappt super, aber beim erstellen eines neuen
    ACL Objektes habe ich das Problem das auch gleichzeitig ein neues Methoden,Gruppen und Benutzer Objekt erstellt und persisiert wird. Dadurch erhalte ich unnötige redundanz in meinen Tabellen(Methode,Gruppe,Benutzer)... :-(

    Hier einmal ein Bild wie es sein sollte(ACL eintrag manuell erstellt):

    001.JPG


    Und hier wie es wirklich ist:

    002.JPG


    Mann sieht auf dem 2ten bild das der ACL Eintrag zwar in dem Sinne korekt ist, aber nicht die auf die vorhandenen Objekte referenziert und stattdessen neue erstellt.... :-/

    Ich glaube das es daran liegt das ich in meinem PresentationModell neue Objekte erstelle und diese dann dem Objekt ACL hinzufüge....

    Code (Java):

    package com.alex.aclgenerator;

    import java.util.List;
    import javax.ejb.EJB;
    import javax.enterprise.context.RequestScoped;
    import javax.inject.Named;

    /**
     *
     * @author schmack
     */

    @Named
    @RequestScoped
    public class AclPM {
       
        private Methode  pm_methode  = new Methode();
        private Gruppe   pm_gruppe   = new Gruppe();
        private Benutzer pm_benutzer = new Benutzer();
        private Acl      pm_acl      = new Acl();
       
        @EJB
        AclBean bean;
       
       
    //---------------------------------------------------

        public Methode getPm_methode() {
            return pm_methode;
        }

        public void setPm_methode(Methode pm_methode) {
            this.pm_methode = pm_methode;
        }

        public Gruppe getPm_gruppe() {
            return pm_gruppe;
        }

        public void setPm_gruppe(Gruppe pm_gruppe) {
            this.pm_gruppe = pm_gruppe;
        }

        public Benutzer getPm_benutzer() {
            return pm_benutzer;
        }

        public void setPm_benutzer(Benutzer pm_benutzer) {
            this.pm_benutzer = pm_benutzer;
        }

        public Acl getPm_acl() {
            return pm_acl;
        }

        public void setPm_acl(Acl pm_acl) {
            this.pm_acl = pm_acl;
        }
       
       
        public List<Methode> getMethods() {
        return bean.getMethods();
        }
       
        public List<Benutzer> getUsers() {
        return bean.getUsers();
        }
       
        public List<Gruppe> getGroups() {
        return bean.getGroups();
        }
       
        public List<Acl> getAcls() {
        return bean.getAcls();
        }
       
       

    //---------------------------------------------------------
       
        public void storeMethod(){
            System.out.println("Methode gespeichert!");
            bean.addEntry(pm_methode);
        }

        public void storeGroup(){
            System.out.println("Gruppe gespeichert!");
            bean.addEntry(pm_gruppe);
        }

        public void storeUser(){
            System.out.println("Benutzer gespeichert!");
            bean.addEntry(pm_benutzer);
        }
       
        public void storeAcl(){
            pm_acl.setMethode(pm_methode);
            pm_acl.setGruppe(pm_gruppe);
            pm_acl.setBenutzer(pm_benutzer);
           
            bean.addAcl(pm_acl);
           
            System.out.println("ACL gespeichert!");
        }
       
    }//endclass
     
    ich würde aber gerne auf die Objekte referenzieren die ich schon in der Selectbox habe....

    003.JPG

    HTML:

                   <p:selectOneMenu id="selectone_methods" value="#{aclPM.pm_methode.name}"
                                    style="margin-left: 5px;">
                        <f:selectItems value="#{aclPM.methods}" var="method"
                                      itemValue="#{method.name}" itemLabel="#{method.name}" />
                    </p:selectOneMenu>            

                   <p:selectOneMenu id="selectone_groups" value="#{aclPM.pm_gruppe.name}"
                                    style="margin-left: 5px;">
                       <f:selectItems value="#{aclPM.groups}" var="group"
                                     itemValue="#{group.name}" itemLabel="#{group.name}" />
                    </p:selectOneMenu>

                   <p:selectOneMenu id="selectone_users" value="#{aclPM.pm_benutzer.name}"
                                    style="margin-left: 5px;">
                        <f:selectItems value="#{aclPM.users}" var="user"
                                      itemValue="#{user.name}" itemLabel="#{user.name}" />
                    </p:selectOneMenu>
     

    ....und keine neuen erstellen......

    Aber wenn ich in der Methode storeAcl() mit gettern anstatt settern versuche zu arbeiten geht das auch nicht.....:bahnhof:

    Ich hoffe ich habe mich einigermaßen verständlich ausgedrückt und hoffe ihr kölnnt mir hier weiterhelfen...

    Grüße, Alex !!
     
    Zuletzt bearbeitet: 24. Nov. 2014
  2. Vielleicht hilft dir dieser Kurs hier weiter --> (hier klicken)
  3. stg
    stg Bekanntes Mitglied
    Du legst ja auch jedes Mal neue Objekte in deiner BusinessLogik an und setzt nur die Attribute auf diejenigen Werte, die anderen Einträge in deiner Datenbank bereits haben.

    Nutze stattdessen dein selectOneMenu, um direkt die Objekte zu setzen, und nicht deren Inhalt. Schaue dir dazu die Klasse SelectItem und Converter an.

    Dein JSF code sollte danach ungefähr so aussehen:
    HTML:

    <p:selectOneMenu id="selectone_methods" value="#{aclPM.pm_methode.name}">
        <f:selectItems value="#{aclPM.methodItems}" />
        <f:converter binding="#{...myConverter}" />
    </p:selectOneMenu>  
     
     
  4. FINF_AW_Alex
    FINF_AW_Alex Neues Mitglied
    Huaaah... Ich versuche den Satz zu verstehen aber bekomme ihn nicht ganz in meinen Kopf....

    Könntest Du mir das irgendwie veranschaulichen?

    Die neuen Objekte im PM brauche ich ja auch um in der View die Tables und SelectBoxen füllen zu können, also entfernen kann ich die nicht... :-(

    HTML:

    <p:selectOneMenu id="selectone_methods" value="#{aclPM.pm_methode.name}"
     
    meinst du das ich hier vielleicht anstatt auf das Objekt pm_methode und das property name auf was anderes referenzieren sollte?


    -----------------

    mein selectItems Tag gibt eine List<Methode> aus, das ist doch ok oder?

    Code (Java):

        public List<Methode> getMethods() {
             Query query = em.createQuery("SELECT data FROM Methode data");        
             List<Methode> resultList = query.getResultList();        
            return resultList;
        }
     
     
  5. stg
    stg Bekanntes Mitglied
    Du sollst aber nicht einfach ein ganz neues Objekt erstellen und bei diesem dann den Namen setzen, sondern du setzt die Referenz auf genau einer der Objekte aus der Liste, die du auch ins SelectOneMenu steckst.
    Insbesondere haben deine neu angelegten Objekte ja eine andere (bzw noch gar keine) ID, als die, die in der Datenbank stehen.


    Ja, und zwar direkt auf pm_methode. Die Stelle ist mir beim anpassen den Codes durch die Lappen gegangen. Es sollte heißen:
    HTML:

    <p:selectOneMenu id="selectone_methods" value="#{aclPM.pm_methode.name}"
     

    Ja, fast ok. Was jedoch nicht ok ist, ist die Datenbank-Abfrage in der getter-Methode durchzuführen. Die getter-Methode sollte wirklich nur (!) die entsprechende Liste zurückgeben.
    Initialisiere die Liste einmalig z.B. in einer PostConstruct-Methode (oder, sofern möglich, auch meinetwegen im Constructor).
     
  6. stg
    stg Bekanntes Mitglied
    HTML:

    <p:selectOneMenu id="selectone_methods" value="#{aclPM.pm_methode}"
     
    !!!!!!!

    Ich sollte echt mal schafen gehen..... :shock:
     
  7. FINF_AW_Alex
    FINF_AW_Alex Neues Mitglied
    Hey stg :meld:

    Danke für Deine Hilfe, weiss ich wirklich zu schätzen !! :applaus:

    Aber weißt Du was? Ich glaube mein Problem liegt an einer ganz anderen Stelle.

    Jedes Mal wenn ich ein neues Acl-Objekt erstelle, wird auch gleichzeitig ein neues Benutzer, Gruppen und Methoden Objekt erstellt.

    So kann ja nur Redundanz entsehen...
    Das liegt daran das ich die Entity ACL wie folgt aufgebaut habe:

    Code (Java):

    @Entity
    public class Acl implements Serializable {
        private static final long serialVersionUID = 1L;
       
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
       
        @OneToOne(optional = false, cascade = CascadeType.ALL)
        @JoinColumn(name="methode",nullable = true)
        private Methode methode;
       
        @OneToOne(optional = false, cascade = CascadeType.ALL)
        @JoinColumn(name="gruppe",nullable = true)
        private Gruppe gruppe;
       
        @OneToOne(optional = false, cascade = CascadeType.ALL)
        @JoinColumn(name="benutzer",nullable = true)
        private Benutzer benutzer;
           
       
    //--------------------------------------------------    
        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public Methode getMethode() {
            return methode;
        }

        public void setMethode(Methode methode) {
            this.methode = methode;
        }

        public Gruppe getGruppe() {
            return gruppe;
        }

        public void setGruppe(Gruppe gruppe) {
            this.gruppe = gruppe;
        }

        public Benutzer getBenutzer() {
            return benutzer;
        }

        public void setBenutzer(Benutzer benutzer) {
            this.benutzer = benutzer;
        }
       

    //--------------------------------------------------
        @Override
        public int hashCode() {
            int hash = 0;
            hash += (id != null ? id.hashCode() : 0);
            return hash;
        }

        @Override
        public boolean equals(Object object) {
            // TODO: Warning - this method won't work in the case the id fields are not set
            if (!(object instanceof Acl)) {
                return false;
            }
            Acl other = (Acl) object;
            if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
                return false;
            }
            return true;
        }

        @Override
        public String toString() {
            return "" + id;
        }
       
    }
     
    Ich habe den Aufbau aus einem JPA Buch und ich glaube daran müsste ich was ändern um das Problem zu lösen.

    Was ich ja eigentlich will ist kein neues Objekt vom Typ Benutzer, Gruppe und Methode sondern nur die Referenz auf ein Attribut der ausgewählten Objekte.

    Aber wie stelle ich das am besten dar?

    Ok, die Objekte müssen aus der KLasse raus, oder?

    Aber mache ich stattdessen dann Strings mit den Inhalten? Ne, oder??

    Ich habs immer noch nicht ganz........:noe::rolleyes::bahnhof:
     
  8. FINF_AW_Alex
    FINF_AW_Alex Neues Mitglied
    Och verdammt....

    Ich habe jetzt die Entity Klasse Acl und das PresentationModel AclPM umgeändert:

    Acl-Entity:
    Code (Java):

    @Entity
    public class Acl implements Serializable {
        private static final long serialVersionUID = 1L;
       
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
       
        @OneToOne(optional = false, cascade = CascadeType.ALL)
        @JoinColumn(name="methode",nullable = true)
        private String methodenname;
       
        @OneToOne(optional = false, cascade = CascadeType.ALL)
        @JoinColumn(name="gruppe",nullable = true)
        private String gruppenname;
       
        @OneToOne(optional = false, cascade = CascadeType.ALL)
        @JoinColumn(name="benutzer",nullable = true)
        private String benutzername;
     

    AclPM:
    Code (Java):

        public void storeAcl(){
            pm_acl.setMethodenname(pm_methode.getName());
            pm_acl.setGruppenname(pm_gruppe.getName());
            pm_acl.setBenutzername(pm_benutzer.getName());
           
            bean.addAcl(pm_acl);
           
            System.out.println("ACL gespeichert!");
        }
     

    Leider geht das wohl auch nicht denn ich bekomme beim Deployen jedesmal diese Exception.....

    Exception Description: [class com.alex.aclgenerator.Acl] uses a non-entity [class java.lang.String] as target entity in the relationship attribute [field gruppenname].

    Muss ich jetzt ganz neue Entityklassen für meine ACL-Entity erstellen damit ich die Redundanz in den anderen Tabellen umgehen kann?

    Grüße und einen schönen Guten Morgen !!!

    Alex
     
    Zuletzt bearbeitet: 26. Nov. 2014
  9. stg
    stg Bekanntes Mitglied
    Deine Entity aus Beitrag #6 sah gut aus, die im folgenden Beitrag #7 ist Murks...
     
  10. stg
    stg Bekanntes Mitglied
    Ja, genau!

    Siehe Beitrag #2 und #4

    Du bekommst eine Liste von z.B. Methoden von deinem JPA-Controller. Das Feld vom Typ Methode in deinem neuen Entity-Objekt, welches du anlegen möchtest, setzt du nun auf genau eine Methoden-Referenz aus dieser Liste (bzw kann das auch ein gänzlich neues Objekt sein, Hauptsache ist, dass der Vergleich mit equals true zurückgibt, aber du hast ja die Liste vorliegen, also wieso nicht einfach eins daraus auswählen)
    Momentan nimmst du dir nur den Methoden-Namen und setzt diesen, was du aber machen solltest, ist die Methoden-Referenz zu setzen. Steht aber auch schon in Beitrag #4, nur mit dem Copy&Paste-fehler, den ich danach in Beitrag #5 verbessert habe :)
     
    Zuletzt bearbeitet: 26. Nov. 2014
  11. FINF_AW_Alex
    FINF_AW_Alex Neues Mitglied
    Ja, das hatte ich eigentlich schon verstanden....glaube ich ^^

    liste.jpg

    feld.jpg

    Genau das mache ich doch, oder?
    pm_acl ist ein neues Acl Objekt welches im der Klasse AclPM bereitgestellt wird.
    Davon wähle ich das Feld Methode aus in welches geschrieben werden soll.

    aber:

    fehler.jpg

    klappt nicht, der Eintrag wird nicht geschrieben.... (in glaube er findet die Einträge nicht)

    und damit bin ich wieder auf dem stand von hier:
    http://www.java-forum.org/web-tier/163646-mehrere-selectone-persistieren.html


    ;(;(;(
     
    Zuletzt bearbeitet: 26. Nov. 2014
Die Seite wird geladen...

Nochmal ACL -+- Neue Entity aus anderen Entitys erstellen - Ähnliche Themen

Unique ID nochmal Unique machen
Unique ID nochmal Unique machen im Forum Java Basics - Anfänger-Themen
Superklasse nochmals erzeugen?
Superklasse nochmals erzeugen? im Forum Java Basics - Anfänger-Themen
Nochmal Realm, Unix, Windows
Nochmal Realm, Unix, Windows im Forum Web Tier
Nochmals: ID ermitteln nach Insert
Nochmals: ID ermitteln nach Insert im Forum Datenbankprogrammierung
Wenn Exception dann nochmal try.
Wenn Exception dann nochmal try. im Forum Java Basics - Anfänger-Themen
Thema: Nochmal ACL -+- Neue Entity aus anderen Entitys erstellen