【发布时间】:2014-10-01 07:53:38
【问题描述】:
我正在使用 Spring MVC + Hibernate 并尝试使用“休眠批处理技术”保存批量记录,但在执行 session.flush() 和 session.clear() 时遇到异常。
org.hibernate.LazyInitializationException: 无法初始化代理 - 没有会话
以下是我的代码示例
-
DaoImpl 方法
@SuppressWarnings("unchecked") @Override public String transferPsalesDataToMisSales() { Session session = null; Transaction tx=null; String result="failed"; try {session = this.getSessionFactory().openSession(); tx = session.beginTransaction(); Criteria criteria=session.createCriteria(PsalesInfo.class); List<PsalesInfo> pSalesData=criteria.list(); if(pSalesData.size() >0){ Iterator<PsalesInfo> it=pSalesData.iterator(); int index=0; MisSalesInfo mis=null; while(it.hasNext()){ mis=new MisSalesInfo(); PsalesInfo psales=it.next(); StockistInfo stockistInfo=psales.getStockistInfo(); TalukaInfo talukaInfo=stockistInfo.getTalukaInfo(); IsrInfo isr=(IsrInfo) session.get(IsrInfo.class, stockistInfo.getIsrId()); //mis settters mis.setMisSalesId(psales.getPsalesId()); mis.setStateName(talukaInfo.getDistrictInfo().getStateInfo().getStateName()); mis.setDistName(talukaInfo.getDistrictInfo().getDistName()); mis.setTalukaName(talukaInfo.getTalukaName()); mis.setAsmId(talukaInfo.getAsmInfo().getAsmId()); mis.setTsoId(stockistInfo.getTsoInfo().getTsoId()); if(null!=isr){ mis.setIsrId(isr.getIsrId()); mis.setIsrName(isr.getIsrName()); } mis.setUnitNo(stockistInfo.getUnitNo()); mis.setBillNo(psales.getBillNo()); session.save(mis); if(index % 50==0){ //flush a batch of inserts and release memory: session.flush(); session.clear(); } index++; }//end of while tx.commit(); result=pSalesData.size()+" Psales are Successfully transfered to MIS Sales"; } else{ result="No Psales is available to transfer since are already available in MIS Sales"; } } catch (HibernateException e) { tx.rollback(); logger.error("error in MasterDaoImpl transfer data:"+e); }finally { if (null != session) session.close(); } return result; } -
POJO
@Entity @Table(name = "psales_info", catalog = "secondary_sales") public class PsalesInfo implements java.io.Serializable { private static final long serialVersionUID = 5578632011679493005L; private Integer psalesId; private StockistInfo stockistInfo; //and some other attributes //getter and setters @Id @GenericGenerator(name="generator", strategy="increment") @GeneratedValue(generator="generator") @Column(name = "psales_id", unique = true, nullable = false) public Integer getPsalesId() { return this.psalesId; } public void setPsalesId(Integer psalesId) { this.psalesId = psalesId; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "pcode", nullable = false) public StockistInfo getStockistInfo() { return this.stockistInfo; } //and others @Entity @Table(name = "stockist_info", catalog = "secondary_sales") public class StockistInfo implements java.io.Serializable { private String stockistId; private TalukaInfo talukaInfo; //and rest attributes //getters and setters // Property accessors @Id @Column(name = "stockist_id", unique = true, nullable = false, length = 10) public String getStockistId() { return this.stockistId; } public void setStockistId(String stockistId) { this.stockistId = stockistId; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "taluka_sid", nullable = false) public TalukaInfo getTalukaInfo() { return this.talukaInfo; } -
服务实现
@Service @Transactional public class TransactionServiceImpl implements TransactionService { @Autowired private TransactionDAO transactionDAO;
}@Override public String transferPsalesDataToMisSales() { return this.getTransactionDAO().transferPsalesDataToMisSales(); } -
dispature-servlet.xml
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:hibernate.cfg.xml"/> <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> <prop key="hibernate.default_catalog">${hibernate.default_catalog}</prop> <prop key="hibernate.jdbc.batch_size">50</prop> </props> </property> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory"/>
这里需要帮助,为什么当我清除会话时它会抛出 LazyInitializationException。
但是当我没有清除会话时,即。 session.clear() 和 session.flush() 应用程序运行正常。
但我知道如果有更多批量记录,它可能会导致OutOfMemoryException。
所以请告诉现在如何处理这种情况?
【问题讨论】:
标签: spring hibernate spring-mvc batch-processing lazy-initialization