[英]Hibernate PersistenceContext session Flush
我想知道当我调用session = session.getCurrentSession()时,休眠何时触发上下文会话
事情是,我在dao中有2个调用getCurrentSession()的方法,当我处理对getCurrentSession()的调用的更新时,实体为空:
SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];...)
我如何才能使这些实体从选择方法保留到更新方法?
这是我的方法:
public List<SystemConfiguration> getListConfigurations() {
List<SystemConfiguration> lista = new ArrayList<SystemConfiguration>();
Session session = null;
Query query = null;
String sql = "from SystemConfiguration where description = :desc";
try {
/* BEFORE
session = SessionFactoryUtil.getInstance().getCurrentSession();
@SuppressWarnings("unused")
Transaction ta = session.beginTransaction(); */
//FOLLOWING LINE SOLVED THE PROBLEM
session = SessionFactoryUtil.getInstance().openSession();
query = session.createQuery(sql);
query.setString("desc", "configuracion");
lista = query.list();
return lista;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public void updateConfigurations(List<SystemConfiguration> configs) throws Exception{
Session sess = null;
Transaction tx = null;
try {
//BEFORE
//sess = SessionFactoryUtil.getInstance().getCurrentSession();
//FOLLOWING LINE SOLVED THE PROBLEM
sess = SessionFactoryUtil.getInstance().openSession(new SystemConfigurationInterceptor());
tx = sess.beginTransaction();
for (SystemConfiguration sys : configs) {
sess.update(sys);
}
tx.commit();
} // try
catch (Exception e) {
e.printStackTrace();
if (tx != null && tx.isActive()) {
tx.rollback();
} // if
throw e;
}
}
这是我的拦截器:
public class SystemConfigurationInterceptor extends EmptyInterceptor {
private int updates;
private int creates;
private int loads;
public void onDelete(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
// do nothing
}
// This method is called when Entity object gets updated.
public boolean onFlushDirty(Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) {
if ( entity instanceof SystemConfiguration ) {
updates++;
for ( int i=0; i < propertyNames.length; i++ ) {
if ( "updated_at".equals( propertyNames[i] ) ) {
currentState[i] = new Timestamp(Calendar.getInstance().getTime().getTime());
return true;
}
}
}
return false;
}
public boolean onLoad(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
if ( entity instanceof SystemConfiguration ) {
loads++;
}
return false;
}
// This method is called when Entity object gets created.
public boolean onSave(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
if ( entity instanceof SystemConfiguration ) {
creates++;
for ( int i=0; i<propertyNames.length; i++ ) {
if ( "updated_at".equals( propertyNames[i] ) ) {
state[i] = new Timestamp(Calendar.getInstance().getTime().getTime());
return true;
}
}
}
return false;
}
public void afterTransactionCompletion(Transaction tx) {
if ( tx.wasCommitted() ) {
System.out.println("Creations: " + creates + ", Updates: " + updates +", Loads: " + loads);
}
updates=0;
creates=0;
loads=0;
}
当您告诉Hibernate和当前事务“关闭”时,Hibernate将刷新(通常在DB连接以某种方式返回到池时)。
因此,问题的答案取决于您使用的框架。 使用Spring,最外面的@Transactional
方法返回时,将刷新会话。
您上面的“解决方案”将无法使用很长时间,因为它永远不会关闭会话。 当它返回结果时,它将泄漏数据库连接,因此,在几次调用之后,您将耗尽连接。
同样,您的问题没有任何意义。 SELECT
不会更改对象,因此在您更改对象之前不需要对其进行“持久化”。
在updateConfigurations()
更改它们之后,Hibernate可以选择不立即将它们写入数据库,而只是更新缓存。
最终,如果您正确配置了所有内容,Spring将提交事务并刷新缓存。 但是,当您使用Spring时,永远不要创建打开和关闭会话,因为这会干扰Spring的工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.