views:

38

answers:

3

I have already posted this question before but as the thread is little old I think I am not getting reply so sorry for duplicating but my issue is something related to spring transaction.

I am facing a similiar problem with Spring Transaction management. I am using hibernate as ORM framework. And below is the excerpt of spring configuration file of my application which uses spring transaction management.

<context:annotation-config/>
    <context:property-placeholder location="classpath:spring.properties"/>

    <tx:annotation-driven transaction-manager="transactionManager"/>
    <tx:advice id="txAdvice">
        <tx:attributes>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="create*" rollback-for="Exception"/>
            <tx:method name="update*" rollback-for="Exception"/>
            <tx:method name="remove*" rollback-for="Exception"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="ServiceOperation" expression="execution(* com.shaikh.demo.*Service.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="ServiceOperation"/>
    </aop:config>

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

All my *Service Classes are annotated by @Transactional annotation.

In my hibernate DTO classes I am modifying return value for each get* method as below because I want to remove all the non-ascii characters. The data in the database is for read-only purpose just for listing down the records ,before this I need to remove non-ascii characters which are creating problems. Database is Oracle 11g.

e.g. For attribute accountNumber

public String getAccountNumber(){
      return StringHelper.removeNonAscii(this.accountNumber);
}

I have read that we are changing the state of the DTO object and making it dirty so hibernate is flushing this dirty objects into the db. I can see the update statements in logs.

Here my questions are :

1.) I am making DTO objects dirty but I have marked get* related methods as Read-only so how can hibernate is flushing changes to the db.

2.) How can I solve my problem related to this Non Ascii character without changing my database data. Am I missing something ?

A: 

From the Hibernate Reference:

Whenever you pass an object to save(), update() or saveOrUpdate(), and whenever you retrieve an object using load(), get(), list(), iterate() or scroll(), that object is added to the internal cache of the Session.

When flush() is subsequently called, the state of that object will be synchronized with the database. If you do not want this synchronization to occur, or if you are processing a huge number of objects and need to manage memory efficiently, the evict() method can be used to remove the object and its collections from the first-level cache.

My guess is that, even though your get* methods are read-only, they're still putting persistent objects on the Hibernate Session which will get flushed at some point, saving your changes.

Could you simply evict() your DTO objects at the end of the get* methods, so that they are detached from the Hibernate Session before it has the chance to flush any changes to those objects?

James Earl Douglas
Could you simply evict() your DTO objects at the end of the get* methodsI am fetching list of objects from the db through dao and I think this evict method works on object level so I doesnt want to iterate through this list and apply evict method on each object.
Shaikh Mohammed Shariq
A: 

In my hibernate DTO classes I am modifying return value for each get* method as below because I want to remove all the non-ascii characters.

Modifying the return value on the fly won't modify the entity itself. In other words, it shouldn't become dirty.

I have read that we are changing the state of the DTO object and making it dirty so hibernate is flushing this dirty objects into the db.

Then you are calling some setter at some point.

I am making DTO objects dirty but I have marked get* related methods as Read-only so how can hibernate is flushing changes to the db.

I doubt you're making any database access in the getter (and I think there is some misunderstanding of the transactional part).

How can I solve my problem related to this Non Ascii character without changing my database data. Am I missing something?

As I wrote, I don't think accessing getters make your entities dirty, there must be something else. But if really they are read-only, you can mark them as immutable (see 5.1.3. Class).

Pascal Thivent
Modifying the return value on the fly won't modify the entity itself. In other words, it shouldn't become dirty.That is what I was thinking so I have updated DTO classes to remove non-ascii characters. I will try to debug my transaction code and also this immutable stuff. Thanks All for your replies, will get back to you soon.
Shaikh Mohammed Shariq
A: 

HI All I was able to fix my issue by marking DTO class as immutable in .hbm.xml file as suggested by Pascal Thivent, thanks for your help. But I am not sure why this happens for the transaction marked as read-only.

Shaikh Mohammed Shariq