2009年4月27日 星期一

解決Eclipse中Java工程間循環引用而報錯的問題

如果我們的項目包含多個工程(project),而它們之間又是循環引用的關係,那麼Eclipse在編譯時會拋出如下一個錯誤信息:
A cycle was detected in the build path of project: XXX

解決方法非常簡單:

Eclipse Menu -> Window -> Preferences... -> Java -> Compiler -> Building -> Building path problems -> Circular dependencies ->將Error改成Warning

The Solution of the Problem That the Java Proejcts Have the Cycle References in Eclipse
If our project contains multiple proejcts, and the cycle references among them, Eclipse will throw out following error message while compiling:
"A cycle was detected in the build path of project: XXX"
The solution is quite simple:
Eclipse Menu -> Window -> Preferences... -> Java -> Compiler -> Building -> Building path problems -> Circular dependencies -> Change it from "Error" to "Warning".

source: http://yichen914.spaces.live.com/blog/cns!723590D920FAF62B!534.entry

2009年4月17日 星期五

一個經典的hibernate錯誤:a different object with the same identifier...

hibernate3.x上使用merge()來合併兩個session中的同一對象
a different object with the same identifier value was already associated with the session

一個經典的hibernate錯誤:a different object with the same identifier value was already associated with the session xxxx

hibernate3.x上使用merge()來合併兩個session中的同一對象,具體的Code就是

public Object getDomain(Object obj) {
getHibernateTemplate().refresh(obj);
return obj;
}
public void deleteDomain(Object obj) {
obj = getHibernateTemplate().merge(obj);
getHibernateTemplate().delete(obj);
}

或是
record = HibernateUtil.getCurrentSession().merge(record);
session.beginTransaction();
session.saveOrUpdate(record);
session.getTransaction().commit();



==========================

今天出现一点小问题,使用内存中的游离状态实体,因为它没有和 当前的session 相关,所以在进行维护该实体操作的时候,出现了

a different object with the same identifier value was already associated with the session 异常,

原因 用到数据库中持久的实体A时候,用它的标识直接在内存中生成,没有从session中取得,这样当维护这个实体相关信息的时候,session会发现,游离的实体和与session保存是查找到的相关的实体虽然标识一样,但是状态 不一样的冲突,从而不能完成事务,

而有同事介绍使用merge,后来查阅文档发现,使用merge的 时候,会发生一些隐形的问题:如果merge从新把游离的实体和session建立关联的时候,当这个游离的实体真的不存在,merge会创建一个非法的 实体,所以最好的办法应该是先从 当前的session中查询出实体,然后对这个相关的实体进行维护,就ok了。

Hibernate的用户曾要求一个既可自动分配新持久化标识(identifier)保存瞬时(transient)对象,又可更新/重新关联脱管(detached)实例的通用方法。 saveOrUpdate()方法实现了这个功能。

// in the first session
Cat cat = (Cat) firstSession.load(Cat.class, catID);
// in a higher tier of the application
Cat mate = new Cat();
cat.setMate(mate);
// later, in a new session
secondSession.saveOrUpdate(cat); // update existing state (cat has a non-null id)
secondSession.saveOrUpdate(mate); // save the new instance (mate has a null id)

saveOrUpdate()用途和语义可能会使新用户感到迷惑。 首先,只要你没有尝试在某个session中使用来自另一session的实例,你应该就不需要使用update()saveOrUpdate(),或merge()。有些程序从来不用这些方法。

通常下面的场景会使用update()saveOrUpdate()

  • 程序在第一个session中加载对象

  • 该对象被传递到表现层

  • 对象发生了一些改动

  • 该对象被返回到业务逻辑层

  • 程序调用第二个session的update()方法持久这些改动

saveOrUpdate()做下面的事:

  • 如果对象已经在本session中持久化了,不做任何事

  • 如果另一个与本session关联的对象拥有相同的持久化标识(identifier),抛出一个异常

  • 如果对象没有持久化标识(identifier)属性,对其调用save()

  • 如果对象的持久标识(identifier)表明其是一个新实例化的对象,对其调用save()

  • 如果对象是附带版本信息的(通过) 并且版本属性的值表明其是一个新实例化的对象,save()它。

  • 否则update() 这个对象

merge()可非常不同:

  • 如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象的状态覆盖旧有的持久实例

  • 如果session没有相应的持久实例,则尝试从数据库中加载,或创建新的持久化实例 (可能创建垃圾数据)

  • 最后返回该持久实例

  • 用户给出的这个对象没有被关联到session上,它依旧是脱管的



ref: http://ideas.javaeye.com/blog/371103

2009年4月13日 星期一

Oracle/PLSQL: Months_Between Function

The syntax for the months_between function is:

months_between( date1, date2 )

date1 and date2 are the dates used to calculate the number of months.

If a fractional month is calculated, the months_between function calculates the fraction based on a 31-day month.


Applies To:

  • Oracle 8i, Oracle 9i, Oracle 10g, Oracle 11g

Example #1:

months_between (to_date ('2003/01/01', 'yyyy/mm/dd'), to_date ('2003/03/14', 'yyyy/mm/dd') )

would return -2.41935483870968


Example #2

months_between (to_date ('2003/07/01', 'yyyy/mm/dd'), to_date ('2003/03/14', 'yyyy/mm/dd') )

would return 3.58064516129032


Example #3

months_between (to_date ('2003/07/02', 'yyyy/mm/dd'), to_date ('2003/07/02', 'yyyy/mm/dd') )

would return 0


Example #4

months_between (to_date ('2003/08/02', 'yyyy/mm/dd'), to_date ('2003/06/02', 'yyyy/mm/dd') )

would return 2

source: http://www.techonthenet.com/oracle/functions/months_between.php

2009年3月25日 星期三

Marshalling

http://www.faqs.org/docs/artu/ch05s03.html#id2908194
http://www.codeproject.com/KB/IP/Marshal.aspx
http://blog.carrion.ws/2006/11/06/marshalling-problem-explained/

2009年3月23日 星期一

Linux 下jdk6 和tomcat6的安装配置

linux 下安装jdk6

1、到 sun 网站下载 jdk rpm 软件包 jdk-6u11-linux-i586-rpm.bin;
2、在/usr下建立一个java目录,拷贝 jdk-6u11-linux-i586-rpm.bin 到 java目录;
3、给 jdk-6u11-linux-i586-rpm.bin 加上执行权限,
命令:chmod a+x jdk-6u11-linux-i586-rpm.bin
4、执行: ./jdk-6u11-linux-i586-rpm.bin,得到 jdk-6u11-linux-i586.rpm
5、执行: rmp -ivh jdk-6u11-linux-i586.rpm
6、至此,安装成功,设置环境变量;
7、设置linux的全局环境变量,需要root权限,可在命令行下输入su 切换到root用户;
8、修改etc/profile 文件,在最后加入如下代码:

#set java environment
export JAVA_HOME=/usr/java/jdk1.6.0_11
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib

linux 下安装tomcat6
1、到apache网站下载tomcat文件 apache-tomcat-6.0.18.tar.gz;
2、在/usr目录下建立tomcat目录;
3、解压apache-tomcat-6.0.18.tar.gz 文件,
命令 tar -xvzf apache-tomcat-6.0.18.tar.gz
4、修改etc/profile 文件,在最后加入如下代码:
export TOMCAT_HOME=/usr/tomcat
5、如果需要使用manager功能,需修改Tomcat_HOME/conf/tomcat-users.xml 文件,加入


6、启动tomcat,命令行方式改变到安装目录,运行
./catalina.sh run 命令 启动tomcat 有控制台
./catalina.sh start 命令 启动tomcat 无控制台
./startup.sh 启动tomcat 无控制台
7、关闭tomcat,执行
./shutdown.sh 或者 ./catalina.sh stop
8、测试tomcat安装是否成功
http://localhost:8080

source : http://www.blogjava.net/mecury

JVM內存的設置的原理

默認的java虛擬機的大小比較小,在對大數據進行處理時java就會報錯:java.lang.OutOfMemoryError。

設置jvm內存的方法,對於單獨的.class,可以用下面的方法對Test運行時的jvm內存進行設置。
java -Xms64m -Xmx256m Test

-Xms是設置內存初始化的大小
-Xmx是設置最大能夠使用內存的大小(最好不要超過物理內存大小)

在weblogic中,可以在startweblogic.cmd中對每個domain虛擬內存的大小進行設置,默認的設置是在commEnv.cmd裡面。

JVM內存的調優

1. Heap設定與垃圾回收
Java Heap分為3個區,Young,Old和Permanent。 Young保存剛實例化的對象。當該區被填滿時,GC會將對象移到Old區。 Permanent區則負責保存反射對象,本文不討論該區。
JVM的Heap分配可以使用-X參數設定,
-Xms初始Heap大小
-Xmx java heap最大值
-Xmn young generation的heap大小

JVM有2個GC線程。
第一個線程負責回收Heap的Young區。
第二個線程在Heap不足時,遍歷Heap,將Young區升級為Older區。 Older區的大小等於-Xmx減去-Xmn,不能將-Xms的值設的過大,因為第二個線程被迫運行會降低JVM的性能。
為什麼一些程序頻繁發生GC?有如下原因:
程序內調用了System.gc()或Runtime.gc()。
一些中間件軟件調用自己的GC方法,此時需要設置參數禁止這些GC。
Java的Heap太小,一般默認的Heap值都很小。
頻繁實例化對象,Release對象。此時盡量保存並重用對象,例如使用StringBuffer()和String()。
如果你發現每次GC後,Heap的剩餘空間會是總空間的50%,這表示你的Heap處於健康狀態。許多Server端的Java程序每次GC後最好能有65%的剩餘空間。

經驗之談:
1. Server端JVM最好將-Xms和-Xmx設為相同值。為了優化GC,最好讓-Xmn值約等於-Xmx的1/3[2]。
2.一個GUI程序最好是每10到20秒間運行一次GC,每次在半秒之內完成[2]。
注意:
1.增加Heap的大小雖然會降低GC的頻率,但也增加了每次GC的時間。並且GC運行時,所有的用戶線程將暫停,也就是GC期間,Java應用程序不做任何工作。
2. Heap大小並不決定進程的內存使用量。進程的內存使用量要大於-Xmx定義的值,因為Java為其他任務分配內存,例如每個線程的Stack等。

2. Stack的設定
每個線程都有他自己的Stack。
-Xss每個線程的Stack大小

Stack的大小限制著線程的數量。如果Stack過大就好導致內存溢漏。 -Xss參數決定Stack大小,例如-Xss1024K。如果Stack太小,也會導致Stack溢漏。

3.硬件環境
硬件環境也影響GC的效率,例如機器的種類,內存,swap空間,和CPU的數量。
如果你的程序需要頻繁創建很多transient對象,會導致JVM頻繁GC。這種情況你可以增加機器的內存,來減少Swap空間的使用[2]。

4.4種GC
第一種為單線程GC,也是默認的GC。 ,該GC適用於單CPU機器。

第二種為Throughput GC,是多線程的GC,適用於多CPU,使用大量線程的程序。第二種GC與第一種GC相似,不同在於GC在收集Young區是多線程的,但在Old區和第一種一樣,仍然採用單線程。 -XX:+UseParallelGC參數啟動該GC。

第三種為Concurrent Low Pause GC,類似於第一種,適用於多CPU,並要求縮短因GC造成程序停滯的時間。這種GC可以在Old區的回收同時,運行應用程序。 -XX:+UseConcMarkSweepGC參數啟動該GC。

第四種為Incremental Low Pause GC,適用於要求縮短因GC造成程序停滯的時間。這種GC可以在Young區回收的同時,回收一部分Old區對象。 -Xincgc參數啟動該GC。
4種GC的具體描述參見[3]。

參考文章:
1. JVM Tuning. http://www.caucho.com/resin-3.0/performance/jvm-tuning.xtp#garbage-collection
2. Performance tuning Java: Tuning steps
http://h21007.www2.hp.com/dspp/tech/tech_TechDocumentDetailPage_IDX/1,1701,1604,00.html
3. Tuning Garbage Collection with the 1.4.2 JavaTM Virtual Machine .
http://java.sun.com/docs/hotspot/gc1.4.2/


C:\>java -X
-Xmixed mixed mode execution (default)
-Xint interpreted mode execution only
-Xbootclasspath:
set search path for bootstrap classes and resources
-Xbootclasspath/a:
append to end of bootstrap class path
-Xbootclasspath/p:
prepend in front of bootstrap class path
-Xnoclassgc disable class garbage collection
-Xincgc enable incremental garbage collection
-Xbatch disable background compilation
-Xms set initial Java heap size
-Xmx set maximum Java heap size
-Xss set java thread stack size
-Xprof output cpu profiling data
-Xrunhprof[:help]|[: