定时任务 quartz 里面拿不到 hibernate session
No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
为什么拿不到不知道,反正下面好使
private SessionFactory sessionFactory;
protected void executeInternal(JobExecutionContext context) {
try {
SchedulerContext schCtx = context.getScheduler().getContext();
ApplicationContext appCtx = (ApplicationContext) schCtx.get("applicationContext");
sessionFactory = appCtx.getBean(SessionFactory.class);
} catch (SchedulerException e1) {
e1.printStackTrace();
}
//这里把session绑定进去
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
boolean existingTransaction = SessionFactoryUtils.isSessionTransactional(session, sessionFactory);
if (existingTransaction) {
log.info("Found thread-bound Session for QuartzJobBean");
} else {
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
}
execute();
}
A different object with the same identifier value was already associated with the session
听我分析:
翻译:一个 session 中有两个相同标识符值的不同对象
这里只是举个栗子,下面 item 和 byId 是 Id字段 相同的两个对象
所以在一个session中有了两个相同标识符(Id)
值的不同对象
for (Item item : items) {
//查出来一个对象,在 session 中
Item byId = itemMng.findById(item.getId());
//更新 item 对象时,也要把 item 放在 session 中
itemMng.update(item );
}
怎么解决
更新刚才查出来的对象,这样session中就只有刚才查出来的一个对象
for (Item item : items) {
//查出来一个对象,在 session 中
Item byId = itemMng.findById(item.getId());
//把 item 的属性copy 到 byId 中
BeanUtils.copyProperties(item,byId);
//更新刚才查出来的对象
itemMng.update(byId );
}
总结
查出来什么更新什么,不要再去添加相同 Id 的对象
hibernate 自定义主键策略
/**
* 自定义的主键生成策略
* 如果set了主键id,就使用这个id插入,如果不set主键id,则利用数据库本身的自增策略指定id
* @Author: hekaikai
* @Date: 2020/12/16 14:34
*/
public class CustomGenerator extends IdentityGenerator {
@Override
public Serializable generate(SharedSessionContractImplementor s, Object obj) throws HibernateException {
Serializable id = s.getEntityPersister(null, obj).getClassMetadata().getIdentifier(obj, s);
if (id != null && Integer.valueOf(id.toString()) > 0) {
return id;
} else {
return super.generate(s, obj);
}
}
}