Fix Spring Data Querydsl example.

The io.github.jpenren:thymeleaf-spring-data-dialect dependency was out of sync with thymeleaf causing an error when you tried to access the index page.

Additionally Added a TestApplication and revamped the TestContainers usage.
This commit is contained in:
Tim Sparg
2024-07-26 14:46:13 +02:00
committed by Oliver Drotbohm
parent 4caa29cc7e
commit 374307235c
6 changed files with 99 additions and 35 deletions

View File

@@ -4,9 +4,8 @@ This example shows some of the Spring Data Querydsl integration features with Sp
## Quickstart ## Quickstart
1. Install MongoDB (http://www.mongodb.org/downloads, unzip, run `mkdir data`, run `bin/mongod --dbpath=data`) 1. Build and run the app (`mvn spring-boot:test-run`)
2. Build and run the app (`mvn spring-boot:run`) 2. Access app directly via its UI (`http://localhost:8080/`).
4. Access app directly via its UI (`http://localhost:8080/`).
## Interesting bits ## Interesting bits

View File

@@ -58,20 +58,20 @@
<dependency> <dependency>
<groupId>io.github.jpenren</groupId> <groupId>io.github.jpenren</groupId>
<artifactId>thymeleaf-spring-data-dialect</artifactId> <artifactId>thymeleaf-spring-data-dialect</artifactId>
<version>3.3.0</version> <version>3.6.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.webjars</groupId> <groupId>org.webjars</groupId>
<artifactId>jquery</artifactId> <artifactId>jquery</artifactId>
<version>2.1.3</version> <version>3.7.1</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.webjars</groupId> <groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId> <artifactId>bootstrap</artifactId>
<version>3.3.4</version> <version>5.3.3</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
@@ -94,6 +94,18 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@@ -23,23 +23,27 @@
<div class="form-group col-sm-6"> <div class="form-group col-sm-6">
<label for="firstname" class="control-label">Firstname:</label> <label for="firstname" class="control-label">Firstname:</label>
<input id="firstname" name="firstname" th:value="${#httpServletRequest.getParameter('firstname')}" type="text" class="form-control" autofocus="autofocus" /> <input id="firstname" name="firstname" th:value="${param.firstname}" type="text" class="form-control" autofocus="autofocus" />
</div> </div>
<div class="form-group col-sm-6"> <div class="form-group col-sm-6">
<label for="lastname" class="control-label">Lastname:</label> <label for="lastname" class="control-label">Lastname:</label>
<input id="lastname" name="lastname" th:value="${#httpServletRequest.getParameter('lastname')}" type="text" class="form-control" autofocus="autofocus" /> <input id="lastname" name="lastname" th:value="${param.lastname}" type="text" class="form-control" autofocus="autofocus" />
</div> </div>
<div class="form-group col-sm-6"> <div class="form-group col-sm-6">
<label for="address.city" class="control-label">City:</label> <label for="address.city" class="control-label">City:</label>
<input id="address.city" name="address.city" th:value="${#httpServletRequest.getParameter('address.city')}" type="text" class="form-control" /> <input id="address.city" name="address.city" th:value="${param['address.city']}" type="text"
class="form-control" />
</div> </div>
<div class="form-group col-sm-6"> <div class="form-group col-sm-6">
<label for="address.street" class="control-label">Street:</label> <label for="address.street" class="control-label">Street:</label>
<input id="address.street" name="address.street" th:value="${#httpServletRequest.getParameter('address.street')}" type="text" class="form-control" /> <input id="address.street" name="address.street" th:value="${param['address.street']}"
type="text"
class="form-control" />
</div> </div>
<div class="form-group col-sm-6"> <div class="form-group col-sm-6">
<label for="nationality" class="control-label">Nationality:</label> <label for="nationality" class="control-label">Nationality:</label>
<input id="nationality" name="nationality" th:value="${#httpServletRequest.getParameter('nationality')}" type="text" class="form-control" /> <input id="nationality" name="nationality" th:value="${param.nationality}" type="text"
class="form-control" />
</div> </div>
<div class="form-group col-sm-12"> <div class="form-group col-sm-12">
<button id="submit" type="submit" class="btn btn-default">Submit</button> <button id="submit" type="submit" class="btn btn-default">Submit</button>
@@ -75,7 +79,7 @@
<tr th:each="user : ${users}"> <tr th:each="user : ${users}">
<td th:text="${users.number * users.size + userStat.index + 1} + '.'">1.</td> <td th:text="${users.number * users.size + userStat.index + 1} + '.'">1.</td>
<td class="text-center"> <td class="text-center">
<img th:src="${user.picture.small}" class="img-circle" /> <img th:src="${user.picture.small}" class="rounded-circle" />
</td> </td>
<td th:text="${user.firstname}">Firstname</td> <td th:text="${user.firstname}">Firstname</td>
<td th:text="${user.lastname}">Lastname</td> <td th:text="${user.lastname}">Lastname</td>

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2017-2021 the original author or authors. * Copyright 2017-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -15,44 +15,26 @@
*/ */
package example.users; package example.users;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.MongoDBContainer; import org.testcontainers.containers.MongoDBContainer;
import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
/** /**
* @author Oliver Gierke * @author Oliver Gierke
* @author Divya Srivastava * @author Divya Srivastava
* @author Tim Sparg
*/ */
@Testcontainers @Testcontainers
@SpringBootTest @SpringBootTest
class ApplicationTests { class ApplicationTests {
@Container // @Container
private static MongoDBContainer mongoDBContainer = MongoContainers.getDefaultContainer(); @ServiceConnection static MongoDBContainer mongoDBContainer = new MongoDBContainer("mongo:7");
@DynamicPropertySource
static void setProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl);
}
@Test @Test
void contextBootstraps() {} void contextBootstraps() {}
static class MongoContainers {
private static final String IMAGE_NAME = "mongo:5.0";
private static final String IMAGE_NAME_PROPERTY = "mongo.default.image.name";
public static MongoDBContainer getDefaultContainer() {
return new MongoDBContainer(DockerImageName.parse(System.getProperty(IMAGE_NAME_PROPERTY, IMAGE_NAME)))
.withReuse(true);
}
}
} }

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.users;
import org.springframework.boot.SpringApplication;
/**
* @author Tim Sparg
*/
public class TestApplication {
public static void main(String[] args) {
SpringApplication.from(Application::main).with(TestcontainersConfiguration.class).run(args);
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.users;
import org.springframework.boot.devtools.restart.RestartScope;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.testcontainers.containers.MongoDBContainer;
import org.testcontainers.utility.DockerImageName;
/**
* @author Tim Sparg
*/
@TestConfiguration(proxyBeanMethods = false)
public class TestcontainersConfiguration {
@Bean
@ServiceConnection
@RestartScope
MongoDBContainer mongoDbContainer() {
return new MongoDBContainer(DockerImageName.parse("mongo:7"));
}
}