Original System Configuration:
- Spring 1.2.8
- Hibernate 3.0.5
Upgrade to:
- Spring 2.0
- Hibernate 3.2.0rc4
Lists:
- 改變 xml 的 dtd 到 xsd,原來:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans>
成:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd" >
上面包括 beans/util/aop/tx 等重要的 xsd,其他還有 jee/lang/tool 等不常用的,詳情請見 xsd-config - singleton="true" 要改為 scope="singleton",singleton="false" 要改為 scope="prototype"
- <util:foo> 很好用,例如:
<bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="location"> <value>classpath:config.properties</value> </property> </bean>
可改為<util:properties id="configProperties" location="classpath:config.properties"/>
- jdbcTemplate 的 ResultReader 已經正式拿掉了。原本:
jdbcTemplate.query(sql, new RowMapperResultReader(new MyRowMapper()));
改寫為:jdbcTemplate.query(sql, new MyRowMapper());
- Hibernate3 的 count 回傳原本是 Integer,新版變成回傳 Long (改這個真的是太狠了...)
//原本可以直接 cast 成 Integer: Integer count = (Integer) hibernateTemplate.find("select count(...) ... ").get(0); //新版的則回傳 Long,所以幹脆全改為用 Number Number countNumber = (Number) hibernateTemplate.find("select count(...) ... ").get(0); int count = countNumber.intValue();
- 承上,在 hql 直接 new 也受影響:
//如果直接在 hql 裡 new 物件,遇到了 count/sum... etc) String hql = " select new Foo(name, count(*)) from ... " //該物件的 argument 型別要為 Long public Foo(String name, Long count) {...}
- Hibernate3 的 UserType 原本在 HQL 只能用 string/int... 代入,現在可直接用 原來的 type:
// MyEnum 經由 UserType 將 enum mapping 為 string //原本要用 string 代入: hibernateTemplate.find(" from myPO where myEnum = ? ", MyEnum.SOMETHING.name() ) ; //要改為: hibernateTemplate.find(" from myPO where myEnum = ? ", MyEnum.SOMETHING ) ;
- Hibernate3 interceptor 加了四個 method: onCollectionRecreate()/onCollectionUpdate()/onCollectionRemove()/onPrepareStatement() 。跟其他 method 不一樣的是,String onPrepareStatement(String statement) 預設最少要回傳 argument statement,而不是 null
- spring.jar 不再內建 hibernate2 相關的 class,舊系統需要的話要加入 spring-hibernate2.jar
- Hibernate3 預設不再偵測 ehcache,需手動設定
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="hibernateProperties"> <props> <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> </props> </property> </bean>
- 測試用的 MockServletContext 改變尋找路徑的方法。原本測試時我們可以這樣做假的 webApplicationContext
String[] testPaths = new String[]{ "/com/foo/config/test-applicationConfig*.xml", "/com/other/foo-applicationConfig*.xml" }; XmlWebApplicationContext ctx = new XmlWebApplicationContext(); ctx.setConfigLocations(testPaths); ctx.setServletContext(new MockServletContext()); ctx.refresh();
升級後發現 MockServletContext 內部會改(先?) 用 filesystem 的方式去找檔案,當然就掛了... 解決的方法是強制要它走 classpath:String[] testPaths = new String[]{ "classpath:/com/foo/config/test-applicationConfig*.xml", "classpath:/com/other/foo-applicationConfig*.xml" };
光這個就搞了我兩個小時... 暈倒... - MockHttpSesseion 做 setAttribute/removeAttribute 時,現在會 trigger event 給 HttpSessionBindingListener 了 (越來越像真的...快不能叫 Mock 囉)
感覺升級 hibernate 問題比較多 =_=;。至於那個 aop 新的 transaction 的寫法... 呃,我還是覺得 txProxyTemplate 的寫法比較好... aspectj 的方式對 package/class 名稱的限制太多了 (因為要讓 pointcut wildcard "寫的出來"...)。改天拿便當系統來亂改試試,呵
最後,令人失望的是 Spring 2 沒有像 EJB3 那樣直接寫個 @Stateless 就可以定義一個 bean,還是得在 xml 寫一個 <bean>... 真希望能夠在 class 上加個 @Bean(id="fooService") 就 ok 了。很多 bean 都很簡單,不需要什麼設定,很適合這種寫法說。 Spring 就是死也不走侵略式的做法。可我不 care 被 Spring 侵略啊!下次自己寫一個算了 =_=
[Update] 加兩條和測試有關的。