- 浏览: 1183264 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (350)
- Ajax研究 (2)
- javascript (22)
- struts (15)
- hibernate (12)
- spring (8)
- 我的生活 (28)
- jsp (2)
- 我的随笔 (84)
- 脑筋急转弯 (1)
- struts2 (2)
- ibatis (1)
- groovy (1)
- json (4)
- flex (20)
- Html Css (5)
- lucene (11)
- solr研究 (2)
- nutch (25)
- ExtJs (3)
- linux (6)
- 正则表达式 (2)
- xml (1)
- jetty (0)
- 多线程 (1)
- hadoop (40)
- mapreduce (5)
- webservice (2)
- 云计算 (8)
- 创业计划 (1)
- android (8)
- jvm内存研究 (1)
- 新闻 (2)
- JPA (1)
- 搜索技术研究 (2)
- perl (1)
- awk (1)
- hive (7)
- jvm (1)
最新评论
-
pandaball:
支持一下,心如大海
做有气质的男人 -
recall992:
山东分公司的风格[color=brown]岁的法国电视[/co ...
solr是如何存储索引的 -
zhangsasa:
-services "services-config ...
flex中endpoint的作用是什么? -
来利强:
非常感谢
java使用json所需要的几个包 -
zhanglian520:
有参考价值。
hadoop部署错误之一:java.lang.IllegalArgumentException: Wrong FS
Hibernate中的对象有三种状态: 瞬时状态 (Transient),持久状态 (Persistent),
1. 脱管状态 (Detached)
1. 1. 瞬时状态 (Transient)
由 new 命令开辟内存空间的 Java 对象,也就是平时所熟悉的普通 Java 对象。
如: Student stu = new Student();
瞬时对象特点:
(1) 不和 Session 实例关联
(2) 在数据库中没有和瞬时对象关联的记录
2. 2. 持久状态 (Persistent)
持久的实例在数据库中有对应的记录,并拥有一个持久化标识 (identifier).
持久对象总是与 Session 和 Transaction 相关联,在一个 Session 中,对持久对象的改变不会马上对数据库进行变更,而必须在 Transaction 终止,也就是执行 commit() 之后,才在数据库中真正运行 SQL 进行变更,持久对象的状态才会与数据库进行同步。在同步之前的持久对象称为脏 (dirty) 对象。
瞬时对象转为持久对象:
(1) 通过 Session 的 save() 和 saveOrUpdate() 方法把一个瞬时对象与数据库相关联,这个瞬时对象就成为持久化对象。
(2) 使用 fine(),get(),load() 和 iterater() 待方法查询到的数据对象,将成为持久化对象。
持久化对象的特点:
(1) 和 Session 实例关联
(2) 在数据库中有和持久对象关联的记录
3. 3. 脱管状态 (Detached)
与持久对象关联的 Session 被关闭后,对象就变为脱管对象。对脱管对象的引用依然有效,对象可继续被修改。
脱管对象特点:
(1) 本质上和瞬时对象相同
(2) 只是比爱瞬时对象多了一个数据库记录标识值 id.
持久对象转为脱管对象:
当执行 close() 或 clear(),evict() 之后,持久对象会变为脱管对象。
瞬时对象转为持久对象:
通过 Session 的 update(),saveOrUpdate() 和 lock() 等方法,把脱管对象变为持久对象。
三种状态相互转化的状态图如下:
4 .结合 save(),update(),saveOrUpdate() 方法说明对象的状态
(1)Save() 方法将瞬时对象保存到数据库,对象的临时状态将变为持久化状态。当对象在持久化状态时,它一直位于 Session 的缓存中,对它的任何操作在事务提交时都将同步到数据库,因此,对一个已经持久的对象调用 save() 或 update() 方法是没有意义的。如:
Student stu = new Strudnet();
stu.setCarId(“200234567”);
stu.setId(“100”);
// 打开 Session, 开启事务
session.save(stu);
stu.setCardId(“20076548”);
session.save(stu); // 无效
session.update(stu); // 无效
// 提交事务,关闭 Session
(2)update() 方法两种用途重新关联脱管对象为持久化状态对象,显示调用 update() 以更新对象。调用 update() 只为了关联一个脱管对象到持久状态,当对象已经是持久状态时,调用 update() 就没有多大意义了。如:
// 打开 session ,开启事务
stu = (Student)session.get(Student.class,”123456”);
stu.setName(“Body”);
session.update(stu); // 由于 stu 是持久对象,必然位于 Session 缓冲中,
对 stu 所做的变更将 // 被同步到数据库中。所以 update() 是没有意义的,可以不要这句效果一样的。
// 提交事务,关闭 Session
Hibernate 总是执行 update 语句,不管这个脱管对象在离开 Session 之后有没有更改过,在清理缓存时 Hibernate 总是发送一条 update 语句,以确保脱管对象和数据库记录的数据一致,如:
Student stu = new Strudnet();
stu.setCarId(“1234”);
// 打开 Session1, 开启事务
session1.save(stu);
// 提交事务,关闭 Session1
stu.set(“4567”); // 对脱管对象进行更改
// 打开 Session2, 开启事务
session2.update(stu);
// 提交事务,关闭 Session2
注:即使把 session2.update(stu); 这句去掉,提交事务时仍然会执行一条 update() 语句。
如果希望只有脱管对象改变了, Hibernate 才生成 update 语句,可以把映射文件中 <class> 标签的 select-before-update 设为 true, 这种会先发送一条 select 语句取得数据库中的值,判断值是否相同,如果相同就不执行 update 语句。不过这种做法有一定的缺点,每次 update 语句之前总是要发送一条多余的 select 语句,影响性能。对于偶尔更改的类,设置才是有效的,对于经常要更改的类这样做是影响效率的。
(3)saveOrUpdate() 方法兼具 save() 和 update() 方法的功能,对于传入的对象, saveOrUpdate() 首先判断其是脱管对象还是临时对象,然后调用合适的方法。
评论
stu.setCarId(“200234567”);
stu.setId(“100”);
// 打开 Session, 开启事务
session.save(stu);
stu.setCardId(“20076548”);
session.save(stu); // 无效 ***这句错了,我试了,有效,而且你写的有问题**
session.update(stu); // 无效
// 提交事务,关闭 Session
纠证一点问题
Student stu = new Strudnet();
stu.setCarId(“1234”);
// 打开 Session1, 开启事务
session1.save(stu);
// 提交事务,关闭 Session1
stu.set(“4567”); // 对脱管对象进行更改
// 打开 Session2, 开启事务
session2.update(stu);
// 提交事务,关闭 Session2
注:即使把 session2.update(stu); 这句去掉,提交事务时仍然会执行一条 update() 语句。
去掉为什么会执行?
如果去掉,它又不在Session2的缓存中,如何来执行update语句呢。
真JB强人。
另外:
hibernate提供这三种状态,个人认为是便于理解,便于在开发的时候清楚的知道实体类的状态和数据在事务中的变化,这点对其实是个基础点,因为EJB也有这类似的状态的!
纠证一点问题
Student stu = new Strudnet();
stu.setCarId(“1234”);
// 打开 Session1, 开启事务
session1.save(stu);
// 提交事务,关闭 Session1
stu.set(“4567”); // 对脱管对象进行更改
// 打开 Session2, 开启事务
session2.update(stu);
// 提交事务,关闭 Session2
注:即使把 session2.update(stu); 这句去掉,提交事务时仍然会执行一条 update() 语句。
你把session2.update(stu);去掉不会执行update语句,只会执行第一个session.save()生成的insert 语句
我不太赞同
session的save()或者update()的操作就提交事务了,
事务操作不是session这类控制的,而session中的save()或者update()不过跟数据库进行insert,update是一样,没有commit,怎么就提交事务了呢
我们的理解就是对象进入了持久化状态,但如果你没有提交数据,别人查询的时候还是你操作之前的数据,如果有另一个事务同时访问同一数据,则出现锁表或者有能出现幻觉(脏数据)。
既然已经提交事务,session关闭的话,数据已经更新到数据库内,session2.update 如果注释的话 绝对会不起作用 赞同楼上的
会起作用
public void testGet(){
Session session = null;
Transaction tx = null;
try{
session = SessionFactoryUtils.getSession();
tx = session.beginTransaction();
/*User user = new User();
user.setName("张三");
user.setPassword("123456");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
*/
User user = (User)session.get(User.class,"402880e42ef34964012ef34966530000");
session.delete(user);
log.debug("++++++++++++++userName:"+user.getName());
user.setName("李四");
session.update(user);
tx.commit();
}catch(Exception e){
e.printStackTrace();
tx.rollback();
}finally{
SessionFactoryUtils.closeSession(session);
}
}
测试过了,出现了异常
20:56:22,593 DEBUG Loader:2050 - done entity load
20:56:22,609 DEBUG HibernateTest:59 - ++++++++++++++userName:张三
org.hibernate.ObjectDeletedException: deleted instance passed to update(): [<null entity name>#<null>]
at org.hibernate.event.def.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:50)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireUpdate(SessionImpl.java:742)
at org.hibernate.impl.SessionImpl.update(SessionImpl.java:730)
at org.hibernate.impl.SessionImpl.update(SessionImpl.java:722)
at com.navagate.client.HibernateTest.testGet(HibernateTest.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at org.hibernate.testing.junit.UnitTestCase.runBare(UnitTestCase.java:63)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
20:56:22,609 DEBUG JDBCTransaction:182 - rollback
20:56:22,625 DEBUG JDBCTransaction:193 - rolled back JDBC Connection
20:56:22,625 DEBUG ConnectionManager:427 - aggressively releasing JDBC connection
执行过delete说明这条记录已经删除了,你怎么还能做更新操作呢.
public void testGet(){
Session session = null;
Transaction tx = null;
try{
session = SessionFactoryUtils.getSession();
tx = session.beginTransaction();
/*User user = new User();
user.setName("张三");
user.setPassword("123456");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
*/
User user = (User)session.get(User.class,"402880e42ef34964012ef34966530000");
session.delete(user);
log.debug("++++++++++++++userName:"+user.getName());
user.setName("李四");
session.update(user);
tx.commit();
}catch(Exception e){
e.printStackTrace();
tx.rollback();
}finally{
SessionFactoryUtils.closeSession(session);
}
}
测试过了,出现了异常
20:56:22,593 DEBUG Loader:2050 - done entity load
20:56:22,609 DEBUG HibernateTest:59 - ++++++++++++++userName:张三
org.hibernate.ObjectDeletedException: deleted instance passed to update(): [<null entity name>#<null>]
at org.hibernate.event.def.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:50)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireUpdate(SessionImpl.java:742)
at org.hibernate.impl.SessionImpl.update(SessionImpl.java:730)
at org.hibernate.impl.SessionImpl.update(SessionImpl.java:722)
at com.navagate.client.HibernateTest.testGet(HibernateTest.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at org.hibernate.testing.junit.UnitTestCase.runBare(UnitTestCase.java:63)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
20:56:22,609 DEBUG JDBCTransaction:182 - rollback
20:56:22,625 DEBUG JDBCTransaction:193 - rolled back JDBC Connection
20:56:22,625 DEBUG ConnectionManager:427 - aggressively releasing JDBC connection
test-text
观察的相当仔细,漏掉的b,在看看你头像,果然很搭
纠证一点问题
Student stu = new Strudnet();
stu.setCarId(“1234”);
// 打开 Session1, 开启事务
session1.save(stu);
// 提交事务,关闭 Session1
stu.set(“4567”); // 对脱管对象进行更改
// 打开 Session2, 开启事务
session2.update(stu);
// 提交事务,关闭 Session2
注:即使把 session2.update(stu); 这句去掉,提交事务时仍然会执行一条 update() 语句。
你把session2.update(stu);去掉不会执行update语句,只会执行第一个session.save()生成的insert 语句
我不太赞同
session的save()或者update()的操作就提交事务了,
事务操作不是session这类控制的,而session中的save()或者update()不过跟数据库进行insert,update是一样,没有commit,怎么就提交事务了呢
我们的理解就是对象进入了持久化状态,但如果你没有提交数据,别人查询的时候还是你操作之前的数据,如果有另一个事务同时访问同一数据,则出现锁表或者有能出现幻觉(脏数据)。
既然已经提交事务,session关闭的话,数据已经更新到数据库内,session2.update 如果注释的话 绝对会不起作用 赞同楼上的
纠证一点问题
Student stu = new Strudnet();
stu.setCarId(“1234”);
// 打开 Session1, 开启事务
session1.save(stu);
// 提交事务,关闭 Session1
stu.set(“4567”); // 对脱管对象进行更改
// 打开 Session2, 开启事务
session2.update(stu);
// 提交事务,关闭 Session2
注:即使把 session2.update(stu); 这句去掉,提交事务时仍然会执行一条 update() 语句。
你把session2.update(stu);去掉不会执行update语句,只会执行第一个session.save()生成的insert 语句
我不太赞同
session的save()或者update()的操作就提交事务了,
事务操作不是session这类控制的,而session中的save()或者update()不过跟数据库进行insert,update是一样,没有commit,怎么就提交事务了呢
我们的理解就是对象进入了持久化状态,但如果你没有提交数据,别人查询的时候还是你操作之前的数据,如果有另一个事务同时访问同一数据,则出现锁表或者有能出现幻觉(脏数据)。
纠证一点问题
Student stu = new Strudnet();
stu.setCarId(“1234”);
// 打开 Session1, 开启事务
session1.save(stu);
// 提交事务,关闭 Session1
stu.set(“4567”); // 对脱管对象进行更改
// 打开 Session2, 开启事务
session2.update(stu);
// 提交事务,关闭 Session2
注:即使把 session2.update(stu); 这句去掉,提交事务时仍然会执行一条 update() 语句。
你把session2.update(stu);去掉不会执行update语句,只会执行第一个session.save()生成的insert 语句
其实这种思想,体现了对象与数据库表对象的关联关系。
往往做设计对物理实体的操作都可以用OO思想来理解。
比如数据库表实体可以被做作为虚拟对象处理,当虚拟对象被处理了,
相应触发了底层实体层变化,而这部分属于高内聚,设计时候类的功能特性必须具
备实体的作用效果。
通过了三种状态,主要还是为了解决对象与数据库表对象的映射,体现了hibernate的面向对象的特性。
发表评论
-
Hibernate性能优化
2011-01-07 10:18 1283文章分为十三个小块儿 ... -
深入理解O/R Mapping
2011-01-04 22:39 2018什么是O/R Mapping? 广义 ... -
hbmdll.auto详解
2011-01-04 14:55 1321hibernate.cfg.xml 中hibern ... -
Hibernate锁机制 悲观锁和乐观锁
2011-01-01 00:07 2604今天就是元旦了,闲着没事,写点东西发上来! 1、Pessim ... -
hibernate的事务处理
2010-12-31 23:09 2353在使用hibernate开发时, ... -
eccache的简单介绍
2010-12-31 22:59 1611关于缓存的话题,在坛 ... -
hibernate中队mappedBy的理解
2010-12-30 12:52 1925对于mappedBy的理解: a) 只有OneToOne, ... -
hibernate中openSesson和getCurrentSession的区别,面试时常会问到
2010-12-28 11:30 927异常信息是没有当前的Session的意思,我又仔细的看了 ... -
关于连接池的讨论
2009-09-28 16:44 1502Tomcat的连接池其实就是dbcp. 我比较过流行的 dbc ... -
hibernate 中distinct的使用
2008-07-30 14:50 5210JDBC中我们熟悉的sql: select distinct ... -
hibernate查询时出现的问题
2008-06-13 17:49 3370org.hibernate.InstantiationExce ...
相关推荐
hibernate中session对象的状态详解
在Java的持久化框架Hibernate中,对象存在三种不同的状态,分别是持久态(Persistent)、自由态(Transient)和游离态(Detached)。这三种状态分别对应了对象与数据库的关联程度,理解它们对于高效地使用Hibernate...
在Java的持久化框架Hibernate中,对象的状态管理是其核心特性之一...总之,理解Hibernate中对象的三种状态以及它们之间的转换对于开发人员来说至关重要。熟练掌握这些概念有助于编写出更加高效、可靠的Java持久化代码。
以下是Hibernate对象的三种主要状态及其特点: 1) 临时状态(Transient State): 当通过`new`关键字创建一个新的对象时,该对象处于临时状态。在这个状态下,对象并未与任何Session关联,因此它的变化不会自动反映...
Hibernate将对象的状态划分为四种:临时状态、持久化状态、游离状态和删除状态。这些状态反映了对象与数据库记录之间的关系,有助于理解Hibernate如何管理和操作数据。 1. **临时状态(Transient State)**: 当一...
在Java的持久化框架Hibernate中,`Session`和`Transaction`是两个至关重要的概念,它们在数据管理和事务处理中起到核心作用。这篇文章将深入解析这两个概念及其相关知识点。 `Session`是Hibernate提供的一种与...
本文将深入探讨Hibernate中的核心概念——Session管理。 首先,理解Session在Hibernate中的角色至关重要。Session是Hibernate的主要工作单元,它是应用程序与数据库之间的桥梁。它负责保存、检索和更新Java对象,...
在Hibernate中,`SessionFactory`是核心组件之一,它是线程安全的,用于创建`Session`对象。`SessionFactory`通常在应用启动时创建一次,然后在整个应用生命周期中复用。创建`SessionFactory`需要通过读取Hibernate...
Hibernate的Session接口是Java应用程序与Hibernate之间主要的运行时交互接口,它提供了对持久化对象的创建、读取和删除操作。Session的概念是基于对象的状态管理和数据库事务的,它的生命周期通常与一个物理事务绑定...
Hibernate对象有三种状态:瞬时状态(Transient)、持久状态(Persistent)和脱管状态(Detached)。理解这些状态对于优化数据操作和避免潜在的问题至关重要。 首先,瞬时状态(Transient)是指通过new关键字创建的...
在Hibernate中,事务和Session是紧密关联的,事务的边界通常定义了Session的工作范围。 3. **持久化操作**: - **加载和检索**:使用`get()`或`load()`方法可以加载一个实体,如果对象存在于数据库,Hibernate将...
`Session.flush()`方法是一个关键的操作,它强制Hibernate将内存中的对象状态同步到数据库,确保数据的一致性。这篇博客深入探讨了`Session.flush()`的工作原理和应用场景。 `Session`在Hibernate中主要有以下职责...
在 Hibernate 中,对象有三种不同的状态,这些状态决定了对象与数据库之间的关联程度以及如何进行数据操作。理解这些状态对于有效地使用 Hibernate 至关重要。 1. **瞬时态(Transient)**: - 瞬时态的对象是刚刚...
在Java的持久化框架Hibernate中,Session对象是与数据库交互的核心组件,它负责管理对象的持久状态。在处理大量数据或者长时间运行的事务时,合理地管理Session的生命周期至关重要,这就涉及到了Hibernate的Session...
在 Hibernate 中,对象的状态管理是其核心特性之一,主要包括三种状态:瞬时状态(Transient)、持久化状态(Persistent)以及游离状态(Detached)。本文将详细阐述这三种状态的特点及其转换机制。 #### 二、瞬时...
首先,我们需要理解Session在Hibernate中的角色。Session是Hibernate的核心接口之一,它负责对象的持久化操作,比如保存、更新、删除和检索对象。Session对象就像一个临时的工作区域,用于在应用程序和数据库之间...
首先,我们要了解Hibernate定义的三种实体状态: 1. **临时状态(Transient)**:当我们在程序中通过`new`关键字创建一个实体对象时,它默认处于临时状态。此时,对象未被Hibernate管理,即使对象包含了主键ID,如果...
Hibernate三种状态和Session常用的方法 Hibernate 作为一个...理解 Hibernate 中的三种状态和 Session 中的常用方法是非常重要的。只有深入了解这些机制,我们才能更好地使用 Hibernate 框架来开发高效的应用程序。
本篇将详细阐述Hibernate中的对象映射关系以及对象的三种状态。 对象映射是Hibernate的核心特性,它通过ORM(Object-Relational Mapping)技术将Java对象与数据库表之间的关系进行映射。Hibernate提供了一种声明式...
- **缓存的同步更新**: 当 Session 清理缓存时,Hibernate 会检查缓存中的对象状态是否发生变化,并同步更新数据库,从而确保数据一致性。 - **缓存相关方法**: - **`flush()`**: 刷新缓存并执行必要的 SQL 语句,...