关于Spring启动和JPA的问题

时间:2018-05-08 02:17:03

标签: java spring hibernate spring-mvc spring-boot

我正在使用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语句,数据仍然会同步到数据库中。

有人可以帮我解决如何解决这个问题吗?

真诚的感谢!

1 个答案:

答案 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!