Question

J'ai une User d'une classe Log (que je ne peux pas choisir):

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

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

Une cartographie possible ressemblera à:

<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>

Cela fonctionne bien et cartes sur les tables de base de données suivantes:

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 |
+---------+---------------+---------------------+

Ma question est de savoir comment est-il possible en veille prolongée corréler ces 2 ensembles (accessLogs et actionLogs) dans la même table produisant le schéma suivant pour les journaux:

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 |
+---------+---------------+---------------------+--------+

Modifier : Je veux conserver le code Java et la sémantique Définir comme est. Je cherche quelque chose comme un discriminateur, une formule ou une extension de l'API mise en veille prolongée qui résoudra ce sans toucher le code Java. Peut-être que quelque chose le long des lignes (configuration de mise en veille prolongée imaginaire suit):

<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 : Je n'ai pas une solution complète à ce moment. Je suis sûr que cela peut être fait, peut-être une API en étendant mise en veille prolongée.

Était-ce utile?

La solution

Comme Maurizio écrit, vous devez utiliser l'attribut where pour récupérer uniquement les lignes qui appartiennent à chaque collection.

insérer lignes en utilisant la colonne supplémentaire, vous devez ajouter l'élément suivant à l'intérieur du <set>:

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

Cela dit essentiellement Hibernate à utiliser que SQL spécifique au lieu de le générer. Notez que je devais échapper manuellement la colonne when.

Bonus: pour ajouter la colonne supplémentaire à la DB, utilisez les touches suivantes (après la fermeture du <class>)

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

peu intéressant: je l'ai écrit et testé cela en utilisant NHibernate , mais il a été porté directement, donc il devrait fonctionner exactement de la même

.

Autres conseils

Avez-vous essayez de mapper ensemble de cette façon:

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

pourquoi ne pas travailler juste combiner les listes en une seule liste? Vos deux listes sont de la même classe.

EDIT - Si vous souhaitez conserver avoir 2 listes, puis créer une troisième liste qui est la combinaison, et persistent seulement. Vous devez contrôler l'accès aux accesseurs des deux listes, vous savez quand mettre à jour la troisième, mais ne devrait pas être trop dur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top