diff --git a/data/mydb.mv.db b/data/mydb.mv.db
new file mode 100644
index 00000000..98a63848
Binary files /dev/null and b/data/mydb.mv.db differ
diff --git a/data/mydb.trace.db b/data/mydb.trace.db
new file mode 100644
index 00000000..54a2bafe
--- /dev/null
+++ b/data/mydb.trace.db
@@ -0,0 +1,73 @@
+2026-04-21 19:51:51.423293+01:00 jdbc[3]: exception
+org.h2.jdbc.JdbcSQLNonTransientException: The object is already closed [90007-224]
+2026-04-22 05:55:04.822844+01:00 jdbc[3]: exception
+org.h2.jdbc.JdbcSQLNonTransientException: The object is already closed [90007-224]
+2026-04-22 06:09:33.475810+01:00 jdbc[3]: exception
+org.h2.jdbc.JdbcSQLNonTransientException: The object is already closed [90007-224]
+2026-04-22 06:16:11.292904+01:00 jdbc[16]: exception
+org.h2.jdbc.JdbcSQLNonTransientException: The object is already closed [90007-224]
+2026-04-22 12:24:23.617910+01:00 jdbc[3]: exception
+org.h2.jdbc.JdbcSQLNonTransientException: The object is already closed [90007-224]
+2026-04-22 12:24:30.987650+01:00 jdbc[3]: exception
+org.h2.jdbc.JdbcSQLNonTransientException: The object is already closed [90007-224]
+2026-04-22 12:24:33.627303+01:00 jdbc[3]: exception
+org.h2.jdbc.JdbcSQLNonTransientException: The object is already closed [90007-224]
+2026-04-22 16:38:46.730818Z jdbc[3]: exception
+java.sql.SQLClientInfoException: Client info name 'ApplicationName' not supported.
+ at org.h2.jdbc.JdbcConnection.setClientInfo(JdbcConnection.java:1624)
+ at com.intellij.database.remote.jdbc.impl.RemoteConnectionImpl.setClientInfo(RemoteConnectionImpl.java:468)
+ at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
+ at java.base/java.lang.reflect.Method.invoke(Method.java:580)
+ at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
+ at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
+ at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
+ at java.base/java.security.AccessController.doPrivileged(AccessController.java:714)
+ at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:598)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:844)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:721)
+ at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:720)
+ at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
+ at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
+ at java.base/java.lang.Thread.run(Thread.java:1583)
+2026-04-22 16:38:53.145271Z jdbc[3]: exception
+java.sql.SQLClientInfoException: Client info name 'ApplicationName' not supported.
+ at org.h2.jdbc.JdbcConnection.setClientInfo(JdbcConnection.java:1624)
+ at com.intellij.database.remote.jdbc.impl.RemoteConnectionImpl.setClientInfo(RemoteConnectionImpl.java:468)
+ at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
+ at java.base/java.lang.reflect.Method.invoke(Method.java:580)
+ at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
+ at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
+ at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
+ at java.base/java.security.AccessController.doPrivileged(AccessController.java:714)
+ at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:598)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:844)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:721)
+ at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:720)
+ at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
+ at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
+ at java.base/java.lang.Thread.run(Thread.java:1583)
+2026-04-22 16:39:21.684624Z jdbc[3]: exception
+java.sql.SQLClientInfoException: Client info name 'ApplicationName' not supported.
+ at org.h2.jdbc.JdbcConnection.setClientInfo(JdbcConnection.java:1624)
+ at com.intellij.database.remote.jdbc.impl.RemoteConnectionImpl.setClientInfo(RemoteConnectionImpl.java:468)
+ at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
+ at java.base/java.lang.reflect.Method.invoke(Method.java:580)
+ at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
+ at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
+ at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
+ at java.base/java.security.AccessController.doPrivileged(AccessController.java:714)
+ at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:598)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:844)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:721)
+ at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:720)
+ at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
+ at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
+ at java.base/java.lang.Thread.run(Thread.java:1583)
+2026-04-24 05:52:19.361391+01:00 jdbc[3]: exception
+org.h2.jdbc.JdbcSQLNonTransientException: The object is already closed [90007-224]
diff --git a/pom.xml b/pom.xml
index 8b415da1..db8dc06e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.2.0
+ 3.5.0
@@ -53,5 +53,13 @@
lombok
true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
diff --git a/src/main/resources/application-dev.yaml b/src/main/resources/application-dev.yaml
index 819ffce0..4ea6c307 100644
--- a/src/main/resources/application-dev.yaml
+++ b/src/main/resources/application-dev.yaml
@@ -1,6 +1,6 @@
spring:
datasource:
- url: jdbc:h2:file:./data/mydb
+ url: jdbc:h2:file:./data/url-shorten-db;AUTO_SERVER=TRUE;DB_CLOSE_ON_EXIT=FALSE
driver-class-name: org.h2.Driver
username: sa
password:
diff --git a/src/test/java/com/tpximpact/urlshortener/controller/UrlControllerIntegrationTest.java b/src/test/java/com/tpximpact/urlshortener/controller/UrlControllerIntegrationTest.java
new file mode 100644
index 00000000..a2d7cbbc
--- /dev/null
+++ b/src/test/java/com/tpximpact/urlshortener/controller/UrlControllerIntegrationTest.java
@@ -0,0 +1,76 @@
+package com.tpximpact.urlshortener.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.tpximpact.urlshortener.dto.UrlRequest;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class UrlControllerIntegrationTest {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @Test
+ @DisplayName("Full integration flow: Create, Redirect, List, and Delete")
+ void testUrlLifecycle() throws Exception {
+ String longUrl = "https://www.tpximpact.com";
+ String alias = "tpx";
+ UrlRequest request = new UrlRequest(longUrl, alias);
+
+ // 1. POST /shorten - Create a new mapping
+ mockMvc.perform(post("/shorten")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(objectMapper.writeValueAsString(request)))
+ .andExpect(status().isCreated())
+ .andExpect(jsonPath("$.shortUrl").exists());
+
+ // 2. GET /{alias} - Test redirection logic
+ mockMvc.perform(get("/{alias}", alias))
+ .andExpect(status().isFound()) // 302
+ .andExpect(header().string("Location", longUrl))
+ .andExpect(content().string(""));
+
+ // 3. GET /urls - Verify the alias appears in the list
+ mockMvc.perform(get("/urls"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$[?(@.alias == '" + alias + "')]").exists());
+
+ // 4. DELETE /{alias} - Remove the mapping
+ mockMvc.perform(delete("/{alias}", alias))
+ .andExpect(status().isNoContent());
+
+ // 5. GET /{alias} - Verify it no longer exists (assuming service throws 404)
+ mockMvc.perform(get("/{alias}", alias))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @DisplayName("POST /shorten - Should return 400 when fullUrl is blank")
+ void shouldReturn400ForInvalidInput() throws Exception {
+ UrlRequest invalidRequest = new UrlRequest("", "short");
+
+ mockMvc.perform(post("/shorten")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(objectMapper.writeValueAsString(invalidRequest)))
+ .andExpect(status().isBadRequest());
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/tpximpact/urlshortener/controller/UrlControllerTest.java b/src/test/java/com/tpximpact/urlshortener/controller/UrlControllerTest.java
new file mode 100644
index 00000000..41a2cffb
--- /dev/null
+++ b/src/test/java/com/tpximpact/urlshortener/controller/UrlControllerTest.java
@@ -0,0 +1,125 @@
+package com.tpximpact.urlshortener.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.tpximpact.urlshortener.dto.UrlListResponse;
+import com.tpximpact.urlshortener.dto.UrlRequest;
+import com.tpximpact.urlshortener.dto.UrlResponse;
+import com.tpximpact.urlshortener.exception.NotFoundException;
+import com.tpximpact.urlshortener.service.UrlService;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.test.context.bean.override.mockito.MockitoBean; // SB 4.0 standard
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+
+import java.util.List;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+@WebMvcTest(UrlController.class)
+class UrlControllerTest {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @MockitoBean
+ private UrlService urlService;
+
+ @Test
+ @DisplayName("POST /shorten - Success")
+ void shortenUrl_Returns201() throws Exception {
+ // Given
+ UrlRequest request = new UrlRequest("https://example.com", "my-alias");
+ UrlResponse response = new UrlResponse("http://localhost:8080/my-alias");
+
+ when(urlService.shorten(any(UrlRequest.class))).thenReturn(response);
+
+ // When & Then
+ mockMvc.perform(post("/shorten")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(objectMapper.writeValueAsString(request)))
+ .andExpect(status().isCreated())
+ .andExpect(jsonPath("$.shortUrl").value("http://localhost:8080/my-alias"));
+
+ verify(urlService, times(1)).shorten(any(UrlRequest.class));
+ }
+
+ @Test
+ @DisplayName("GET /{alias} - Redirects to full URL")
+ void redirect_Returns302() throws Exception {
+ // Given
+ String alias = "tpx";
+ String fullUrl = "https://tpximpact.com";
+ when(urlService.getFullUrl(alias)).thenReturn(fullUrl);
+
+ // When & Then
+ mockMvc.perform(get("/{alias}", alias))
+ .andExpect(status().isFound())
+ .andExpect(header().string("Location", fullUrl))
+ .andExpect(content().string("")); // Asserting empty body as requested
+
+ verify(urlService).getFullUrl(alias);
+ }
+
+ @Test
+ @DisplayName("GET /{alias} - Redirects returns 404 if alias not exist")
+ void redirect_Returns404_If_Alias_Not_Exist() throws Exception {
+ // Given
+ String aliasNotExist = "notExist";
+ when(urlService.getFullUrl(aliasNotExist)).thenThrow(NotFoundException.class);
+
+ // When & Then
+ mockMvc.perform(get("/{alias}", aliasNotExist))
+ .andExpect(status().isNotFound());
+
+ verify(urlService).getFullUrl(aliasNotExist);
+ }
+
+ @Test
+ @DisplayName("GET /urls - Returns list of mappings")
+ void getAll_Returns200() throws Exception {
+ // Given
+ List mockList = List.of(
+ new UrlListResponse("alias1", "https://site1.com", "http://short/1"),
+ new UrlListResponse("alias2", "https://site2.com", "http://short/2")
+ );
+ when(urlService.getAll()).thenReturn(mockList);
+
+ // When & Then
+ mockMvc.perform(get("/urls"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.length()").value(2))
+ .andExpect(jsonPath("$[0].alias").value("alias1"));
+ }
+
+ @Test
+ @DisplayName("DELETE /{alias} - Success")
+ void delete_Returns204() throws Exception {
+ // When & Then
+ mockMvc.perform(delete("/{alias}", "old-alias"))
+ .andExpect(status().isNoContent());
+
+ verify(urlService).delete("old-alias");
+ }
+
+ @Test
+ @DisplayName("POST /shorten - Fails on invalid input")
+ void shortenUrl_BlankUrl_Returns400() throws Exception {
+ UrlRequest invalidRequest = new UrlRequest("", "alias");
+
+ mockMvc.perform(post("/shorten")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(objectMapper.writeValueAsString(invalidRequest)))
+ .andExpect(status().isBadRequest());
+
+ verifyNoInteractions(urlService);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/tpximpact/urlshortener/controller/UrlControllerWIT.java b/src/test/java/com/tpximpact/urlshortener/controller/UrlControllerWIT.java
new file mode 100644
index 00000000..f2973462
--- /dev/null
+++ b/src/test/java/com/tpximpact/urlshortener/controller/UrlControllerWIT.java
@@ -0,0 +1,90 @@
+package com.tpximpact.urlshortener.controller;
+
+import com.tpximpact.urlshortener.dto.UrlListResponse;
+import com.tpximpact.urlshortener.dto.UrlRequest;
+import com.tpximpact.urlshortener.dto.UrlResponse;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.ActiveProfiles;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@ActiveProfiles("test")
+class UrlControllerWIT {
+ @Autowired
+ private TestRestTemplate restTemplate;
+
+
+ @Test
+ @DisplayName("POST /shorten - Should create short URL")
+ void shouldCreateShortUrl() {
+ // Given
+ UrlRequest request = new UrlRequest("https://tpximpact.com", "tpx");
+
+ // When
+ ResponseEntity response = restTemplate.postForEntity(
+ "/shorten",
+ request,
+ UrlResponse.class
+ );
+
+ // Then
+ assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED);
+ assertThat(response.getBody()).isNotNull();
+ assertThat(response.getBody().shortUrl()).contains("/tpx");
+ }
+
+ @Test
+ @DisplayName("GET /{alias} - Should return 302 Redirect")
+ void shouldRedirect() {
+ // First, ensure the URL exists (Seed the data)
+ restTemplate.postForEntity("/shorten", new UrlRequest("https://google.com", "goog"), UrlResponse.class);
+
+ // When - We use getForEntity
+ ResponseEntity response = restTemplate.getForEntity("/{alias}", Void.class, "goog");
+
+ // Then
+ assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
+ }
+
+ @Test
+ @DisplayName("GET /urls - Should return list using TestRestTemplate")
+ void getAllRestTemplate() {
+ ResponseEntity response = restTemplate.getForEntity(
+ "/urls",
+ UrlListResponse[].class
+ );
+
+ assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
+ assertThat(response.getBody()).isNotNull();
+
+ // Convert array to list for easier assertions
+ List urls = Arrays.asList(response.getBody());
+ assertThat(urls).isNotEmpty();
+ assertThat(urls.get(0).alias()).isEqualTo("goog");
+
+
+ }
+
+ @Test
+ @DisplayName("DELETE /{alias} - Should remove entry")
+ void shouldDelete() {
+ // When
+ restTemplate.delete("/{alias}", "tpx");
+
+ // Then - Verify 404 after deletion
+ ResponseEntity response = restTemplate.getForEntity("/{alias}", Void.class, "tpx");
+ assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
+ }
+
+}
diff --git a/src/test/java/com/tpximpact/urlshortener/service/UrlServiceImplTest.java b/src/test/java/com/tpximpact/urlshortener/service/UrlServiceImplTest.java
new file mode 100644
index 00000000..555efae4
--- /dev/null
+++ b/src/test/java/com/tpximpact/urlshortener/service/UrlServiceImplTest.java
@@ -0,0 +1,92 @@
+package com.tpximpact.urlshortener.service;
+
+import com.tpximpact.urlshortener.dto.UrlRequest;
+import com.tpximpact.urlshortener.entity.Url;
+import com.tpximpact.urlshortener.exception.BadRequestException;
+import com.tpximpact.urlshortener.exception.NotFoundException;
+import com.tpximpact.urlshortener.repository.UrlRepository;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+
+import java.util.Optional;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(org.mockito.junit.jupiter.MockitoExtension.class)
+class UrlServiceImplTest {
+
+ @Mock
+ private UrlRepository repository;
+
+ @InjectMocks
+ private UrlServiceImpl service;
+
+ private UrlRequest request;
+ private Url url;
+
+ @BeforeEach
+ public void setUp() {
+ request = new UrlRequest("https://google.com", "alias1");
+
+ url = Url.builder()
+ .alias("alias1")
+ .fullUrl("https://google.com")
+ .build();
+ }
+
+ @Test
+ void shouldCreateShortUrl_withCustomAlias() {
+
+ when(repository.existsByAlias("alias1")).thenReturn(false);
+
+ var response = service.shorten(request);
+
+ assertThat(response.shortUrl()).contains("alias1");
+ verify(repository).existsByAlias("alias1");
+ }
+
+ @Test
+ void shouldThrowException_whenAliasAlreadyExists() {
+
+ when(repository.existsByAlias("alias1")).thenReturn(true);
+
+ assertThatThrownBy(() -> service.shorten(request))
+ .isInstanceOf(BadRequestException.class)
+ .hasMessageContaining("Invalid input or alias already taken");
+ }
+
+ @Test
+ void shouldReturnFullUrl_whenAliasExists() {
+
+ when(repository.findByAlias("alias1")).thenReturn(Optional.of(url));
+
+ var result = service.getFullUrl("alias1");
+
+ assertThat(result).isEqualTo("https://google.com");
+ }
+
+ @Test
+ void shouldThrowNotFound_whenAliasMissing() {
+ when(repository.findByAlias("abc")).thenReturn(Optional.empty());
+
+ assertThatThrownBy(() -> service.getFullUrl("abc"))
+ .isInstanceOf(NotFoundException.class);
+ }
+
+ @Test
+ void shouldDelete_whenAliasExists() {
+ Url url = Url.builder().alias("abc").build();
+
+ when(repository.findByAlias("abc")).thenReturn(Optional.of(url));
+
+ service.delete("abc");
+
+ verify(repository).delete(url);
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/application-test.yaml b/src/test/resources/application-test.yaml
new file mode 100644
index 00000000..5421926e
--- /dev/null
+++ b/src/test/resources/application-test.yaml
@@ -0,0 +1,10 @@
+spring:
+ datasource:
+ url: jdbc:h2:mem:testdb
+ driverClassName: org.h2.Driver
+ jpa:
+ hibernate:
+ ddl-auto: create-drop
+ h2:
+ console:
+ enabled: true
\ No newline at end of file