Вопросы относительно Spring boot и JPA - PullRequest
0 голосов
/ 08 мая 2018

Я работал над проектом, используя Spring boot, Spring MVC и Hibernate. Я столкнулся с этой проблемой, которая заняла у меня 2 дня.

Мой проект был имитацией твиттера. Когда я начал работать над проектом, я использовал JPA, чтобы получить Hibernate Session. Вот код в моем классе BaseDaoImpl:

@Autowired
private EntityManagerFactory entityManagerFactory;

public Session getSession(){

return entityManagerFactory.createEntityManager().unwrap(Session.class);

}

В своем классе обслуживания я использовал аннотацию @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);
    }



}

Когда я использовал эту настройку, все выглядело нормально, пока я не смог подняться до такой степени, что я начал добавлять функцию «пост». Я мог бы добавлять посты и комментарии в базу данных. Однако я не мог сделать это много раз. Каждый раз, когда я добавлял до 4 сообщений, программа перестала работать - без исключений, без ошибок - страница просто застряла там.

Я посмотрел в Интернете, осознав, что проблема, вероятно, связана с entityManagerFactory. Мне сказали, что entityManagerFactory.createEntityManager().unwrap(Session.class) открывает новые сеансы Hibernate вместо традиционного sessionFactory.getCurrentSession(), который возвращает существующий сеанс.

Так что я начал работать над этим. Я изменил свою конфигурацию Дао на это:

@Autowired
    private EntityManagerFactory entityManagerFactory;
public Session getSession(){

        Session session = entityManagerFactory.unwrap(SessionFactory.class).getCurrentSession();

        return session;
    }

Моя идея состояла в том, чтобы с помощью autowired EntityManagerFactory вернуть Hibernate SessionFactory, чтобы затем можно было использовать метод getCurrentSession.

Но тогда у меня возникла проблема:

Поскольку я настроил этот параметр, любая операция, связанная с вводом данных из контроллера в базу данных service-dao, вызывает исключение: No Transaction Is In Progress

Но странная вещь: хотя система не работала из-за отсутствия видимых транзакций, Hibernate по-прежнему генерирует новые операторы SQL, и данные по-прежнему синхронизируются в базе данных.

Кто-нибудь может мне помочь, как решить эту проблему?

Искренне спасибо!

1 Ответ

0 голосов
/ 09 мая 2018

После @M. По предложению Дейна, я наконец-то решил эту проблему.

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!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...