2009-02-02 14 views
5

Ich habe zwei Tabellen zusammen mit eins-zu-viele Beziehung: Mitarbeiter -> Abteilung: und Beziehung durch department_id in der Mitarbeiter-Tabelle.Hibernate ändern Fetch-Modus in der Laufzeit

Ich benutze Hibernate und meine Hibernate Mapping-Dateien sind:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools 
--> 
<hibernate-mapping default-lazy="false"> 
<class catalog="moi" 
    name="com.ebla.moi.correspondence.model.entity.user.User" table="user"> 
    <id name="id" type="java.lang.Long"> 
    <column name="id"/> 
    <generator class="identity"/> 
    </id> 
    <many-to-one 
    class="com.ebla.moi.correspondence.model.entity.department.Department" 
    fetch="select" name="department"> 
    <column name="department_id"/> 
    </many-to-one> 
    <property generated="never" lazy="false" name="name" type="java.lang.String"> 
    <column length="128" name="name" not-null="true"/> 
    </property> 
    <property generated="never" lazy="false" name="email" type="java.lang.String"> 
    <column length="128" name="email" not-null="true" unique="true"/> 
    </property> 
    <property generated="never" lazy="false" name="maritalStatus" type="java.lang.Short"> 
    <column name="marital_status" not-null="true"/> 
    </property> 
    <property generated="never" lazy="false" name="hireDate" type="java.lang.String"> 
    <column length="64" name="hire_date"/> 
    </property> 
</class> 
</hibernate-mapping> 

und die zweite Zuordnungsdatei ist:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools 
--> 
<hibernate-mapping default-lazy="false"> 
<class catalog="moi" 
    name="com.ebla.moi.correspondence.model.entity.department.Department" table="department"> 
    <id name="id" type="java.lang.Long"> 
    <column name="id"/> 
    <generator class="identity"/> 
    </id> 
    <property generated="never" lazy="false" name="name" type="java.lang.String"> 
    <column length="256" name="name" unique="true"/> 
    </property> 
    <set inverse="true" name="users" sort="unsorted"> 
    <key> 
    <column name="department_id"/> 
    </key> 
    <one-to-many class="com.ebla.moi.correspondence.model.entity.user.User"/> 
    </set> 
</class> 
</hibernate-mapping> 

Mein Problem ist: Manchmal muss ich dem Mitarbeiter seiner Abteilung bekommen und zu anderen Zeiten brauche ich nur die Mitarbeiterinformationen ohne Abteilungsinformationen ..... und das gleiche mit Abteilung mit Mitarbeiter .... mit der Mapping-Datei über den Winterschlaf bringen die Abteilung und es ist Benutzer, wenn ich den Mitarbeiter brauche oder nicht ... wie ich meinen Bedarf zum Winterschlaf definieren kann ätzen genau das, was ich brauche ...

danke

Antwort

10

Man könnte die Beziehung als „faul“ Karte und zwei Abfragen schreiben, um Ihre Daten zu bekommen:

  • Die übliche einfache Abfrage, um Ihre Daten ("faul"). Z.B. "select e from Employee e where ..."

  • Dieselbe Abfrage, die "fetch join" verwendet, um Hibernate zum Abrufen von "childs" zu zwingen. Z.B. "Select e aus Mitarbeiter holen LEFT JOIN e.department wo ..."

LLP, Andrea

8

Sie können ICriteria benutzen, um Ihre Mitarbeiter zu holen.

Sie können die setFetchMode Methode des ICriteria verwenden, um festzustellen, ob die Abteilung geholt werden soll oder nicht:

Dies wird sicherstellen, dass die Abteilung nicht abgerufen wird:

ICriteria crit = theSession.CreateCriteria (typeof(Employee)); 
crit.SetFetchMode ("Department", FetchMode.Lazy) 

Mit diesem Code Die Abteilung wird abgeholt.

ICriteria crit = theSession.CreateCriteria (typeof(Employee)); 
crit.SetFetchMode ("Department", FetchMode.Join) 

Einige sagen, dass es am besten Praxis ist die Standard fetchmode in den Zuordnungen zu verwenden (was faul wäre, glaube ich), und die fetchmode in jedem spezifischen Szenario angeben. (Das heißt, in Ihren Repositories).

+0

Es funktioniert nicht für mich. Es ruft weiterhin die verknüpften Entitäten ab, verwendet jedoch keine Join-Klausel. Stattdessen ruft es eine andere Select-Anweisung auf. – supertonsky

2

Eine Möglichkeit, dies zu tun, ist zwei Klassen haben einen Mitarbeiter vertreten:

  • Employee welche Abteilung Informationen abgebildet durch hat;
  • EmployeeSummary die nur die Mitarbeiterdaten selbst hat.

Beide Klassen haben dann unabhängig Bindungen auf den employee Tisch, aber nur Employee hat auch die Beziehung auf department definiert.

Dann, wenn Sie alle Informationen benötigen, laden Sie Employee Instanzen, und wenn Sie nur Mitarbeiterinformationen benötigen, laden Sie EmployeeSummary Instanzen.

Sie können jede Duplizierung von ORM-Bindungen und Geschäftslogik entfernen, indem Sie eine gemeinsame Oberklasse wie AbstractEmployee für beide Mitarbeiterklassen einführen.

+1

Ich denke nicht, dass dies eine gute Idee in dieser Situation ist. Was ist, wenn Ihre Klassen komplexe BL enthalten? Du musst es duplizieren? –

+0

Nicht unbedingt, wenn Sie die gemeinsame Oberklasse einführen, aber guter Punkt - ich habe die Antwort aktualisiert, um dies zu reflektieren. –

+0

Was wäre, wenn in einer einzigen Sitzung sowohl ein Mitarbeiter als auch eine EmployeeSummary aus dem gleichen Datenbankeintrag geladen wurden, dann wurden einer oder beide geändert? –

Verwandte Themen