2010-05-27 3 views
1

J'ai article table et plusieurs tables utilisateur a_user, b_user, ... avec exactement la même structure (mais des données différentes). Je ne peux rien changer dans les tables *_user sauf le préfixe de leur nom de table mais peut changer tout le reste (les tables utilisateur contiennent seulement des informations d'utilisateur, il n'y a rien sur l'article ou le type d'utilisateur).Quelle est une bonne solution pour lier différentes tables dans Hibernate en fonction d'une valeur de champ?

Je dois lier l'article à un utilisateur (plusieurs-à-un), mais le nom de la table utilisateur est défini par le champ type_utilisateur. Par exemple

Article table record: 
... 
user_id="5" 
user_type="a" 

signifie qu'il est lié à un utilisateur id = 5 de la table a_user (id 5 est pas unique dans la portée des utilisateurs, chaque table utilisateur peut avoir son id 5).

Des suggestions pour gérer cette situation? Comment puis-je mapper cette relation dans Hibernate (mappage xml, pas d'annotations) pour qu'il récupère automatiquement l'utilisateur correct pour un article lors de la sélection/mise à jour? Comment dois-je mapper les tables utilisateur (une ou plusieurs classes?)?

je besoin d'exécuter certaines requêtes comme ceci:

from Article a where a.userType=:type and a.user.name=:name 

Merci.

+0

conception de base de données assez étrange, comment est la clé étrangère définie pour l'article de table? – tkr

+0

Eh bien, actuellement, il n'est pas défini. Il s'agissait d'une simple relation plusieurs-à-un avec une table utilisateur. Maintenant, il doit y avoir plusieurs tables d'utilisateurs. Pourquoi y a-t-il plusieurs tables d'utilisateurs - elles proviennent d'un autre produit (forum), et nous avons plusieurs forums. – serg

Répondre

3

Hibernate a @Any annotation (et <any> élément xml) pour de telles conceptions.

Désolé pour les annotations, mais je ne suis pas bon dans hbm.xml. Il peut être traduit en XML, voir <any> element:

@Entity @Table(name = "Article") 
public class Article { 

    @Any(metaColumn = @Column(name = "user_type")) 
    @AnyMetaDef(
      idType = "integer", 
      metaType = "string", 
      metaValues = { 
        @MetaValue(value = "A", targetEntity = UserA.class), 
        @MetaValue(value = "B", targetEntity = UserB.class) 
      } 
    ) 
    @JoinColumn(name = "user_id") 
    private User user; 

    ... 
} 

UserA et UserB partage le même schéma défini par User:

@MappedSuperclass 
abstract public class User { 
    @Id 
    private Long id; 

    private String name; 

    ... 
} 

@Entity @Table(name = "a_user") 
public class UserA extends User {} 

@Entity @Table(name = "b_user") 
public class UserB extends User {} 
+0

Merci, on dirait que c'est exactement ce dont j'ai besoin. – serg

Questions connexes