我是Hibernate的新手。我正在尝试编写一个方法,插入或更新50条记录然后提交它&然后再次继续插入。我这样做是因为如果在插入最后一条记录时发生了某些事情,我想保留数据库中的所有先前记录。
这就是我在做的事情:
view.sendSubviewToBack
这样可以正常工作但在执行此方法后会发生异常。由于这个原因,此方法的返回值从未返回到调用方法。谁能帮我? stacktrace:
@Override
public boolean updateStoreDetails(List<StoreDetailsDTO> storeDetailsDTOs){
Session session = this.hibernateSessionFactory.getCurrentSession();
int count = 0;
boolean sessionEnded =false;
for(StoreDetailsDTO storeDetailsDTOTmp : storeDetailsDTOs){
if(sessionEnded){//At the very beginning, the transaction remains open dont know why. So session.getTransaction().begin() causing exception
session.getTransaction().begin();
sessionEnded = false;
}
session.saveOrUpdate(storeDetailsDTOTmp);
if ( ++count % 10 == 0 ) { //If batch size is 50 clear session-level cache & to avoid OutOfMemoryException
logger.info("Clearing session after 50 batch size. Total rows inserted/updated till now: "+ count);
session.getTransaction().commit();
session.flush();
session.clear();
sessionEnded =true;
} else if(count == storeDetailsDTOs.size()){
session.getTransaction().commit();
session.flush();
session.clear();
}
}
logger.info("Insertion completed. Total rows inserted/updated: "+ count);
return true;
}
答案 0 :(得分:1)
仅当sessionEnded
为true
但您仅在true
之后将其设置为session.getTransaction().commit()
时才会打开会话。更好的解决方案是在循环之外开始和结束会话。
答案 1 :(得分:1)
我已将@Transactional
放在班级。我相信这导致了这个问题,虽然我不确定。删除后,我在执行时遇到了一些错误:this.hibernateSessionFactory.getCurrentSession();
。我想我必须为此设置一个属性。
无论如何要实现我想要的东西我修改了方法:
@Override
public boolean updateStoreDetails(List<StoreDetailsDTO> storeDetailsDTOs){
Session session = this.hibernateSessionFactory.getCurrentSession();
int count = 0;
boolean sessionEnded =false;
for(StoreDetailsDTO storeDetailsDTOTmp : storeDetailsDTOs){
session.saveOrUpdate(storeDetailsDTOTmp);
//session.evict(storeDetailsDTOTmp);
if ( ++count % 50 == 0 ) { //If batch size is 50 clear session-level cache & to avoid OutOfMemoryException
logger.info("Clearing session after 50 batch size.");
session.flush();
session.clear();
}
}
return true;
}
我在插入50条记录后调用此方法。请注意,在修改方法后,我已在类级别保留@Transactional
注释。
感谢大家的帮助!!
答案 2 :(得分:0)
以下是您可以在50条记录之后将记录刷新到DB中的代码,但是在发生故障的情况下提交/回滚所有这些通常是场景但是如果要提交50条记录,则在清除后执行提交。
public void insert(List<T> items) {
//begin transaction
for (int i = 0; i < items.size(); i++) {
T item = items.get(i);
session.save(item);
if (i % 50 == 0) {
session.flush();
session.clear();
}
}
session.flush();
session.clear();
//commit transaction
}
答案 3 :(得分:0)
标志检查中存在错误,导致交易无法开始。我做了改变,希望这会有效。
@Override
public boolean updateStoreDetails(List<StoreDetailsDTO> storeDetailsDTOs)
{
Session session = this.hibernateSessionFactory.getCurrentSession();
int count = 0;
boolean sessionEnded =true; for(StoreDetailsDTO storeDetailsDTOTmp : storeDetailsDTOs)
{
if(sessionEnded)
{
session.getTransaction().begin(); sessionEnded = false;
} session.saveOrUpdate(storeDetailsDTOTmp) ;
if ( ++count % 10 == 0 )
{
//If batch size is 50 clear session-level cache & to avoid OutOfMemoryException
logger.info("Clearing session after 50 batch size. Total rows inserted/updated till now: "+ count);
session.getTransaction().commit();
session.flush(); session.clear();
sessionEnded =true;
}
else if(count == storeDetailsDTOs.size()){
session.getTransaction().commit();
session.flush();
session.clear();
}
}
logger.info("Insertion completed. Total rows inserted/updated: "+ count);
return true;
}