Reputation: 3
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("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.
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?
Upvotes: 0
Views: 1895
Reputation: 7322
You can use org.hibernate.StatelessSession
interface instead of org.hibernate.Session
.
In javadocs you see:
A stateless session does not implement a first-level cache nor interact with any second-level cache, nor does it implement transactional write-behind or automatic dirty checking, nor do operations cascade to associated instances. Collections are ignored by a stateless session. Operations performed via a stateless session bypass Hibernate's event model and interceptors. Stateless sessions are vulnerable to data aliasing effects, due to the lack of a first-level cache.
Upvotes: 0
Reputation: 7048
You could call
getHibernateTemplate().getSession().evict(cartA);
to remove it from the session.
The best option though is to not modify cartA. If you need to calculate something using a cartA property you could make a copy of that property.
Upvotes: 2