hibernate获取实体更新前的值

在使用hibernat的时候有时需要获取实体在更新前的某个字段的值,但hibernate没有提供公开的api来获取,如果使用session的get方法或用hql获取始终只能获取到更新后的值(我说的是在同一个会话当中,如果你另启一个会话来获取的话当我没说),如果想要获取更新前的值只能拼sql,然后用jdbc来获取,但在研究hibernate的拦截器时候,发现在onFlushDirty中可以获取到更新前的值,如下:

public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) throws CallbackException;

于是仔细研究发现确实可以通过hibernate的session来获取更新前的值,代码如下:

/**
 * 
 */
package com.jason.ddoWeb.common.hibernate;

import java.util.Map;

import org.hibernate.Session;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.persister.entity.EntityPersister;

/**
 * @author jasonzhang
 *
 */
public final class HibernateUtil {

	/**
	 * 获取实体的某个字段被更新前的值
	 * @param session hibernate的会话
	 * @param entityName 实体的class名全称
	 * @param propertyName 需要获取的属性的名称
	 * @return
	 */
	public final static Object getOldValue(Session session, String entityName, String propertyName) {
		org.hibernate.internal.SessionImpl actualSession = (org.hibernate.internal.SessionImpl)session;
		final PersistenceContext persistenceContext = actualSession.getPersistenceContext();
		Object oldValue = null;
		for ( Map.Entry<Object,EntityEntry> me : persistenceContext.reentrantSafeEntityEntries() ) {
			EntityEntry entry = (EntityEntry) me.getValue();
			if (entry.getEntityName().equals(entityName)) {
				Object[] loadedStates = entry.getLoadedState();
				EntityPersister persister = entry.getPersister();
				String[] propertyNames = persister.getPropertyNames();
				for (int i=0; i<propertyNames.length; i++) {
					if (propertyNames[i].equals(propertyName)) {
						oldValue = loadedStates[i];
					}
				}
			}
		}
		return oldValue;
	}
}

调用方法如下:

Integer oldNum = (Integer)HibernateUtil.getOldValue(super.getSession(), "com.jason.ddoWeb.entity.warning.ChannelComplaintDayEntity", "num");

其中super.getSession()是我自己代码中获取hibernate的session的封装。

时间: 2024-10-12 07:57:18

hibernate获取实体更新前的值的相关文章

根据查询实体获取指定返回列的值

一步步完善并优化自己的ORM框架功能 [新增] /// <summary> /// 根据查询实体获取指定返回列的值 /// </summary> /// <typeparam name="SearchT">查询实体类</typeparam> /// <typeparam name="ResultT">返回实体类</typeparam> /// <param name="searc

Java反射获取实体的所有可见属性值,返回Object数组

获取实体的所有可见属性值 以下代码提供了两种实现,一种是基于List,一种是基于Map; 基于List的实现更节省内存,更高效一些:如果你有其它特殊的需求,可以根据实际参考以下代码进行扩展,或许有需要用到Map的情况呢! 当然,使用BeanUtils.describe或PropertyUtils.describe一两句代码就搞定了,但还需要额外添加包引用:另外效率方面是不是更高呢?我没有做过测试. /** * 获取实体的所有可见属性值 * @param object 实体类的实例 * @retu

java 中利用反射机制获取和设置实体类的属性值

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. JAVA反射(放射)机制:"程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言".从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言.但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可

hibernate之实体类型到映射文件

1.通过写hibernate的映射文件,将实体类型转换成数据库中的表 其中那个映射文件是根据实体类型而写的. 实体类型User.java package cn.wwh.www.hibernate.dd.property; import java.util.Arrays; import java.util.Date; /** *类的作用: * * *@author 一叶扁舟 *@version 1.0 *@创建时间: 2014-8-17 下午08:05:30 */ public class Use

关于hibernate 多实体(多表)连接查询映射到实体的讨论

前提表与实体信息: 在hibernate 查询中,我们经过遇到三种情况: 1.查询事个实体,如: select  b from TableB b; 返回的LIst 中封装的是 实体TableB的实例. 2.查询单个属性,如: select b.id from TableB b; hibernate 返回的List 中封装的是ojbect对象. 3.当查询多于一个属性且又不是整个实体时,如:select b.id,b.mes from TableB b;返回的List中封装的是Object[]数组

c# winform TreeView NODE(节点) 重命名或获取节点修改后的值

在程序开发过程中我们经常用到treeview,还经常要修改节点的名字.节点名字修改后还想及时更新数据库.这时问题就来了,怎样获取NODE(节点)更新后的值呢?本人试了很多方法最终分析出treeview节点名字修改的AfterLabelEdit事件.事件内有两个参数如下代码 sender 和 e. private void treeView2_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) { } 代码内的e 有两个值,e.Lable

Hibernate之实体类设计基本步骤

1.先设计一个基类BaseBean (1)@MappedSuperclass表示实体类父类 package com.life.hibernate.bean; import java.util.Date; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Temporal; im

Entity Framework 6 Recipes 2nd Edition(13-3)译 -&gt; 为一个只读的访问获取实体

问题 你想有效地获取只是用来显示不会更新的操作的实体.另外,你想用CodeFirst的方式来实现 解决方案 一个非常常见行为,尤其是网站,就是只是让用户浏览数据.大多数情况下,用户不会更新数据.在这种情况下,你可以通过避开上下文的缓存和修改跟踪来提高代码性能,你可以非常简单地使用AsNoTracking方法来实现. 让我们假设你一个应用程序来管理doctor(医生)的appointments(预约),你的模型如下图Figure 13-5. Figure 13-5. A model for man

《Entity Framework 6 Recipes》中文翻译系列 (40) ------ 第七章 使用对象服务之从跟踪器中获取实体与从命令行生成模型(想解决EF第一次查询慢的,请阅读)

翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-5  从跟踪器中获取实体 问题 你想创建一个扩展方法,从跟踪器中获取实体,用于数据保存前执行一些操作. 解决方案 假设你有如图7-7所示的模型. 图7-7. 包含实体Technician和ServiceCall的模型 在这个模型中,每个技术员(technician)都有一些业务服务请求(service call),业务服务请求包含联系人姓名,问题.使用代码清单7-4,创建一个扩展方法获取