繁体   English   中英

休眠/春季交易管理问题

[英]Issue with hibernate/Spring transaction management

我在Spring事务管理中面临一个问题。 我正在使用休眠作为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方法,因此My DaoObject用于获取Domain对象,而服务类具有DAO对象以对其进行处理。

我面临的问题:我正在查询大型数据集并将结果加载到服务类内的列表中。 我已经将服务类标记为@transactional(readonly =“ true”)。

为了处理一些要求,我将盒装原语的所有吸气剂更改为

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

每当我通过命名查询加载所有数据集时。 随后触发多个更新查询以更新数据集。 我调试了它,然后知道这是由于transaction.commit发生的。 就像冬眠把我的实体当成肮脏一样。

有什么办法可以避免这种情况吗? 我知道Flushmode.never可能无济于事,但在我的应用程序中未看到渗透对象,因此我无法访问它。 还有其他方法或某些映射更改可以帮助我吗?

问题是

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

当Hibernate提取您的实体时,它们在students字段中的值均为空。 在提交时,当检查它们是否脏时, getStudents()返回0,这与存储在数据库中的值不同。 因此,Hibernate认为它们很脏,然后继续进行更新。

如果适合您的要求,将student字段的类型更改为基本类型long而不是Long可能会有所帮助。 请注意,从长远来看,这将导致将该列中的所有null都更新为0。

也许您应该在其他地方处理该要求,并使吸气剂摆脱这种担忧。

除了XaviLópez的答案外,另一种选择是将Hibernate处理的持久属性与符合您要求的瞬时属性分开。 例如,如下:

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

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

您还可以通过将注释移动到Hibernate上来配置Hibernate以使用字段而不是属性,这也将解决您的问题(请注意,注释的放置对于实体的所有字段都应是适当的,或者您可以使用@Access来配置排除):

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM