0

I want to run tests on my app using h2 as a database but every time I attempt to run a test it shows me an exception saying that h2 db is empty. None of the related questions I`ve read helped me.

This is the method I am trying to test:

/// I know is pointless to test this, but I am learning to implement tests
public interface ConocimientoRepository extends JpaRepository<Conocimiento,Long>{
    @Modifying 
    @Transactional 
    @Query(value = "DELETE FROM conocimiento WHERE busca_id = :buscaId", nativeQuery = true) 
    void deleteAllConocimientoFromBuscaId(@Param("buscaId") Long buscaId);
}

The test itself:

@DataJpaTest
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
@ActiveProfiles("test")
public class ConocimientoRepositoryTests {

    @Autowired
    BuscaRepository buscaRepository;
    
    @Autowired
    ConocimientoRepository conocimientoRepository;

    private Busca b1, b2;
    private List<Conocimiento> listConocimientos;

    @BeforeEach
    public void initData() {

        b1 = new Busca("Ana", "[email protected]", "Sevilla", "612345678", "Password1!");
        b2 = new Busca("Luis", "[email protected]", "Madrid", "712345678", "SecurePwd2@");

        listConocimientos = List.of(
            Conocimiento.builder()
                .centroEducativo("Centro 1")
                .titulo("Título 1")
                .inicioPeriodoConocimiento(LocalDate.of(2020, 1, 1))
                .finPeriodoConocimiento(LocalDate.of(2021, 1, 1))
                .busca(b1)
                .build(),
            Conocimiento.builder()
                .centroEducativo("Centro 2")
                .titulo("Título 2")
                .inicioPeriodoConocimiento(LocalDate.of(2019, 1, 1))
                .finPeriodoConocimiento(LocalDate.of(2020, 1, 1))
                .busca(b1)
                .build(),
            Conocimiento.builder()
                .centroEducativo("Centro 3")
                .titulo("Título 3")
                .inicioPeriodoConocimiento(LocalDate.of(2018, 1, 1))
                .finPeriodoConocimiento(LocalDate.of(2019, 1, 1))
                .busca(b2)
                .build()
        );

        b1.setListaConocimientos(listConocimientos.subList(0, 1));
        b2.setListaConocimientos(List.of(listConocimientos.get(2)));

        buscaRepository.saveAll(List.of(b1,b2));
    }

    @Test
    public void ConocimientoRepository_DeleteAllConocimientoFromBuscaId_RemoveAllConocimientoFromBuscaId() {
        buscaRepository.delete(b1);

        Assertions.assertThat(listConocimientos.stream().allMatch(con -> con.getBusca().getId() != b1.getId()));
    }
}

Entities affected by test:

@EqualsAndHashCode(of = "id")
@Data
@ToString(exclude = "busca")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Conocimiento {
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    private Long id;

    @NotNull
    @Size(max = 40, message = "Máximo 40 carácteres")
    private String centroEducativo;

    @NotNull
    @Size(max = 40, message = "Máximo 40 carácteres")
    private String titulo;

    @NotNull
    private LocalDate inicioPeriodoConocimiento;
    
    @NotNull
    private LocalDate finPeriodoConocimiento;

    @ManyToOne
    @JoinColumn(name = "busca_id")
    @JsonBackReference(value = "busca-conocimiento")
    private Busca busca;

    public Conocimiento(@NotNull @Size(max = 40, message = "Máximo 40 carácteres") String centroEducativo,
        @NotNull @Size(max = 40, message = "Máximo 40 carácteres") String titulo, LocalDate fechaInicio, LocalDate fechaFin) {
        this.centroEducativo = centroEducativo;
        this.titulo = titulo;      
        this.inicioPeriodoConocimiento = fechaInicio;
        this.finPeriodoConocimiento = fechaFin;  
    }
    
}
@Data
@ToString(exclude = {"listaOfertas"})
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "id")
@Builder
@Entity
@Table(name = "Busca")
public class Busca extends Usuario {
    
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "busca")
    private List<Experiencia> listaExperiencias;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "busca")
    private List<Conocimiento> listaConocimientos;
 
    @JsonBackReference("busca-oferta") 
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    @JoinTable(name = "busca_oferta", joinColumns = @JoinColumn(name = "busca_id"), inverseJoinColumns = @JoinColumn(name = "oferta_id")) 
    @JsonIgnoreProperties("busca_id") 
    private List<Oferta> listaOfertas;

    public Busca(String nombre, String email, String ciudad, String telefono, String password) {
        super(nombre, email, ciudad, telefono, password, Rol.BUSCA);
    }
}

This is the content of application-test.properties:

spring.h2.console.enabled=true
spring.sql.init.platform=h2
spring.jpa.defer-datasource-initialization=true

spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create-drop

And finally, the stack error from the test:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement [Table "BUSCA" not found (this database is empty); SQL statement:
insert into busca (ciudad,email,nombre,password,rol,telefono) values (?,?,?,?,?,?) [42104-214]] [insert into busca (ciudad,email,nombre,password,rol,telefono) values (?,?,?,?,?,?)]; SQL [insert into busca (ciudad,email,nombre,password,rol,telefono) values (?,?,?,?,?,?)]
 at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:277)
 at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:241)
 at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:550)
 at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
 at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:335)
 at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
 at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:164)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
 at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:220)
 at jdk.proxy2/jdk.proxy2.$Proxy142.saveAll(Unknown Source)
 at com.example.demo.repositories.ConocimientoRepositoryTests.initData(ConocimientoRepositoryTests.java:67)
 at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
 at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

What could it be?

EDIT: Reopened issue because the question used to mark this problem as duplicated has a solution that I ALREADY TRIED. The question that I was redirected states that to fix the issue all I have to do is set this on my application-test.properties:

jdbc:h2:mem:test;DB_CLOSE_DELAY=-1

Which I already did:

spring.h2.console.enabled=true
spring.sql.init.platform=h2
spring.jpa.defer-datasource-initialization=true

spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create-drop
2
  • 1
    Is Usuario marked with @MappedSuperclass or @Entity? Commented Jul 9 at 10:00
  • @MappedSuperclass Commented Jul 9 at 10:21

1 Answer 1

0

I managed to fix my tests by adding a application-test.properties on my project:

spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.h2.console.enabled=true

And setting it up on my test:

@DataJpaTest
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
@ActiveProfiles("test")
public class ExperienciaRepositoryTests {
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.