JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Object Relational Mapping » Hibernate  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 [Hibernate] 當 Foreign Key 出槌時,有辦法從中攔截嗎? [精華]
smallufo





發文: 57
積分: 2
於 2004-12-31 15:57 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
最近在 map 一個 legacy forum , 使用 PHP 寫的。大體的架構不脫 Board / Post / User 的架構
每篇 Post 有一組 PosterId,BoardId 分別指向 User 以及 Board 的 PK
如果以 Hibernate 來 Map 這個 Post Class , 寫法如下:
1
2
3
4
5
6
7
8
9
   <class name="Post" table="Posts">
      <cache usage="read-only"/>
      <id name="number" column="B_Number" type="long">
         <generator class="native"/>
      </id>
      <property.../> //跳過
      <many-to-one name="poster"    column="B_PosterId" class="User" />
      <many-to-one name="board"     column="B_Board"    class="Board"/>
   </class>

這樣的 mapping 沒有問題...

但是...

由於這個 forum 執行已久,可能因為當時程式問題,造成一些 broken model
最明顯的是,某些 Post.PosterId 在 User 中找不到對應的 PK
意思是,該使用者已經被刪除了,但是板面仍有他的文章

這樣子會對 Hibernate 造成 UnresolvableObjectException

我不想要 lose 這些文章,我希望當 Post.poster 出槌時,系統塞一個 Dummy 的 User 給 Post.poster , 因此嘗試撰寫 PostInterceptor :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class PostInterceptor implements Interceptor
{
  public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException
  {
    if (entity instanceof Post)
    {       
        if (("poster").equals( propertyNames[i]))
        {
          if (state[i] == null)
          {
            User u = new User();
            u.setNumber(1);
            u.setUsername ("Invalid_User");
            u.setEmail("INVALID@NON_EXIST.COM");
            u.setPassword("XXX");
            state[i] = u;
          }
        }
      }
    }//if
    return false;
  }
} 


但是似乎 Interceptor.onLoad() 不做這樣的事,
FK 的錯誤不會被 Interceptor 給攔截

因此想請問各位,有沒有遇過這樣的問題?有沒有其他的解決方案?

參考 JIRA HB-785 : http://opensource.atlassian.com/projects/hibernate/browse/HB-785

Gavin King 似乎不想理會 Broken Data Model ... Black Eye


reply to postreply to post
作者 Re:[Hibernate] 當 Foreign Key 出槌時,有辦法從中攔截嗎? [Re:smallufo]
Forth



版主

發文: 676
積分: 8
於 2004-12-31 17:30 user profilesend a private message to usersend email to Forthreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
那就真的在資料庫建個dummy poster,然後把無效的poster id改填入dummy poster's id? 有什麼原因會讓您跳過這種方式嗎?

reply to postreply to post
孟母擇鄰,良禽擇木,電腦擇友
作者 Re:[Hibernate] 當 Foreign Key 出槌時,有辦法從中攔截嗎? [Re:Forth]
smallufo





發文: 57
積分: 2
於 2004-12-31 22:47 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Forth wrote:
那就真的在資料庫建個dummy poster,然後把無效的poster id改填入dummy poster's id? 有什麼原因會讓您跳過這種方式嗎?

因為,我必須使用非侵入式的方式 mapping 這個 forum,純粹讀取,不能刪除或是修改

有人建議我使用 UserType , 我思考後發現幾個問題:

第一,如果使用 UserType , 我勢必喪失 <many-to-one> , 因為 UserType 只能被用在 <property>

第二,如果真要使用 <property> + UserType , 我也勢必在 nullSafeGet() 中作資料存取的動作:透過 PosterId 查詢 User Table 是否有這個 User , 如果有,就 new 出來。如果沒有,就產生一個 Dummy User , 程式類似我上述。
但是 , UserType 無法取得 SessionFactory , 況且, 我使用 Spring 來管理我的 Hibernate 以及 SessionFactory 以及所有 Business Objects , Spring 無法 inject SessionFactory 進入 UserType , 因為 UserType 是 Hibernate 所 instantiated 的 , 而 Hibernate 不知道 Spring 的存在。

第三,另一個解法,在 nullSafeGet() 中,開啟 Spring 的 BeanFactory/ApplicationContext , 雖然可以動,這是我認為最爛也最沒效率的方法... Dead


reply to postreply to post
作者 Re:[Hibernate] 當 Foreign Key 出槌時,有辦法從中攔截嗎? [Re:smallufo]
ingramchen

Web monkey



發文: 479
積分: 12
於 2005-01-01 00:23 user profilesend a private message to usersend email to ingramchenreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
create database view ?

reply to postreply to post
MyBlog | 訂便當管理系統

作者 Re:[Hibernate] 當 Foreign Key 出槌時,有辦法從中攔截嗎? [Re:smallufo]
Forth



版主

發文: 676
積分: 8
於 2005-01-01 00:23 user profilesend a private message to usersend email to Forthreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
那麼,可以用Hibernate的native SQL query跟無效資料說再見嗎?能直接用SQL,可以做的事也多了些。

reply to postreply to post
孟母擇鄰,良禽擇木,電腦擇友
作者 Re:[Hibernate] 當 Foreign Key 出槌時,有辦法從中攔截嗎? [Re:smallufo]
hkdennis2k





發文: 1926
積分: 6
於 2005-01-01 00:43 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
還有.........

找 hibernate 的 source code,

自已改動~!

不過要改動那部份, 多少
和改動之後有沒有負作用就不知而知了.......


reply to postreply to post
作者 Re:[Hibernate] 當 Foreign Key 出槌時,有辦法從中攔截嗎? [Re:smallufo]
smallufo





發文: 57
積分: 2
於 2005-01-01 00:46 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Hibernate Team 的 max 告訴我,在 H3 會解決這問題
Interceptor 將被 Event 系統取代
可以解決各種不同奇怪的 hooking
呵∼我蠻期待的...


reply to postreply to post
» JWorld@TW »  Object Relational Mapping » Hibernate

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8