Hibernate обновляет базу данных, хотя все методы обслуживания помечены как доступные только для чтения при управлении транзакциями Spring - PullRequest
1 голос
/ 11 августа 2010

Я уже писал этот вопрос раньше, но поскольку ветка устарела, я думаю, что не получаю ответа, извините за дублирование , но моя проблема связана с весенней транзакцией.

У меня похожая проблема с управлением Spring Transaction.Я использую Hibernate в качестве платформы 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>

Все мои * классы обслуживания снабжены аннотацией @Transactional.

В моем гибком DTOКлассы Я изменяю возвращаемое значение для каждого метода get *, как показано ниже, потому что я хочу удалить все не-ascii символы.Данные в базе данных предназначены только для чтения и предназначены для перечисления записей, перед этим мне нужно удалить не-ascii символы, которые создают проблемы.База данных - Oracle 11g.

Например, для атрибута accountNumber

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

Я прочитал, что мы меняем состояние объекта DTO и делаем его грязным, чтобы в спящем режиме эти грязные объекты сбрасывались вдб.Я могу видеть операторы обновления в журналах.

Вот мои вопросы:

1.) Я делаю объекты DTO грязными, но я пометил методы get * related только для чтения, так как я могуhibernate сбрасывает изменения в базу данных.

2.) Как я могу решить мою проблему, связанную с этим персонажем Non Ascii, без изменения данных в моей базе данных.Я что-то упустил?

Ответы [ 3 ]

0 голосов
/ 11 августа 2010

В моих классах DTO гибернации я изменяю возвращаемое значение для каждого метода get *, как показано ниже, потому что хочу удалить все не-ascii символы.

Изменение возвращаемого значения на лету не изменит сам объект. Другими словами, это не должно стать грязным.

Я читал, что мы меняем состояние объекта DTO и делаем его грязным, чтобы спящий режим сбрасывал эти грязные объекты в базу данных.

Тогда вы в какой-то момент вызываете сеттера.

Я делаю объекты DTO грязными, но я пометил методы get * related только для чтения, так как hibernate сбрасывает изменения в БД.

Я сомневаюсь, что вы делаете какой-либо доступ к базе данных в геттере (и я думаю, что есть некоторое недопонимание транзакционной части).

Как я могу решить мою проблему, связанную с этим персонажем, отличным от Ascii, без изменения данных в моей базе данных. Я что-то пропустил?

Как я писал, я не думаю, что доступ к геттерам делает ваши сущности грязными, должно быть что-то еще. Но если на самом деле они доступны только для чтения, вы можете пометить их как неизменяемые (см. 5.1.3. Класс ).

0 голосов
/ 18 августа 2010

HI Все, что я смог исправить мою проблему, пометив класс DTO как неизменяемый в файле .hbm.xml, как это предложил Паскаль Тивент, спасибо за вашу помощь.Но я не уверен, почему это происходит для транзакции, помеченной как доступная только для чтения.

0 голосов
/ 11 августа 2010

Из Hibernate Reference :

Всякий раз, когда вы передаете объект для save (), update () или saveOrUpdate (), и всякий раз, когда вы извлекаете объект, используя load), get (), list (), iterate () или scroll (), этот объект добавляется во внутренний кэш сеанса.

Когда впоследствии вызывается flush (), состояние этого объекта будетсинхронизироваться с базой данных.Если вы не хотите, чтобы эта синхронизация происходила, или если вы обрабатываете огромное количество объектов и вам необходимо эффективно управлять памятью, метод evict () можно использовать для удаления объекта и его коллекций из кэша первого уровня.

Я предполагаю, что, хотя ваши методы get * доступны только для чтения, они по-прежнему помещают постоянные объекты в сеанс Hibernate, которые в какой-то момент сбрасываются, сохраняя ваши изменения.

Не могли бы вы просто evict () свои объекты DTO в конце методов get *, чтобы они отсоединились от сеанса Hibernate до того, как у него появится возможность сбросить любые изменения этих объектов?

...