Hibernate Mapping - Nur eine Spalte per Join aus anderer Tabelle holen

Dieses Thema Hibernate - Mapping - Nur eine Spalte per Join aus anderer Tabelle holen im Forum "Data Tier" wurde erstellt von peez, 5. Feb. 2013.

Thema: Mapping - Nur eine Spalte per Join aus anderer Tabelle holen Ich habe ein Hibernate-Mapping und nur eine Spalte daraus soll per Join aus einer anderen Tabelle (nur lesend, muss...

  1. Ich habe ein Hibernate-Mapping und nur eine Spalte daraus soll per Join aus einer anderen Tabelle (nur lesend, muss nicht schreiben können) geholt werden. Der Unterschied zu 90% der Beispiele aus dem Netz ist, dass der FK nicht in der zweiten Tabelle sitzt, sondern in der ersten. Hier mein Beispiel.

    Ich habe diese beiden Tabellen:
    Code (Text):

    PERSON
    -----------------------------
      personId
      personName
      FKadresseId

    ADRESSE
    -----------------------------
      adresseId
      ort
      strasse
     
    Im Mapping soll zum Namen der Person lediglich der Ort auftauchen.

    Das habe ich jetzt so gemacht (funktioniert leider nicht):
    [XML]
    <!-- .... -->
    <property name="name" column="personName" type="java.lang.String" />

    <join table="ADRESSE">
    <key column="FKadresseId" />
    <property name="ort" column="ort" type="java.lang.String" insert="false" update="false" />
    </join>
    [/XML]

    Leider baut Hibernate den Join falsch rum auf. Es kommt sowas in der Art raus:

    Code (SQL):
    SELECT personName, ort
    FROM PERSON
    INNER JOIN ADRESSE ON PERSON.personId = ADRESSE.FKadresseId
    Das heißt er geht davon aus, dass der ForeignKey in der ADRESSE-Tabelle ist, statt in meiner Haupt-Tabelle (PERSON).
    Hat jemand eine Idee wie ich das anders rum machen könnte? Zur Not auch mit Subselect / formula o.ä...
     
  2. Vielleicht helfen dir diese Java-Grundlagen weiter --> *Klick*
  3. Moin,

    es ist zwar nicht der weg den du einschlagen willst aber warum benutzt du nicht einfach die JPQL ?

    Code (Java):

     EntityManagerFactory emf = Persistence.createEntityManagerFactory("PersistenceUnit");

    Query q = emf.createEntityManager().createQuery("Hier deine SQL-Abfrage mit der JPQL");
     
    q.setParameter("a", "Parameter falls gebraucht");

     
    Ich mag mich persönlich bei solchen sachen nicht auf Hibernate verlassen und baue meine Abfragen immer selbst auf. Zum wiederverwenden kann man daraus ja ein NamedQuery machen.


    LG
     
  4. Naja - die Umgebung ist eben 100% auf Businessobjekten aufgebaut.
    Sache ist, bisher war der "ort" als String in der Personentabelle gespeichert und zusätzlich per Fremdschlüssel die Adresse-Tabelle referenziert.

    Jetzt ist aufgefallen (oh Wunder :lol:), dass wenn jemand was in der Adresse-Tabelle ändert, der Ort beim Anzeigen nicht aktualisiert wird.
    Und er Ort wird halt an zig Stellen über das Businessobjekt mit .getOrt() angesprochen.
    Da jetzt überall noch ein JPQL dazwischenzuschalten halte ich für unnötigen Aufwand (und unnötige verkomplizierung im Code), wenn Hibernate das schon so ins Bo reinjoinen kann...

    Ganz abgesehen von der Performance - ein einzelner Join gegen zig zusätzliche Selects...
     
  5. Zjaa wenn euch das schon aufgefallen ist, dann wäre es ja mal angebracht sich die Entitys näher anzuschauen ;)

    Wenn du sie posten magst? Ich denke mal ihr habt da an der ein oder anderen Stelle die falschen Beziehungen / Annotationen.

    btw: Ein NamedQuery macht da auch nichts anderes, wie du schon geschrieben hast baut Hibernate einen Join auf. Das kann man auch mit NamedQuerys und auch so ablegen, das man nicht überall ein Query im code braucht. ( z.B. einen zusätzlichen getter im Entity ;) ).
     
  6. Nein ich will da eigentlich keine NamedQuery oder sonst was zusätzliches verwenden..

    Genau dafür gibts doch Entities / Businessobjekte.
    1. Damit man sich um die zugrundeliegenden Selects - egal ob SQL oder HQL / JPQL - keine größeren Gedanken machen muss wenns mal initial eingerichtet ist.
    2. Dass sich bei Bedarf die zugrundeliegende Datenstruktur ändern kann ohne an allen Stellen Anpassungen vorzunehmen.
     
  7. Code (Java):

    import java.io.Serializable;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;

    /**
     *
     * @author david
     */

    @Entity(name="person")
    public class Person implements Serializable, Comparable<Person> {

        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;

        private String name;
        //das hier ist wichtig
        @OneToOne(mappedBy="person")
        private Adresse adresse;
       
       //restliche getter und setter blah sülz

      public String getOrt(){
       return this.adresse.getOrt();
       }



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

        @Override
        public boolean equals(Object object) {
           
            if (!(object instanceof Person)) {
                return false;
            }
            Person other = (Perso) 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 "de.paket.Person[ id=" + id + " ]";
        }
       
        @Override
        public int compareTo(Person person){
            //oder was auch immer
            return this.name.compareTo(person.name);
        }
       
    }
     
     
  8. KOSTENLOSES Java-Grundlagen Training im Wert von 39 € Sichere dir hier den kostenlosen Zugriff auf umfangreiches Java-Know How und starte richtig durch!