0

I already search in forums, and i tried many things without succes.

I want at the end on a transactional method, and only at the end, to save only hibernate object for whom i will use explicitly the Hibernate getHibernateTemplate().saveOrUpdate() method, and NOT dirty ones, that i only modify using setters.

My need will be clearer after reading my service layer code:

For simplicity purpose, i will summarize my code.

Service layer:

@Service("cartService")
public class CartServiceImpl extends AbstractServiceImpl<Cart> implements
        CartService {

   @Autowired 
   private CartDao cartDao;

   @Transactional(readOnly = false)
   public Cart updateCart1(){

            Cart cartA = cartDao.findById(1);
            cartA.setTotal=(5);

            Cart cartB = cartDao.findById(1);
            cartB.setTotal=(5);     
            CartDao.Update(cartB);
   }
}

So, what i need, is at the end of the method updateCart1() is to save the change of cartB, BUT Not to save the change of cartA.

Dao layer:

NB: cartDao's methods (findById, saveOrUpdate) call the HibernateTemplate one.

public T update(T entite) {
    getHibernateTemplate().saveOrUpdate(entite);
    return entite;
}

public T findById(Serializable id) {
    return getHibernateTemplate().get(this.clazz, id);
}

I didn't want that Dao's method act on database outside a transactionnal service layer method. And i wanted them to be executed in database at the end of a transaction defined on the service layer. Thus, in hibernate spring configuration file:

<prop key="connection.autocommit">false</prop> 

Note that i am using OpenSessionInViewFilter for Lazyu loading purpose. So in my XML file:

<filter>
  <filter-name>OpenSessionInViewFilter</filter-name>
  <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
  <init-param>
     <param-name>singleSession</param-name>
     <param-value>false</param-value>
  </init-param> 
</filter>

NB: These cart cartDao's methods are working fine in a normal scenario. But not in the one i'm describing. And "@Transactional" is correctly configured and work fine two.

Problem: With this code, i get the two objects (cartA and cartB) changed in database, while i dont want to modify cartA, for whom i didn't call explicitly the HibernateTemplate's saveOrUpdate method.

After searching in forums, i tried to make the hibernate FLUSH mode to FLUSH_NEVER. But at the execution of CartDao.Update(cartB) i get this exception:

org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.

Please, can you help me?

4

2 回答 2

2

你可以打电话

getHibernateTemplate().getSession().evict(cartA);

将其从会话中删除。

最好的选择是修改cartA。如果您需要使用 cartA 属性进行计算,您可以复制该属性。

于 2013-10-26T13:11:19.670 回答
0

您可以使用org.hibernate.StatelessSessioninterface 而不是org.hibernate.Session.

在 javadocs 中,您会看到:

无状态会话不实现一级缓存,也不与任何二级缓存交互,也不实现事务性后写或自动脏检查,也不将操作级联到关联的实例。无状态会话会忽略集合。通过无状态会话执行的操作绕过 Hibernate 的事件模型和拦截器。由于缺少一级缓存,无状态会话容易受到数据别名效应的影响。

于 2013-10-26T13:40:39.453 回答