顯示具有 Hibernate 標籤的文章。 顯示所有文章
顯示具有 Hibernate 標籤的文章。 顯示所有文章

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年1月20日 星期二

DBCP, C3P0常用參數,和使用中碰到的問題

DBCP:
driverClassName
url
username
password
上面四個分別是驅動,連接字符串,用戶名和密碼

maxActive連接池支持的最大連接數
maxIdle連接池中最多可空閒maxIdle個連接
minIdle連接池中最少空閒maxIdle個連接
initialSize初始化連接數目
maxWait連接池中連接用完時,新的請求等待時間,毫秒
timeBetweenEvictionRunsMillis timeBetweenEvictionRunsMillis和minEvictableIdleTimeMillis一起使用,每

timeBetweenEvictionRunsMillis毫秒秒檢查一次連接池中空閒的連接,把空閒時間超過minEvictableIdleTimeMillis毫秒的連接斷開,直到連接池中的連接數到minIdle為止

minEvictableIdleTimeMillis連接池中連接可空閒的時間,毫秒

removeAbandoned true,false,是否清理removeAbandonedTimeout秒沒有使用的活動連接,清理後並沒有放回連接池
removeAbandonedTimeout活動連接的最大空閒時間
logAbandoned true,false,連接池收回空閒的活動連接時是否打印消息


minEvictableIdleTimeMillis,removeAbandonedTimeout這兩個參數針對的連接對像不一樣,minEvictableIdleTimeMillis針對連接池中的連接對象,removeAbandonedTimeout針對未被close的活動連接.

在dbcp使用中遇到的問題:
當短時間之內活動連接達到maxActive,再請求連接,等maxWait秒後連接池就會報出錯來:Cannot get a connection, pool exhausted.在這maxWait秒裡removeAbandoned並沒有起作用,出錯後連接池就會把所有的連接斷開,為什麼這時候 removeAbandoned沒有起作用呢?


C3P0:
http://sourceforge.net/projects/c3p0 (c3p0-src - c3p0-0.9.1.2)
driverClass
jdbcUrl
user
password
minPoolSize
maxPoolSize
initialPoolSize

acquireIncrement池中沒有空閒連接時,一次請求獲取的連接數
maxIdleTime池中連接最大空閒時間
acquireRetryAttempts獲取連接失敗後,重新嘗試的次數
acquireRetryDelay嘗試連接間隔時間,毫秒
checkoutTimeout等待連接時間,0為無限等待,毫秒
DebugUnreturnedConnectionStackTraces true,false,是否收回未返回的活動連接
unreturnedConnectionTimeout活動連接的時間.

c3p0中的問題:
unreturnedConnectionTimeout是給每個活動連接一個時間限制,到點兒就收回,不管有沒有正在使用連接.這樣不是太好,應該是從最後一次使用連接才開始計時才好.那有沒有這樣的一個參數從最後一次使用計時呢?

source:
http://www.javaeye.com/post/607253
http://www.hibernate.org/214.html
For C3P0
http://www.hibernate.org/214.html?cmd=comphist&histnode=1059