Frage

Ich habe eine User ein eine Log Klasse bekommt (die ich nicht ändern kann):

class User {
    private long id;
    private String name;
    private Set<Log> accessLogs;
    private Set<Log> actionLogs;
}

class Log {
    private String what;
    private Date when;
}

Eine mögliche Zuordnung wird wie folgt aussehen:

<class name="com.example.User" table="users">
    <id name="id" access="field">
        <generator class="native" />
    </id>

    <property name="name" length="256" />

    <set name="accessLogs" table="user_access_logs" cascade="all-delete-orphan" order-by="`when`">
        <key column="user_id" />
        <composite-element class="com.example.Log">
            <property name="what" length="512" />
            <property name="when" column="`when`" />
        </composite-element>
    </set>

    <set name="actionLogs" table="user_action_logs" cascade="all-delete-orphan" order-by="`when`">
        <key column="user_id" />
        <composite-element class="com.example.Log">
            <property name="what" length="512" />
            <property name="when" column="`when`" />
        </composite-element>
    </set>

</class>

Das funktioniert gut und Karten auf den folgenden Datenbanktabellen:

users
+----+------+
| id | name |
+----+------+
|  1 | john |
|  2 | bill |
|  3 | nick |
+----+------+

user_access_logs
+---------+------------+---------------------+
| user_id | what       | when                |
+---------+------------+---------------------+
|       1 | logged in  | 2010-09-21 11:25:03 |
|       1 | logged out | 2010-09-21 11:38:24 |
|       1 | logged in  | 2010-09-22 10:19:39 |
|       2 | logged in  | 2010-09-22 11:03:18 |
|       1 | logged out | 2010-09-22 11:48:16 |
|       2 | logged in  | 2010-09-26 12:45:18 |
+---------+------------+---------------------+

user_action_logs
+---------+---------------+---------------------+
| user_id | what          | when                |
+---------+---------------+---------------------+
|       1 | edit profile  | 2010-09-21 11:28:13 |
|       1 | post comment  | 2010-09-21 11:30:40 |
|       1 | edit profile  | 2010-09-21 11:31:17 |
|       1 | submit link   | 2010-09-22 10:21:02 |
|       2 | submit review | 2010-09-22 11:10:22 |
|       2 | submit link   | 2010-09-22 11:11:39 |
+---------+---------------+---------------------+

Meine Frage ist, wie ist es möglich, in den Ruhezustand, diese zwei Sätze zur Karte (accessLogs und actionLogs) in die gleiche Tabelle für die Protokolle das folgende Schema Herstellung:

user_logs
+---------+---------------+---------------------+--------+
| user_id | what          | when                | type   |
+---------+---------------+---------------------+--------+
|       1 | logged in     | 2010-09-21 11:25:03 | access |
|       1 | edit profile  | 2010-09-21 11:28:13 | action |
|       1 | post comment  | 2010-09-21 11:30:40 | action |
|       1 | edit profile  | 2010-09-21 11:31:17 | action |
|       1 | logged out    | 2010-09-21 11:38:24 | access |
|       1 | logged in     | 2010-09-22 10:19:39 | access |
|       1 | submit link   | 2010-09-22 10:21:02 | action |
|       2 | logged in     | 2010-09-22 11:03:18 | access |
|       2 | submit review | 2010-09-22 11:10:22 | action |
|       2 | submit link   | 2010-09-22 11:11:39 | action |
|       1 | logged out    | 2010-09-22 11:48:16 | access |
|       2 | logged in     | 2010-09-26 12:45:18 | access |
+---------+---------------+---------------------+--------+

Bearbeiten : Ich möchte den Java-Code und Set Semantik beibehalten wie es ist. Ich bin auf der Suche nach so etwas wie einem Diskriminator, eine Formel oder einer Hibernate-API-Erweiterung, die dies ohne Berührung des Java-Code zu lösen. Vielleicht etwas entlang der Linien (imaginäre Hibernate Konfiguration folgt):

<set name="accessLogs" table="user_logs" ... formula="type='access'">
    <key column="user_id" />
    <composite-element class="Log">
        ...
    </composite-element>
</set>

<set name="actionLogs" table="user_logs" ... formula="type='action'">
    <key column="user_id" />
    <composite-element class="Log">
        ...
    </composite-element>
</set>

EDIT2 : Ich habe nicht eine vollständige Lösung dieses Problems noch bekam. Ich bin sicher, es kann getan werden, möglicherweise durch eine Hibernate API erstreckt.

War es hilfreich?

Lösung

Wie Maurizio schrieb, müssen Sie das where Attribut verwenden, nur die Zeilen abzurufen, die zu jeder Sammlung gehören.

Einsatz Reihen die zusätzliche Spalte, müssen Sie das folgende Element in der <set> hinzuzufügen:

<sql-insert>
  insert into user_logs(user_id, what, [when], type)
  values(?, ?, ?, 'access')
</sql-insert>

Das sagt im Wesentlichen Hibernate, dass bestimmte SQL zu verwenden, anstatt es zu erzeugen. Beachten Sie, dass ich musste manuell die when Spalte entweichen kann.

Bonus: die zusätzliche Spalte in die DB hinzuzufügen, verwenden Sie die folgende (nach dem <class> Schließen)

<database-object>
  <create>alter table user_logs add type char(6)</create>
  <drop></drop>
</database-object>

Interessante Bit: Ich schrieb und getestet diese mit NHibernate , aber es wurde direkt portiert, so sollte es funktionieren genau die gleichen

.

Andere Tipps

Haben Sie versucht Satz auf diese Weise abzubilden:

<set name="accessLogs" table="user_logs" where="type='access'">    

Warum funktioniert es nicht, nur die Listen zu einer Liste kombinieren? Ihre beiden Listen sind von der gleichen Klasse.

EDIT - Wenn Sie 2 Listen mit erhalten wollen, dann eine dritte Liste erstellen, die die Kombination ist, und nur das fortbestehen. Sie werden zu Accessoren der beiden Listen zu steuern den Zugriff haben, so dass Sie wissen, wenn die dritte zu aktualisieren, sollte aber nicht zu hart sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top