2010-03-24 8 views
2

J'ai une application Spring-Hibernate qui échoue à mapper un objet correctement: fondamentalement, j'ai 2 objets de domaine, un Post et un User. La sémantique est que chaque publication a 1 utilisateur correspondant.Problème de mappage Spring-Hibernate

L'objet de domaine Post semble à peu près comme suit:

class Post { 

    private int pId; 
    private String attribute; 
    ... 
    private User user; 

    //getters and setters here 

} 

Comme vous pouvez le voir, Post contient une référence à User. Lorsque je charge un objet Post, je veux correspondre User objet à charger (paresseusement - seulement quand c'est nécessaire).

Ma cartographie se présente comme suit:

<class name="com...Post" table="post"> 
    <id name="pId" column="PostId" /> 
    <property name="attribute" column="Attribute" type="java.lang.String" /> 

    <one-to-one name="User" fetch="join" 
     class="com...User"></one-to-one> 
</class> 

Et bien sûr, j'ai une cartographie de base pour User mis en place.

En ce qui concerne mon schéma de table, j'ai une table appelée post avec un UserId étranger qui est relié au tableau user.

Je pensais que cette configuration devrait fonctionner, mais quand je charge une page qui force le chargement paresseux de l'objet User, je remarque la requête Hiberate suivante généré:

Select ... from post this_ left outer join user user2_ on this.PostId=user2_.UserId ... 

Évidemment, cela est faux: il se doit rejoindre UserId de post avec UserId de user, mais son adhésion à tort PostId de post (sa clé primaire) avec UserId de user.

Des idées? Merci!

Mise à jour: Merci à deux des postes ci-dessous, je me rends compte maintenant que je l'ai utilisé plusieurs-à-un au lieu d'un à un. J'ai changé la cartographie sous post à ce qui suit:

<many-to-one name="User" class="com...User" column="uId"/> 

Mais maintenant, je reçois une erreur d'exécution me disant qu'il n'y a pas d'attribut appelé uId. Cela est logique car je n'ai pas de colonne uId dans mon objet domaine post (j'ai simplement une référence à un objet user). Maintenant, je suis vraiment confus quant à comment je peux obtenir Hibernate pour réaliser qu'il doit mapper la clé étrangère de la table de poste à la table des utilisateurs. Doit-on ajouter explicitement un attribut uId à mon objet domaine post pour qu'il soit placeholder pour la clé étrangère?

J'espère que je fais sens ...

Répondre

1

Depuis un utilisateur de nombreux messages, votre association est en fait un "many-to-one", pas un "one-to-one". Cela devrait fonctionner si vous le mappez en conséquence.

Modifier: Oui, vous pouvez mapper la propriété Post.user sur la publication avec un "plusieurs-à-un", ou l'ensemble User.posts dans l'utilisateur avec un "un-à-plusieurs", ou tous les deux.Avez-vous spécifié le nom de votre colonne de clé étrangère?

Édition2: En mode Hibernate, une "colonne" dans la base de données est mappée à une "propriété" dans votre classe Java. C'est-à-dire que l'attribut column contient le nom de votre colonne de clé étrangère dans la base de données, pas le nom d'une propriété dans votre classe Java. Si je lis bien votre question, vous devriez utiliser "UserId", pas "uId".

Oh, et un fetch = "join" ne peut pas être paresseux, car il exige que l'utilisateur soit récupéré dans la même requête que le message.

+0

Merci, mais est-ce correct de placer cette cartographie dans le "post" de cartographie? J'ai essayé ceci avec des résultats incorrects similaires. Je ne suis pas sûr comment l'obtenir pour joindre sur UserId de la table de poteau puisque mes objets de domaine n'ont aucune notion d'une clé étrangère, juste une référence à un objet d'utilisateur. – James

+0

Merci pour votre mise à jour, pouvez-vous s'il vous plaît élaborer ce que vous entendez par "avez-vous spécifié le nom de votre colonne de clé étrangère?", Car je soupçonne que cela pourrait être mon problème? – James

+0

Merci! J'ai perdu tellement de temps à ce sujet ... que vous avez probablement deviné que je suis nouveau à hiberner ... – James

0

C'est le comportement d'un mappage un-à-un. Ils partagent généralement une clé primaire. Hibernate suppose que la clé primaire de la publication est la même que la clé primaire de l'utilisateur. This page résume ce comportement.

Je suppose qu'un utilisateur peut réellement avoir plus d'un message. Cela rend votre cartographie un-à-plusieurs.

+0

Vous avez raison à propos d'un utilisateur ayant plus d'une publication. Je suis juste confus quant à l'endroit où placer cette cartographie: sous la cartographie pour la poste ou sous la cartographie pour l'utilisateur? – James

Questions connexes