Не удалось открыть JPA EntityManager для транзакции (с использованием LocalContainerEntityManagerFactoryBean) - PullRequest
0 голосов
/ 07 декабря 2018

Я вижу это, когда запускаю тест.Я уверен, что соединение с базой данных устанавливается (или предпринимается), так как оно первоначально выдало ошибку, когда я не включил пароль, а затем пожаловалось, что база данных с таким именем не существует.После того, как я создал базу данных, она выдала мне эту ошибку:

$ mvn clean test
...
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.317 sec <<< FAILURE!
testGetAccounts(com.oreilly.repositories.JpaAccountRepositoryTest)  Time elapsed: 0.104 sec  <<< ERROR!
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is java.lang.NoSuchMethodError: org.hibernate.Session.getFlushMode()Lorg/hibernate/FlushMode;
    at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:431)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
    at org.springframework.test.context.transaction.TransactionContext.startTransaction(TransactionContext.java:98)
...

Ниже приведен мой конфигурационный файл:

@Configuration
@ComponentScan(basePackages = "com.oreilly")
@PropertySource("classpath:prod.properties")
@EnableTransactionManagement
public class AppConfig {
    @Autowired
    private Environment env;

    @Bean
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(env.getProperty("db.driver"));
        dataSource.setUrl(env.getProperty("db.url"));
        dataSource.setUsername(env.getProperty("db.user"));
        dataSource.setPassword(env.getProperty("db.pass"));
        return dataSource;
    }

    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setShowSql(true);
        adapter.setGenerateDdl(true);
        adapter.setDatabase(Database.MYSQL);
        return adapter;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {

        Properties props = new Properties();
        props.setProperty("hibernate.format_sql", String.valueOf(true));

        LocalContainerEntityManagerFactoryBean emf =
                new LocalContainerEntityManagerFactoryBean();
        emf.setDataSource(dataSource);
        emf.setPackagesToScan("com.oreilly.entities");
        emf.setJpaVendorAdapter(jpaVendorAdapter);
        emf.setJpaProperties(props);

        return emf;
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }

    @Bean
    public BeanPostProcessor persistenceTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

}

Рад включить больше кода, если это поможет.Я могу успешно войти в консоль mysql с теми же учетными данными, и база данных там есть:

$ mysql -uroot -p spring
Enter password: 
...

mysql> show databases;
+-----------------------+
| Database              |
+-----------------------+
| ...                   |
| spring                |
+-----------------------+
10 rows in set (0.00 sec)

Я слежу за видеокурсом по книгам по сафари, так что я довольно новичок в JPA.Практически просто взяли их код и все еще получали сообщение об ошибке, поэтому довольно сложно определить, какую часть кода мне следует задавать.

ОБНОВЛЕНИЕ

Вот мой тест, который я выполняю.Сейчас я просто провожу один тест, иначе моя консоль забита ошибками.Я также добавлю код репозитория ниже:

JpaAccountRepositoryTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
@Transactional
public class JpaAccountRepositoryTest {

    @Autowired
    private AccountRepository repository;

    @Test
    public void testGetAccounts() throws Exception {
        List<Account> accounts = repository.getAccounts();
        assertThat(accounts.size(), is(3));
    }

//    @Test
//    public void testGetAccount() throws Exception {
//       ...

JpaAccountRepository.java

@Repository
public class JpaAccountRepository implements AccountRepository {
    private long nextId = 4;

    @PersistenceContext
    private EntityManager entityManager;

    public List<Account> getAccounts() {
        return entityManager.createQuery("select a from Account a", Account.class)
                .getResultList();
    }

    public Account getAccount(Long id) {
        ...

Ответы [ 4 ]

0 голосов
/ 17 декабря 2018

Эта проблема выглядит как конфликт Jar.Вы можете попробовать перейти на hibernate-core-5.1.0.Если нет, создайте анализ сходимости зависимостей с помощью плагина maven -forcer, чтобы убедиться, что у вас нет конфликтов с переходными зависимостями.

0 голосов
/ 10 декабря 2018

Spring JpaTransactionManager ожидает какую-то другую версию Hibernate, поскольку Session.getFlushMode (), по-видимому, отсутствует.

Согласно этому ответу , они рекомендуют понизить Hibernate до hibernate-core-5.1.0.Final.jar, если вы используете более старую версию Spring.

Проверьте свой график зависимостей и посмотрите, не перекрывает ли что-нибудь версию Hibernate.

0 голосов
/ 17 декабря 2018

Почему вы используете @Transaction в тестовом классе.Использование может использовать @DataJpaTest или @SpringBootTest аннотации, в основном предпочитают @DataJpaTest.

0 голосов
/ 08 декабря 2018

Замените

@Autowired
private AccountRepository repository;

на

@Autowired
private JpaAccountRepository repository;

в вашем классе JpaAccountRepositoryTest

...