![](/img/trans.png)
[英]“Write operations are not allowed in read-only mode” error : confused with Spring @Service @transaction @Repository and Hibernate
[英]Hibernate updates database though all the service methods marked as read-only by spring transaction management
我之前已經發布了這個問題,但是由於線程太舊了,我想我沒有得到答復,因此對不起重復,但是我的問題與春季交易有關。
我面臨與Spring事務管理類似的問題。 我正在使用休眠作為ORM框架。 以下是我的應用程序使用Spring事務管理的Spring配置文件的摘錄。
<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>
我所有的* Service類都由@Transactional
注釋進行注釋。
在我的休眠DTO類中,我正在如下修改每個get *方法的返回值,因為我想刪除所有非ASCII字符。 數據庫中的數據僅供只讀,僅用於列出記錄,在此之前,我需要刪除造成問題的非ascii字符。 數據庫是Oracle 11g。
例如,對於屬性accountNumber
public String getAccountNumber(){
return StringHelper.removeNonAscii(this.accountNumber);
}
我已經讀到我們正在更改DTO對象的狀態並使它變臟,因此休眠狀態會將這些臟對象刷新到db中。 我可以在日志中看到更新語句。
我的問題是:
1.)我正在使DTO對象變臟,但是我將與get *相關的方法標記為只讀,因此如何休眠將刷新對數據庫的更改。
2.)如何在不更改數據庫數據的情況下解決與該非Ascii字符有關的問題。 我想念什么嗎?
從Hibernate參考 :
每當您將對象傳遞到save(),update()或saveOrUpdate()時,以及每當使用load(),get(),list(),iterate()或scroll()檢索對象時,都會將該對象添加到會話的內部緩存。
隨后調用flush()時,該對象的狀態將與數據庫同步。 如果您不希望發生這種同步,或者正在處理大量對象並且需要有效地管理內存,則可以使用evict()方法從一級緩存中刪除該對象及其集合。
我的猜測是,即使您的get *方法是只讀的,它們仍然將持久對象放在Hibernate會話上,該對象將在某個時候刷新,從而保存您的更改。
您是否可以簡單地在get *方法的末尾將ctct()移出DTO對象,以便在Hibernate Session有機會刷新對這些對象的任何更改之前將它們與Hibernate Session分離?
在我的休眠DTO類中,我正在如下修改每個get *方法的返回值,因為我想刪除所有非ASCII字符。
即時修改返回值不會修改實體本身。 換句話說,它不應該變臟。
我已經讀到我們正在更改DTO對象的狀態並使它變臟,因此休眠狀態會將這些臟對象刷新到db中。
然后,您在某個時候打電話給二傳手。
我正在使DTO對象變臟,但已將與get *相關的方法標記為只讀,因此如何休眠將刷新對數據庫的更改。
我懷疑您在getter中進行任何數據庫訪問(並且我認為對事務部分有一些誤解)。
如何在不更改數據庫數據的情況下解決與該Non Ascii字符有關的問題。 我想念什么嗎?
如我所寫,我認為訪問getter不會使您的實體變得骯臟,必須有其他東西。 但是,如果它們確實是只讀的,則可以將它們標記為不可變的(請參見5.1.3。Class )。
大家好,我能夠通過按照Pascal Thivent的建議在.hbm.xml文件中將DTO類標記為不可變來解決我的問題,謝謝您的幫助。 但是我不確定為什么標記為只讀的事務會發生這種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.