Проблема с управлением транзакциями hibernate / Spring - PullRequest
2 голосов
/ 13 сентября 2011

У меня проблема с управлением Spring Transaction. Я использую Hibernate в качестве платформы ORM. И ниже моя весна для управления транзакциями.

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


  <bean id="abstractDao"
      class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true" lazy-init="true">
    <property name="transactionManager">
        <ref bean="transactionManager"/>
    </property>
    <property name="transactionAttributeSource">
        <ref bean="transactionAttributeSource"/>
    </property>   
    <property name="postInterceptors">
      <list>
        <ref bean="finderIntroductionAdvisor"/>
      </list>
    </property>       
</bean>
   <bean id="abstractService"
      class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true" lazy-init="true">
    <property name="transactionManager">
        <ref bean="transactionManager"/>
    </property>
    <property name="transactionAttributeSource">
        <ref bean="transactionAttributeSource"/>
    </property>   
</bean>

Я в основном придерживаюсь подхода genericDao, как уже упоминалось здесь , поэтому мой DaoObject используется для извлечения объектов Domain, а классы обслуживания имеют объекты DAO для их отображения.

проблема, с которой я сталкиваюсь: я запрашиваю большой набор данных и загружаю результат в список внутри класса обслуживания. я пометил класс обслуживания как @transactional (readonly = "true").

для обработки некоторых требований я изменил все получатели упакованного примитива на

  @Column(name = "students")
public Long getStudents() {
    if(students== null){
        return 0l;
    }
    return this.students;
}

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

есть ли способ, которым я могу избежать этого. я знаю, что Flushmode.never может помочь, но в моем приложении видимость объекта не отображается, поэтому у меня нет к нему доступа. Есть ли какой-либо другой способ или какие-либо изменения в отображении, которые могут мне помочь?

Ответы [ 2 ]

2 голосов
/ 13 сентября 2011

В дополнение к ответу Хави Лопеса, другой вариант - отделить постоянное свойство, обрабатываемое Hibernate, от переходного свойства, которое соответствует вашему требованию. Например, следующим образом:

@Column(name = "students")
public Long getStudentsInternal() {
    return students;
}

@Transient
public Long getStudents() {
    if (students == null) {
        return 0l;
    }
    return students;
}

Вы также можете настроить Hibernate на использование полей вместо свойств, перемещая аннотации к ним, это также решит вашу проблему (обратите внимание, что размещение аннотаций должно быть согласованным для всех полей сущности, или вы можете использовать @Access настроить исключение):

@Column(name = "students")
private Long students;

public Long getStudents() {
    if (students == null) {
        return 0l;
    }
    return students;
}
2 голосов
/ 13 сентября 2011

Проблема с

if(students== null){ return 0l; }

Когда Hibernate выбирает ваши сущности, все они имеют нулевое значение в поле students. Во время фиксации, при проверке, не загрязнены ли они, getStudents() возвращает 0, что отличается от значения, хранящегося в базе данных. Итак, Hibernate видит их как грязные, и переходит к обновлению.

Если это соответствует вашим требованиям, вероятно, поможет изменение типа поля student на тип примитива long вместо Long. Обратите внимание, что это приведет к обновлению всех null в этом столбце до 0 в долгосрочной перспективе.

Может быть, вам следует выполнить это требование где-то еще и освободить добытчика от этой заботы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...