I need to run my tests in docker containers. I have Testcontainers lib for this. Besides that I use hibernate. Also, I use Flyway to run some initial SQL scripts. I'm new in Testcontainers and Hibernate and don't understand why I get "Relation not found exception". This is how my app organized:
Abstract test for initializing container:
@ActiveProfiles("test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ContextConfiguration(initializers = AbstractIT.DockerPostgreDataSourceInitializer.class)
@Testcontainers
public class AbstractIT {
public static PostgreSQLContainer<?> postgreDBContainer = new PostgreSQLContainer<>
("postgres:12.2");
static {
postgreDBContainer.start();
}
public static class DockerPostgreDataSourceInitializer implements
ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
applicationContext,
"spring.datasource.url=" + postgreDBContainer.getJdbcUrl(),
"spring.datasource.username=" + postgreDBContainer.getUsername(),
"spring.datasource.password=" + postgreDBContainer.getPassword()
);
}
}
}
My test for "create" function that extends abstract AbstractIT:
@SpringBootTest
class JdbcGroupDaoTest extends AbstractIT {
@Autowired
private JdbcGroupDao jdbcGroupDao;
@Test
void create() throws Exception {
jdbcGroupDao.setFactory(Persistence.createEntityManagerFactory("university-test"));
Group group = new Group("Test group");
Group expected = new Group(1L, "Test group");
Group actual = jdbcGroupDao.save(group);
assertEquals(expected, actual);
}
}
Class under test:
@Component
public class JdbcGroupDao extends JdbcAbstractDao<Group, Long> implements GroupDao {
private EntityManagerFactory factory ;
private static final Logger LOGGER = LoggerFactory.getLogger(JdbcGroupDao.class);
@Override
public void setFactory(EntityManagerFactory factory){
this.factory = factory;
}
@Override
protected Group create(Group group) {
if(factory==null){
factory=Persistence.createEntityManagerFactory("university");
}
EntityManager entityManager = factory.createEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(group);
entityManager.getTransaction().commit();
entityManager.close();
entityManager.flush();
factory.close();
return group;
}
My config file for Hibernate:
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="university">
<properties>
<property name="javax.persistence.jdbc.url"
value="jdbc:postgresql://localhost:5432/university" />
<property name="javax.persistence.jdbc.user" value="admin" />
<property name="javax.persistence.jdbc.password" value="admin" />
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
<persistence-unit name="university-test">
<properties>
<property name="javax.persistence.jdbc.driver"
value="org.testcontainers.jdbc.ContainerDatabaseDriver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:tc:postgresql:9.6.8:///university"/>
<property name="javax.persistence.jdbc.user" value="admin" />
<property name="javax.persistence.jdbc.password" value="admin" />
</properties>
</persistence-unit>
</persistence>
The error message:
Caused by: org.postgresql.util.PSQLException: ERROR: relation "groups" does not exist
I have two persistence units here because this is the only way I found to prevent hibernate from altering data in real DB. I believe this is the main reason why I got my error. Though I don't know how to fix it. If you need more info about my code, feel free to ask, I will add whatever you need into my post. Thanks in advance.
EDIT: Flyway init. sql file. (added code related to "groups" only):
create table groups
(
id serial
constraint groups_pkey
primary key,
title varchar(100)
);
alter table groups
add constraint uq_groups_title UNIQUE
(
title
);