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