Hibernate通过spring transaction management标记为只读的所有服务方法更新数据库

时间:2010-08-11 04:25:32

标签: hibernate spring transactions dto

我之前已经发布过这个问题,但由于线程有点老,我想我没有收到回复,对duplicating抱歉,但我的问题与春季交易有关。

我面临着与Spring Transaction管理类似的问题。我使用hibernate作为ORM框架。以下是我的应用程序的spring配置文件的摘录,该文件使用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>

我的所有*服务类都由@Transactional注释注释。

在我的hibernate DTO类中,我正在修改每个get *方法的返回值,如下所示,因为我想删除所有非ascii字符。数据库中的数据仅用于列出记录的只读目的,在此之前我需要删除产生问题的非ascii字符。数据库是Oracle 11g。

e.g。对于属性accountNumber

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

我已经读过我们正在改变DTO对象的状态并使其变脏,因此hibernate将这些脏对象刷新到db中。我可以在日志中看到更新语句。

我的问题是:

1。)我正在使DTO对象变脏,但是我将get *相关方法标记为只读,那么hibernate如何刷新对db的更改。

2.。)如何在不更改数据库数据的情况下解决与此非Ascii字符相关的问题。我错过了什么吗?

3 个答案:

答案 0 :(得分:0)

来自Hibernate Reference

  

无论何时将对象传递给save(),   update()或saveOrUpdate(),和   每当你使用时检索一个对象   load(),get(),list(),iterate()或   scroll(),该对象被添加到   会话的内部缓存。

     

随后调用flush()时,   该对象的状态将是   与数据库同步。如果你   不希望这种同步   发生,或者如果你正在处理一个巨大的   对象数量和需要管理   有效的记忆,evict()方法   可以用来删除对象和   它的收藏来自一级   高速缓存中。

我的猜测是,即使你的get *方法是只读的,它们仍然会在Hibernate Session上放置持久对象,这些对象会在某个时刻被刷新,从而保存你的更改。

您是否可以在get *方法的末尾简单地evict()您的DTO对象,以便它们在有机会刷新对这些对象的任何更改之前与Hibernate会话分离?

答案 1 :(得分:0)

  

在我的hibernate DTO类中,我正在修改每个get *方法的返回值,如下所示,因为我想删除所有非ascii字符。

动态修改返回值不会修改实体本身。换句话说,它不应该变脏。

  

我已经读过我们正在改变DTO对象的状态并使其变脏,因此hibernate将这些脏对象刷新到db中。

然后你在某个时候打电话给某人。

  

我正在使DTO对象变脏,但我已将get *相关方法标记为只读,因此hibernate如何将更改刷新到db。

我怀疑你是否在getter中进行任何数据库访问(我认为对事务部分存在一些误解)。

  

如何在不更改数据库数据的情况下解决与此非Ascii字符相关的问题。我错过了什么吗?

正如我所写,我不认为访问getter会让你的实体变脏,所以必须有别的东西。但如果他们真的是只读的,你可以将它们标记为不可变(见5.1.3. Class)。

答案 2 :(得分:0)

HI所有我能够修复我的问题是在Pascal Thivent建议的.hbm.xml文件中将DTO类标记为不可变的,感谢您的帮助。但我不确定为什么这会发生标记为只读的事务。