3

I'm seeing this when I run my test. I'm confident that the database connection is being established (or attempted) as it initially gave an error when I didn't include the password, then it complained because the database of that name didn't exist. Once I created the database, it then gave me this error:

$ 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)
...

Below is my config file:

@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();
    }

}

Happy to include more code if it helps. I can successfully log into my mysql console with the same credentials, and the database is there:

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

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

I'm following a safari books video course so pretty new to JPA. Pretty much just taken their code and still getting the error so quite difficult to know which part of the code I should be questioning.

UPDATE

Here is my test I'm running. I'm just running one test for now otherwise my console gets swamped with errors. I'll add the repository code below too:

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) {
        ...
Martyn
  • 6,031
  • 12
  • 55
  • 121

4 Answers4

3

The spring JpaTransactionManager expects some other version of Hibernate, since Session.getFlushMode() seems to be missing.

According to this answer, they recommend downgrading Hibernate to hibernate-core-5.1.0.Final.jar if you are using an older version of Spring.

Check your dependency graph and see if something is overriding the Hibernate version.

KarlP
  • 5,149
  • 2
  • 28
  • 41
  • https://stackoverflow.com/questions/38417613/migration-to-hibernate-core-5-2-1-ava-lang-nosuchmethoderror-org-hibernate-sess/38428648 – KarlP Dec 10 '18 at 11:38
1

Why are you using @Transaction in test class. Use can use @DataJpaTest or @SpringBootTest annotations, mostly prefer @DataJpaTest.

DHARMENDRA SINGH
  • 607
  • 5
  • 21
1

This issue looks like a Jar Conflict. You could try to downgrade to hibernate-core-5.1.0. If not, create a dependency convergence analysis with the maven-enforcer plugin, to make sure you don't have conflicts with the transitive dependencies.

Dezso Gabos
  • 2,297
  • 5
  • 21
  • 29
0

Replace

@Autowired
private AccountRepository repository;

with

@Autowired
private JpaAccountRepository repository;

in your JpaAccountRepositoryTest class

  • Thanks for the reply. Would that matter though as `JpaAccountRepository implements AccountRepository`? Anyway, I tried but still gives me an error: `Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.407 sec <<< FAILURE! testGetAccounts(com.oreilly.repositories.JpaAccountRepositoryTest) Time elapsed: 0.007 sec <<< ERROR! org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.oreilly.repositories.JpaAccountRepositoryTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationExce...` – Martyn Dec 07 '18 at 22:47