2010-02-15 134 views
1

我有以下兩個表(這與春季安全追平 - 但我相信這個問題是使用Hibernate):幫助Hibernate(Spring)中的外鍵映射?

Table user 
Table authority 

user表被捆綁(通過Hibernate)的域對象在我的應用程序:class User,其具有以下屬性(和相應的getter和setter),其對應於在user表中的列(除了後述的集合):

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

authority表有兩列:UserIduser表中的外鍵)和Authority(例如, 「ROLE_USER」)。此表不被表示爲域對象,但僅是User類中的一個集合。

要創建的映射,在我.hbm文件我用如下:

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

在我休眠DAO實現中,我創建一個查詢對象,執行查詢,並把結果向User對象:

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

在這一點上,我希望這個對象來與它從DB拉(我確信,該​​表與試驗數據正確填充和映射的名字是在映射正確的數據填充文件)。

但是,由於某種原因,在user對象上調用各種屬性的getter方法都會返回NULL。有人可以看到我的設置立即出錯嗎?也許我映射集合(到外鍵關係)是錯誤的?謝謝!

更新:這裏是SQL查詢Hibernate生成(從它的調試輸出取):

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

出於某種原因,它不會顯示相關authority表什麼...不這意味着我的映射不正確?

編輯:每bozho的建議下,我看了一眼在啓動時對CONSOL消息(Tomcat)的,但沒有看到任何不尋常的:

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

您使用的是什麼版本的Spring Hibernate。 。 。好奇 – 2010-02-15 21:58:55

+0

Spring 3.0和hibernate 3.2.7 – oym 2010-02-15 22:02:37

+0

映射對我來說看起來還不錯,而且這種關聯似乎也沒問題,但這就像在黑暗中摸索。你能否提供完整的映射,以及如何將你的映射添加到sessionfactory,比如spring config?你能夠保存對象嗎?你看到他們在你的SQL瀏覽器?如果這只是用戶實體的一個問題,我建議在單元測試中嘗試重現它,並在春天的東西。 – zoidbeck 2010-02-15 22:13:01

回答

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

這應該幾乎做到這一點。

+0

我有這個,我只是沒有顯示行。唯一的區別是,我使用了以下內容:query.setString(「username」,username);其中username是該方法的參數。我嘗試setParamter()只是爲了有趣和同樣的問題。 – oym 2010-02-15 22:05:16

+0

System.out.println該參數的值,看看它是什麼 – Bozho 2010-02-15 22:18:59

+0

是的,我在該函數中調試調用,打印出適當的值和它的集合(即該值存在於數據庫中)。 Thakns建議。 – oym 2010-02-15 22:21:21

0

嘗試用"from User where username = :username"

HQL使用類的屬性,而不是數據庫列名

+0

同樣的效果:一切都是NULL。我覺得這很奇怪 - 如果我不正確地使用列名取代類屬性,我會不會在之前得到一些其他錯誤? – oym 2010-02-15 21:45:54

+0

當我將名稱更改爲既不是類屬性也不是db列名的東西時,則出現錯誤。也許hibernate足夠聰明地檢查類屬性和映射到哪個數據庫列?無論哪種方式,我的原始問題仍然存在.. – oym 2010-02-15 21:56:49

+0

可以配置休眠以記錄它的SQL查詢嗎?有沒有真正的SQL查詢? – 2010-02-15 21:57:21

0

您是否每次運行測試/ java代碼都清除數據庫?在休眠中有一個設置,當它打開時,它可以在每次運行測試/ java代碼時清除數據庫。

你可以做一個findAll()並打印大小?我非常懷疑這是錯誤的數據庫,或者數據庫中沒有數據或數據清除。

注意:檢查配置文件中的「hibernate.hbm2ddl.auto」屬性。如果它被設置爲「create-drop」,hibernate會在啓動時自動創建模式,並在VM關閉時刪除模式。只是點到「更新」或類似

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

+0

返回一行(完全填充)感謝您的建議,我會研究它並讓你知道。但是我很懷疑,因爲我總是打開一個數據庫管理程序,向我顯示數據,而且數據不會被清除。 – oym 2010-02-16 15:32:33

+0

也只是做一個findAll,遍歷每個用戶並打印所有內容。你會知道你是否錯過了一些東西。也許「用戶名」有一個空間,你沒有給,在最後的空間......東西:) – 2010-02-16 16:16:47

+0

仍然一切都是空的。正如我在之前的評論中提到的那樣,我試着直接用Hibernate生成的查詢字符串查詢數據庫(我從它的調試輸出中提取),並正確地返回該行... – oym 2010-02-16 16:36:06

0

「密碼」,通常是在數據庫的關鍵字。這似乎是你遇到名稱衝突問題。嘗試以下操作。在列名稱周圍放置刻度標記以進行轉義。

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

假設您使用的是org.springframework.security.GrantedAuthority,那麼您的權威映射不正確。根據你映射的方式,當你訪問集合時,你很有可能會得到一個ClassCastException。你可能想使用類似UerType的東西來避免這個問題。