2010-02-15 8 views
1

je les deux tableau ci-dessous (qui sont liés à la sécurité de printemps - mais la question que je crois avec Hibernate):Aide avec le mappage de clé étrangère dans Hibernate (Spring)?

Table user 
Table authority 

Le tableau user est lié (par Hibernate) à un objet de domaine dans mon application : class User, qui a les attributs suivants (et accesseurs correspondants), qui correspondent aux colonnes de la table user (sauf pour la collection qui est expliqué plus loin):

long uId 
String username 
String password 
... 
Collection<GrantedAuthority> authorities 

le tableau authority a 2 colonnes: UserId (clé étrangère dans le tableau user) et Authority (par ex. "ROLE_USER"). Cette table n'est pas représentée en tant qu'objet de domaine, mais est simplement une collection de la classe User.

Pour créer le mappage, dans mon fichier .hbm j'utilise les éléments suivants:

<class name="com.business.project.domain.User" table="user"> 
    <id name="uId" column="UserId"></id> 
    <property name="username" column="Name" type="java.lang.String" /> 
    <property name="password" column="Password" type="java.lang.String" /> 
    ... 
    <set name="authorities" table="authority"> 
     <key column="UserId" /> 
     <element column="Authority" type="java.lang.String" /> 
    </set> 
</class> 

Dans ma mise en veille prolongée la mise en œuvre de DAO, je crée un objet de requête, exécutez la requête, et jeter le résultat à un objet User:

... 
Query query = session.createQuery("from User where name = :username"); 
... 
User user = (User) query.uniqueResult(); 

à ce stade, je me attends à cet objet pour être rempli avec les données qu'il a tiré de la DB (je me suis assuré que les tables sont correctement avec des données de test et les noms de mappage sont corrects dans la cartographie fichier). Toutefois, l'appel des méthodes getter pour divers attributs de l'objet user renvoie tous NULL pour une raison quelconque. Quelqu'un peut-il voir quelque chose qui ne va pas dans ma configuration? Peut-être que j'ai mappé la collection (à la relation clé étrangère) mal? MERCI!

Mise à jour: voici la requête SQL qui hibernent généré (tiré de sa sortie DEBUG):

Hibernate: select user0_.UserId as UserId1_, user0_.Name as Name1_, 
    user0_.Password as Password1_ from user user0_ where user0_.Name=? 

Pour une raison quelconque, il ne montre pas tout ce qui touche à la table authority ... ne cela signifie que ma cartographie est incorrecte?

Modifier: Par la suggestion de bozho, j'ai regardé les messages sur le Consol au démarrage (tomcat), mais ne vois rien hors de l'ordinaire:

Feb 16, 2010 10:35:12 AM org.hibernate.cfg.HbmBinder bindRootPersistentClassCommonValues 
INFO: Mapping class: com.me.project.domain.User -> user 
Feb 16, 2010 10:35:12 AM org.hibernate.cfg.HbmBinder bindCollection 
INFO: Mapping collection: com.me.project.domain.User.authorities -> authority 
+1

Quelles versions de Spring Hibernate utilisez-vous? . . curieux –

+0

Spring 3.0 et hibernate 3.2.7 – oym

+0

La cartographie me semble ok et l'association semble ok aussi mais c'est comme tâtonner dans l'obscurité. Pouvez-vous fournir le mappage complet et comment vous ajoutez votre mapping à sessionfactory comme Spring Config par exemple s'il vous plait? Êtes-vous capable de sauvegarder des objets? Les voyez-vous dans votre navigateur sql? Si c'est juste un problème avec l'entité utilisateur, je suggère de le reproduire dans un test unitaire w et wo les trucs de printemps. – zoidbeck

Répondre

0
Query query = session.craeteQuery("FROM User WHERE username = :username"); 
query.setString("username", "SomeUserName"); 

cela devrait à peu près le faire.

+0

Je l'avais, je n'ai pas montré la ligne. La seule différence est que j'ai utilisé ce qui suit: query.setString ("nom d'utilisateur", nom d'utilisateur); où nom d'utilisateur est un paramètre de la méthode. J'ai essayé setParamter() juste pour le plaisir et le même problème. – oym

+0

System.out.println la valeur du paramètre pour voir ce que c'est – Bozho

+0

Oui, j'ai des appels de débogage dans cette fonction qui impriment la valeur et son ensemble correctement (c'est-à-dire que cette valeur existe dans la base de données). Thakns pour la suggestion. – oym

0

Essayez avec "from User where username = :username"

HQL utilise des propriétés de classe, pas les noms de colonne db

+0

même effet: tout est nul. Je trouve cela étrange - n'aurais-je pas eu une autre erreur avant si j'utilisais incorrectement le nom de la colonne à la place de la propriété de classe? – oym

+0

lorsque je change le nom en quelque chose qui n'est ni une propriété de classe ni un nom de colonne DB, alors je reçois une erreur. Peut-être que hibernate est assez intelligent pour vérifier à la fois la propriété de classe et la colonne db à laquelle elle est mappée? De toute façon, mon problème d'origine est toujours là. – oym

+0

pouvez-vous configurer hibernate pour enregistrer ses requêtes SQL? Y a-t-il une vraie requête sql? –

0

Etes-vous en train d'effacer la base de données chaque fois que vous exécutez le code java? En hibernation, il y a un paramètre et quand il est allumé, il peut effacer la base de données chaque fois qu'un code test/java est exécuté.

Pouvez-vous faire un findAll() et imprimer la taille? Je suspecte beaucoup que ce soit la mauvaise base de données, ou pas de données dans la base de données ou la suppression des données.

REMARQUE: Vérifiez la propriété "hibernate.hbm2ddl.auto" dans votre fichier de configuration. Si elle est définie sur "create-drop", hibernate créera automatiquement le schéma au démarrage et supprimera le schéma lorsque VM s'arrêtera. Il suffit de pointer à « mettre à jour » ou quelque chose

http://docs.atlassian.com/hibernate2/2.1.8/reference/session-configuration.html

+0

Merci pour la suggestion, je vais regarder dans et vous le faire savoir. Mais je suis sceptique parce que j'ai toujours un programme d'administration DB ouvert qui me montre les données, et les données ne sont pas effacées ou quoi que ce soit. – oym

+0

Aussi juste faire un findAll, parcourez chaque utilisateur et imprimez tout. Vous saurez si vous avez manqué quelque chose. Peut-être que le "nom d'utilisateur" contient un espace que vous ne donnez pas, un espace à la fin ... quelque chose :) –

+0

Toujours tout est NULL. comme je l'ai mentionné dans un commentaire précédent, j'ai essayé d'interroger la base de données directement avec la chaîne de requête qu'Hibernate génère (que j'ai extrait de sa sortie de débogage), et elle renvoie correctement la ligne ... – oym

0

« Mot de passe » est généralement un mot-clé dans les bases de données. Il semble que vous rencontriez un problème de collision de noms. Essayez ce qui suit. Mettez une coche autour du nom de la colonne pour échapper.

<property name="username" column="`Name`" type="java.lang.String" /> 
<property name="password" column="`Password`" type="java.lang.String" /> 

Supposons que vous utilisez org.springframework.security.GrantedAuthority, votre cartographie des autorités est incorrecte. En fonction de la manière dont vous effectuez le mappage, lorsque vous accédez à la collection, vous obtiendrez probablement une exception ClassCastException. Vous voulez probablement utiliser quelque chose comme UerType pour éviter le problème.

Questions connexes