我正在使用Spring启动,Spring MVC和Hibernate开发一个项目。我遇到了这个已经花了我2天的问题。
我的项目是模仿推特。当我开始研究项目时,我使用JPA来获取Hibernate Session。这是我的BaseDaoImpl类中的代码:
@Autowired
private EntityManagerFactory entityManagerFactory;
public Session getSession(){
return entityManagerFactory.createEntityManager().unwrap(Session.class);
}
在我的Service类中,我使用了@Transactional注释:
@Service("userServ")
@Transactional(propagation=Propagation.REQUIRED, readOnly=false,rollbackFor={Exception.class, RuntimeException.class})
public class UserServImpl implements IUserServ {}
最后,我的主要课程概述:
@SpringBootApplication
@EnableTransactionManagement
@EntityScan(basePackages = {"edu.miis.Entities"})
@ComponentScan({"edu.miis.Controllers","edu.miis.Service","edu.miis.Dao"})
@EnableAutoConfiguration
@Configuration
public class FinalProjectSpringbootHibernateDruidApplication {
public static void main(String[] args) {
SpringApplication.run(FinalProjectSpringbootHibernateDruidApplication.class, args);
}
}
当我使用此设置时,一切似乎都很好 - 直到我能够移动到我开始添加“post”功能的程度。我可以在数据库中添加帖子和评论。但是,我不能这么做很多次。每次我添加最多4个帖子,程序停止运行 - 没有例外,没有错误 - 页面刚刚卡在那里。
我在线查看,发现问题可能是由于entityManagerFactory。我被告知entityManagerFactory.createEntityManager().unwrap(Session.class)
打开新的Hibernate会话,而不是返回现有会话的传统sessionFactory.getCurrentSession()
。
所以我开始研究它。我将Dao配置改为:
@Autowired
private EntityManagerFactory entityManagerFactory;
public Session getSession(){
Session session = entityManagerFactory.unwrap(SessionFactory.class).getCurrentSession();
return session;
}
我的想法是使用自动装配的EntityManagerFactory返回一个Hibernate SessionFactory,以便可以使用getCurrentSession方法。
但后来我遇到了问题:
由于我配置了此设置,因此涉及从控制器到service-dao-database的输入的任何操作都会调用异常:No Transaction Is In Progress
但奇怪的是:虽然由于没有可见的事务正在进行系统崩溃,但Hibernate仍会生成新的SQL语句,数据仍然会同步到数据库中。
有人可以帮我解决如何解决这个问题吗?
真诚的感谢!
答案 0 :(得分:0)
关注@M。 Deinum的建议,我终于解决了这个问题。
The reason why the @Transactional annotation didn't work in my code in the first place, was because in my original code, I used plain Hibernate features - Session, SessionFactory, getCurrentSession() etc.
In order for these features to work, I need to specifically configure the transaction manager into a Hibernate Transaction Manager (under default setting, Spring boot autowires a JPA transaction manager).
But the problem is: most of methods that were used to support Hibernate features are now deprecated. Now, the JPA method is the mainstream.
Use EntityManager instead of Session/
Use EntityManager.persist instead of Session.save
Use EntityManager.merge instead of Session.update
Use EntityManager.remove instead of Session.remove.
That's all.
Thanks!