<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    badqiu

    XPer
    隨筆 - 46, 文章 - 3, 評論 - 195, 引用 - 0
    數據加載中……

    使用動態代理解決Hibernate序列化,避免延遲加載問題.

    在使用Ajax: Hibernate Entity => json,?Flex RemoteObject:?Hibernate Entity => ActionScript Object的過程,經常碰到如下問題:

    問題:

    1.Hibernate碰到延遲加載的屬性訪問時如果session被關閉則拋出LazyInitializationException

    2.Hibernate中的one-to-many等關聯關系在序列化時如果沒有控制,則將整個數據庫都有可能被全部序列化

    3.過多的使用DTO/ValueObject解決這個問題.

    解決辦法:

    對Entity對象生成一個動態代理,攔截getXXXX()方法,如果訪問的是延遲加載的屬性,則return null,而不拋出LazyInitializationException,遞歸生成屬性的代理,只要碰到未延遲加載的屬性,而序列化會自動停止.避免將整個Entity序列化傳播,導致可能序列化整個數據庫的問題.

    類似解決方案:

    dwr中HibernateConverter,在序列化時如上類似,碰到延遲加載的屬性自動停止convert工作.而HibernateBeanSerializer則一勞永逸,無論object => json都可以工作.

    ?

    使用用例:

    ?

    Java代碼 復制代碼
    1. //role為原始對象 ??
    2. role?=?(Role)roleDao.getById( new ?Long( 1 )); ??
    3. //生成的動態代理proxyRole,訪問延遲加載的屬性將return?null ??
    4. Role?proxyRole?=?(Role) new ?HibernateBeanSerializer<Role>(role).getProxy(); ??
    5. assertNotNull(role.getResource());?? ??
    6. assertNull(proxyRole.getResource());? //延遲加載,為null ??
    7. ??
    8. Hibernate.initialize(role.getResource());? //抓取進來 ??
    9. assertNotNull(proxyRole.getResource());? //不為null ??

    ??

    ?

    源碼.

    Java代碼 復制代碼
    1. package ?cn.org.rapid_framework.util; ??
    2. ??
    3. import ?java.lang.reflect.Modifier; ??
    4. import ?java.util.ArrayList; ??
    5. import ?java.util.Collection; ??
    6. import ?java.util.LinkedHashMap; ??
    7. import ?java.util.LinkedHashSet; ??
    8. import ?java.util.List; ??
    9. import ?java.util.Map; ??
    10. import ?java.util.Set; ??
    11. ??
    12. import ?org.aopalliance.intercept.MethodInterceptor; ??
    13. import ?org.aopalliance.intercept.MethodInvocation; ??
    14. import ?org.hibernate.Hibernate; ??
    15. import ?org.hibernate.collection.PersistentCollection; ??
    16. import ?org.hibernate.proxy.HibernateProxy; ??
    17. import ?org.springframework.aop.framework.ProxyFactory; ??
    18. import ?org.springframework.util.StringUtils; ??
    19. ??
    20. /** ?
    21. ?*?用于Hibernate?Object?的序列化,訪問延遲加載的屬性不會拋出LazyInitializationException,而會返回null值. ?
    22. ?*?使用: ?
    23. ?*?<pre> ?
    24. ?*?Blog?proxyBlog?=?new?HibernateBeanSerializer(blog).getProxy(); ?
    25. ?*?</pre> ?
    26. ?*?@author?badqiu ?
    27. ?*?@param?<T> ?
    28. ?*/ ??
    29. public ? class ?HibernateBeanSerializer?<T>?{ ??
    30. ????T?proxy?=? null ; ??
    31. ???? /** ?
    32. ?????*/ ??
    33. ???? public ?HibernateBeanSerializer(T?object,String...?excludesProperties)?{ ??
    34. ???????? if (object?==? null )?{ ??
    35. ???????????? this .proxy?=? null ; ??
    36. ????????} else ?{ ??
    37. ????????????ProxyFactory?pf?=? new ?ProxyFactory(); ??
    38. ????????????pf.setTargetClass(object.getClass()); ??
    39. ????????????pf.setOptimize( true ); ??
    40. ????????????pf.setTarget(object); ??
    41. ????????????pf.setProxyTargetClass( true ); ??
    42. ????????????pf.setOpaque( true ); ??
    43. ????????????pf.setExposeProxy( true ); ??
    44. ????????????pf.setPreFiltered( true ); ??
    45. ????????????HibernateBeanSerializerAdvice?beanSerializerAdvice?=? new ?HibernateBeanSerializerAdvice(); ??
    46. ????????????beanSerializerAdvice.setExcludesProperties(excludesProperties); ??
    47. ????????????pf.addAdvice(beanSerializerAdvice); ??
    48. ???????????? ??
    49. ???????????? this .proxy?=?(T)pf.getProxy(); ??
    50. ????????} ??
    51. ????} ??
    52. ??
    53. ???? public ?T?getProxy(){ ??
    54. ???????? return ? this .proxy; ??
    55. ????} ??
    56. ???? ??
    57. ???? static ? private ? class ?HibernateBeanSerializerAdvice? implements ?MethodInterceptor?{ ??
    58. ???????? private ?String[]?excludesProperties?=? new ?String[ 0 ];? ??
    59. ???????? public ?String[]?getExcludesProperties()?{ ??
    60. ???????????? return ?excludesProperties; ??
    61. ????????} ??
    62. ???????? public ? void ?setExcludesProperties(String[]?excludesProperties)?{ ??
    63. ???????????? this .excludesProperties?=?excludesProperties?==? null ??? new ?String[ 0 ]?:?excludesProperties; ??
    64. ????????} ??
    65. ???????? public ?Object?invoke(MethodInvocation?mi)? throws ?Throwable?{ ??
    66. ????????????String?propertyName?=?getPropertyName(mi.getMethod().getName()); ??
    67. ????????????Class?returnType?=?mi.getMethod().getReturnType(); ??
    68. ???????????? ??
    69. ???????????? if (propertyName?==? null )?{ ??
    70. ???????????????? return ?mi.proceed(); ??
    71. ????????????} ??
    72. ???????????? if (!Hibernate.isPropertyInitialized(mi.getThis(),?propertyName))?{ ??
    73. ???????????????? return ? null ; ??
    74. ????????????} ??
    75. ???????????? if (isExclude(mi,?propertyName))?{ ??
    76. ???????????????? return ? null ; ??
    77. ????????????} ??
    78. ???????????? ??
    79. ????????????Object?returnValue?=?mi.proceed(); ??
    80. ???????????? return ?processReturnValue(returnType,?returnValue); ??
    81. ????????} ??
    82. ???????? ??
    83. ???????? private ?Object?processReturnValue(Class?returnType,?Object?returnValue)?{ ??
    84. ???????????? if (returnValue?==? null ) ??
    85. ???????????????? return ? null ; ??
    86. ???????????? if (returnType?!=? null ?&&?Modifier.isFinal(returnType.getModifiers()))?{ ??
    87. ???????????????? return ?returnValue; ??
    88. ????????????} ??
    89. ???????????? //This?might?be?a?lazy-collection?so?we?need?to?double?check ??
    90. ???????????? if (!Hibernate.isInitialized(returnValue))?{ ??
    91. ???????????????? return ? null ;???????????????? ??
    92. ????????????} ??
    93. ???????????? ??
    94. ???????????? //this?is?Hibernate?Object ??
    95. ???????????? if (returnValue? instanceof ?HibernateProxy)?{ ??
    96. ???????????????? return ? new ?HibernateBeanSerializer(returnValue).getProxy(); ??
    97. ????????????} else ? if (returnValue? instanceof ?PersistentCollection)?{ ??
    98. ???????????????? if (returnType.isAssignableFrom(Map. class ))?{ ??
    99. ????????????????????Map?proxyMap?=? new ?LinkedHashMap(); ??
    100. ????????????????????Map?map?=?(Map)returnValue; ??
    101. ????????????????????Set<Map.Entry>?entrySet?=?map.entrySet(); ??
    102. ???????????????????? for (Map.Entry?entry?:?entrySet)?{ ??
    103. ????????????????????????proxyMap.put(entry.getKey(),? new ?HibernateBeanSerializer(entry.getValue())); ??
    104. ????????????????????} ??
    105. ???????????????????? return ?proxyMap; ??
    106. ????????????????} ??
    107. ???????????????? ??
    108. ????????????????Collection?proxyCollection?=? null ; ??
    109. ???????????????? if (returnType.isAssignableFrom(Set. class ))?{ ??
    110. ????????????????????proxyCollection?=? new ?LinkedHashSet(); ??
    111. ????????????????} else ? if (returnType.isAssignableFrom(List. class ))?{ ??
    112. ????????????????????proxyCollection?=? new ?ArrayList(); ??
    113. ????????????????} else ?{ ??
    114. ???????????????????? return ?returnValue; ??
    115. ????????????????} ??
    116. ???????????????? ??
    117. ???????????????? for (Object?o?:?(Collection)returnValue)?{ ??
    118. ????????????????????proxyCollection.add( new ?HibernateBeanSerializer(o).getProxy()); ??
    119. ????????????????} ??
    120. ???????????????? return ?proxyCollection; ??
    121. ????????????} else ?{ ??
    122. ???????????????? return ?returnValue; ??
    123. ????????????} ??
    124. ????????} ??
    125. ? ??
    126. ???????? private ? boolean ?isExclude(MethodInvocation?mi,?String?propertyName) ??
    127. ???????????????? throws ?Throwable?{ ??
    128. ???????????? ??
    129. ???????????? for (String?excludePropertyName?:?excludesProperties)?{ ??
    130. ???????????????? if (propertyName.equals(excludePropertyName))?{ ??
    131. ???????????????????? return ? true ; ??
    132. ????????????????} ??
    133. ????????????} ??
    134. ???????????? ??
    135. ???????????? return ? false ; ??
    136. ????????} ??
    137. ???????? ??
    138. ???????? private ? static ?String?getPropertyName(String?methodName)?{ ??
    139. ????????????String?propertyName?=? null ; ??
    140. ???????????? if (methodName.startsWith( "get" ))?{ ??
    141. ????????????????propertyName?=?methodName.substring( "get" .length()); ??
    142. ????????????} else ? if (methodName.startsWith( "is" ))?{ ??
    143. ????????????????propertyName?=?methodName.substring( "is" .length()); ??
    144. ????????????} else ? if (methodName.startsWith( "set" ))?{ ??
    145. ????????????????propertyName?=?methodName.substring( "set" .length()); ??
    146. ????????????} ??
    147. ???????????? return ?propertyName?==? null ??? null ?:?StringUtils.uncapitalize(propertyName); ??
    148. ????????} ??
    149. ????} ??
    150. }??

    ?

    ?

    ?

    ?另這個類屬于rapid-framework的一部分,v2.0版本的flex RemoteObject將采用這個辦法.preview版本即將發布

    posted on 2008-10-31 00:33 badqiu 閱讀(3178) 評論(3)  編輯  收藏

    評論

    # re: 使用動態代理解決Hibernate序列化,避免延遲加載問題.  回復  更多評論   

    用了spring,你的方法就不行了吧
    2008-10-31 09:12 | lsqlister

    # re: 使用動態代理解決Hibernate序列化,避免延遲加載問題.  回復  更多評論   

    不用spring么?
    有spring用干嘛不用?重復發明輪子?。?
    不過spring后面也是使用cglib生成動態代理,將以上代碼修改,可以改為只依賴cglib的Enhancer
    2008-10-31 09:26 | badqiu

    # re: 使用動態代理解決Hibernate序列化,避免延遲加載問題.  回復  更多評論   

    但這也是一種很有趣的解法。
    2008-11-01 17:07 | 金山詞霸2008

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 国产AV无码专区亚洲AV毛网站| 亚洲精品亚洲人成在线观看下载| 午夜亚洲国产理论秋霞| a级成人毛片免费视频高清| 亚洲桃色AV无码| 免费无码又爽又刺激网站| 国产亚洲av片在线观看播放| 中文字幕的电影免费网站| 亚洲一区二区三区无码中文字幕 | 国产日产亚洲系列| 一级毛片视频免费| 国产亚洲成人久久| 国产成人AV免费观看| 亚洲精品在线免费看| 国产精品美女午夜爽爽爽免费| 亚洲经典千人经典日产| 亚洲日本va午夜中文字幕久久| 中文字幕无码免费久久9一区9 | 亚洲激情在线观看| 在线永久免费的视频草莓| 亚洲午夜在线播放| 深夜国产福利99亚洲视频| 中国一级特黄的片子免费| 亚洲成AV人片天堂网无码| 18禁成人网站免费观看| 亚洲色成人网站WWW永久四虎| 四虎永久成人免费| 免费国产成人18在线观看| 亚洲一区二区三区深夜天堂| 国产美女无遮挡免费视频| av电影在线免费看| 亚洲理论片中文字幕电影| 又粗又黄又猛又爽大片免费| 三级网站在线免费观看| 成人亚洲国产va天堂| 国产亚洲精品成人a v小说| jjizz全部免费看片| 美女被羞羞网站免费下载| 亚洲AV无码一区二区三区系列| 好先生在线观看免费播放| 国产精品综合专区中文字幕免费播放 |