Java Spring Data Hibernate Search Engine - java

error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'searchController' method
public java.lang.String softuniBlog.controller.SearchController.search(java.lang.String,org.springframework.ui.Model)
to {[/search]}: There is already 'searchController' bean method
public java.lang.String softuniBlog.controller.SearchController.index() mapped.
**I`m trying to build search engine for my blog and have 3 questions.
1) Why In application properties last 3 rows are "can not resolve"
2) How can I fix the error I have, app is working but when try url /search?q=someText it trows exception:
[Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: org.hibernate.engine.spi.SessionDelegatorBaseImpl.(Lorg/hibernate/engine/spi/SessionImplementor;)V] with root cause
java.lang.NoSuchMethodError: org.hibernate.engine.spi.SessionDelegatorBaseImpl.(Lorg/hibernate/engine/spi/SessionImplementor;)V
3) How can take search query from input form instead from url
please check the code:
search input box
<div id="wrap">
<form action="" autocomplete="on">
<input id="search" name="search" type="text" placeholder="What're we looking for ?"></input>
<input id="search_submit" value="Rechercher" type="submit"></input>
</form>
</div>
Article controller
package softuniBlog.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import softuniBlog.bindingModel.ArticleBindingModel;
import softuniBlog.entity.Article;
import softuniBlog.entity.User;
import softuniBlog.repository.ArticleRepository;
import softuniBlog.repository.UserRepository;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
#Controller
public class ArticleConstroller {
#Autowired
private ArticleRepository articleRepository;
#Autowired
private UserRepository userRepository;
#GetMapping("/article/create")
#PreAuthorize("isAuthenticated()")
public String create(Model model){
model.addAttribute("view", "/article/create");
return "base-layout";
}
#PostMapping("/article/create")
#PreAuthorize("isAuthenticated()")
public String createProcess(ArticleBindingModel articleBindingModel){
UserDetails user = (UserDetails) SecurityContextHolder
.getContext()
.getAuthentication()
.getPrincipal();
User userEntity = this.userRepository.findByEmail(user.getUsername());
String databasePathImage = null;
String[] allowedContentTypes = {
"image/png",
"image/jpg",
"image/jpeg"
};
boolean isContentTypeAllowed =
Arrays.asList(allowedContentTypes)
.contains(articleBindingModel.getImage().getContentType());
if(isContentTypeAllowed){
String imagesPath = "\\src\\main\\resources\\static\\img\\";
String imagePathRoot = System.getProperty("user.dir");
String imageSaveDirectory = imagePathRoot + imagesPath;
String fileName = articleBindingModel.getImage().getOriginalFilename();
String savePath = imageSaveDirectory + fileName;
File imageFile = new File(savePath);
try {
articleBindingModel.getImage().transferTo(imageFile);
databasePathImage = "/img/" + fileName;
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
Article articleEntity = new Article(
articleBindingModel.getTitle(),
articleBindingModel.getContent(),
userEntity,
databasePathImage
);
this.articleRepository.saveAndFlush(articleEntity);
return "redirect:/";
}
#GetMapping("/article/edit/{id}")
#PreAuthorize("isAuthenticated()")
public String edit(#PathVariable Integer id, Model model){
if(!this.articleRepository.exists(id)){
return "redirect:/";
}
Article article = this.articleRepository.findOne(id);
if(!this.isUserAuthorOrAdmin(article)){
return "redirect:/";
}
model.addAttribute("view", "article/edit");
model.addAttribute("article", article);
return "base-layout";
}
#GetMapping("/article/{id}")
public String details(Model model, #PathVariable Integer id) {
if(!this.articleRepository.exists(id)){
return "redirect:/";
}
if(!(SecurityContextHolder.getContext().getAuthentication()
instanceof AnonymousAuthenticationToken)){
UserDetails principal = (UserDetails) SecurityContextHolder.getContext()
.getAuthentication().getPrincipal();
User entityUser = this.userRepository.findByEmail(principal.getUsername());
model.addAttribute("user", entityUser);
}
Article article = this.articleRepository.findOne(id);
model.addAttribute("view", "article/details");
model.addAttribute("article", article);
return "base-layout";
}
#PostMapping("/article/edit/{id}")
#PreAuthorize("isAuthenticated()")
public String editProcess(#PathVariable Integer id, ArticleBindingModel articleBindingModel) {
if(!this.articleRepository.exists(id)){
return "redirect:/";
}
Article article = this.articleRepository.findOne(id);
if(!this.isUserAuthorOrAdmin(article)){
return "redirect:/";
}
article.setTitle(articleBindingModel.getTitle());
article.setContent(articleBindingModel.getContent());
this.articleRepository.saveAndFlush(article);
return "redirect:/article/" + article.getId();
}
#GetMapping("/article/delete/{id}")
#PreAuthorize("isAuthenticated()")
public String delete(#PathVariable Integer id, Model model){
if(!this.articleRepository.exists(id)){
return "redirect:/";
}
Article article = this.articleRepository.findOne(id);
if(!this.isUserAuthorOrAdmin(article)){
return "redirect:/";
}
model.addAttribute("article", article);
model.addAttribute("view", "article/delete");
return "base-layout";
}
#PostMapping("/article/delete/{id}")
#PreAuthorize("isAuthenticated()")
public String deleteProcess(#PathVariable Integer id) {
if(!this.articleRepository.exists(id)){
return "redirect:/";
}
Article article = this.articleRepository.findOne(id);
if(!this.isUserAuthorOrAdmin(article)){
return "redirect:/";
}
this.articleRepository.delete(article);
return "redirect:/";
}
private boolean isUserAuthorOrAdmin(Article article){
UserDetails user = (UserDetails) SecurityContextHolder
.getContext()
.getAuthentication()
.getPrincipal();
User userEntity = this.userRepository.findByEmail(user.getUsername());
return userEntity.isAdmin() || userEntity.isAuthor(article);
}
}
Article model
import javax.validation.constraints.NotNull;
import javax.persistence.*;
import java.util.Date;
#Entity
#Indexed
#Table(name = "articles")
public class Article {
private Integer id;
#Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
#NotNull
private String title;
#Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
#NotNull
private String content;
private Date date;
private User author;
private String imagePath;
public Article(String title, String content, User author, String imagePath) {
this.title = title;
this.content = content;
this.author = author;
this.imagePath = imagePath;
this.date = new Date();
}
public Article(){
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "title", nullable = false)
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#Column(name = "content", nullable = false, columnDefinition = "text")
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
#Column(name = "date", nullable = true)
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
#ManyToOne()
#JoinColumn(nullable = false, name = "authorId")
public User getAuthor() {
return author;
}
public void setAuthor(User author) {
this.author = author;
}
#Transient
public String getSummary(){
return this.getContent().substring(0, this.getContent().length()/2) + "...";
}
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
}
Application properties
# Database connection with the given database name
spring.datasource.url = jdbc:mysql://localhost:3306/javablog
# Username and password
spring.datasource.username = root
spring.datasource.password =
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update): with "update" the database
# schema will be automatically updated accordingly to java entities found in
# the project
# Using "create" will delete and recreate the tables every time the project is started
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming.strategy = org.hibernate.cfg.ImprovedNamingStrategy
# Allows Hibernate to generate SQL optimized for a particular DBMS
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.search.default.directory_provider = filesystem
# Using the filesystem DirectoryProvider you also have to specify the default
# base directory for all indexes (make sure that the application have write
# permissions on such directory)
spring.jpa.properties.hibernate.search.default.indexBase = ../java/softuniBlog/lucene/indexes
#Turn off Thymeleaf cache
spring.thymeleaf.cache = false
POM XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>softuni.blog</groupId>
<artifactId>blog</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Blog</name>
<description>Blog Project from the Software Technologies Course</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId>
<version>5.7.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-infinispan</artifactId>
<version>5.7.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-elasticsearch</artifactId>
<version>5.7.0.Final</version>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-directory-provider</artifactId>
<version>8.2.4.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.0.Alpha2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>`enter code here`
</project>

I honestly don't understand you other questions (and you probably should ask them separately), but for question 2 I can tell you that a NoSuchMethodError is very likely to be caused by your using an incompatible version of Hibernate ORM with Hibernate Search.
To sum up:
Hibernate Search 5.7.0 and later should be used with Hibernate ORM 5.2.3 or later.
Hibernate Search 5.6.x and earlier should be used with Hibernate ORM 5.1.x or earlier.
EDIT: Your pom appears to contain a dependency to hibernate-entitymanager, and you didn't set the version for this dependency, so I suspect you're getting some older version. hibernate-entitymanager isn't required to use JPA starting with Hibernate ORM 5.2, so you should try to remove it.

Related

Model contains correct annotation but still passes empty field to the repository - Spring boot, Java

some strange issue has shown up, in the business model I use the list of addresses that cannot be empty or null, but each field in the object address cannot be null or empty either. But when I send a request with one of the fields empty, the request will pass to the repository, which shouldn't happen. Instead of passing a request, the server should return an internal server error.
Address object:
#Data
#NoArgsConstructor
public class Address {
#NotEmpty(message = "Street may not be empty")
#Size(min = 2, max = 256)
private String street;
#NotEmpty(message = "Number may not be empty")
#Size(min = 1, max = 5)
private String number;
#NotEmpty(message = "Postal code may not be empty")
#Field("postal_code")
#JsonProperty("postal_code")
#Size(min = 5, max = 6)
private String postalCode;
#NotEmpty(message = "City may not be empty")
#Size(min = 2, max = 256)
private String city;
#NotEmpty(message = "Province may not be empty")
#Size(min = 2, max = 256)
private String province;
#NotEmpty(message = "Country may not be empty")
#Size(min = 2, max = 256)
private String country;
}
Business object which contains list of addresses:
#Data
#NoArgsConstructor
#Document(collection = "businesses")
public class Business {
#Id
private String id;
#NotBlank
#Size(max = 64)
private String name;
#Field("created_at")
private Date createdAt;
#Field("updated_at")
private Date updatedAt;
private Boolean active;
#DBRef
private User owner;
#Valid
private List<Address> addresses;
public Business(String name, User owner, List<Address> addresses, Date createdAt, Date updatedAt, Boolean active) {
this.name = name;
this.owner = owner;
this.addresses = addresses;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
this.active = active;
}
public Business(String name, User owner, List<Address> addresses, Date updatedAt, Boolean active) {
this.name = name;
this.owner = owner;
this.addresses = addresses;
this.updatedAt = updatedAt;
this.active = active;
}
}
And in the end, service:
#Override
public ResponseEntity<?> createBusiness(CreateBusinessRequest request, String token) throws RuntimeException {
Optional<User> user = userRepository.findByUsername(jwtUtils.getUserNameFromJwtToken(token.substring(7)));
if(businessRepository.existsByName(request.getName())) {
throw new ItemAlreadyExistsException("Business with " + request.getName() + " already exists!");
}
if(user.isEmpty()) {
throw new NotFoundException("User with "+ user.get().getUsername() +" does not exist!");
}
if(request.getAddresses().isEmpty() || request.getAddresses() == null) {
throw new InvalidInputException("Address is empty!");
}
Business business = new Business(
request.getName(),
user.get(),
request.getAddresses(),
new Date(),
new Date(),
true
);
businessRepository.save(business);
return ResponseEntity.ok(business);
}
Controller:
#PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')")
#PostMapping("/create")
public ResponseEntity<?> createBusiness(#Valid #RequestBody CreateBusinessRequest request, #RequestHeader (name="Authorization") String token) {
return businessService.createBusiness(request, token);
}
CreateBusinessRequest request model
#Data
public class CreateBusinessRequest {
#NotNull
private String name;
#Valid
private List<Address> addresses;
}
Request:
{
"name": "Test business",
"addresses": [
{
"street": "",
"number": "100",
"postal_code": "84104",
"city": "Test city",
"province": "Test",
"country": "Slovakia"
}
]
}
Pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ratify</groupId>
<artifactId>backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>backend</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<json.webtoken.version>0.9.1</json.webtoken.version>
<lombok.version>1.18.22</lombok.version>
<jakarta.xml.bind.version>2.3.2</jakarta.xml.bind.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${json.webtoken.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>${jakarta.xml.bind.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I hope that I explained my issue correctly.
Is there any solution to this issue?
Thanks in advance.
My guess is that you are missing one key dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Per this question I recommend adding the #Valid annotation (javax.validation.Valid) to the addresses property of the Business class. Also see the example here
EDIT:
After adding the annotation you can use BindingResult for controller validation. An example would like this:
#PostMapping("/")
public String doSomething(#Valid #RequestBody SomeModel model, BindingResult bindingResult)
{
if (bindingResult.hasErrors())
{
// handle validation error
}
}
To fully configure method level security you need to add the following annotation/class:
#Configuration
#EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
}
This will turn on validation of your service methods. As mentioned earlier, you can add BindingResult to your controller and check for errors in the controller if needed.

Error creating bean with name 'orderController'

I am studying Spring Boot and I want to create a Rest Controller, and using a sql database, but there is a problem when I start the project :
Error:
(the error text is great I will leave the link)
And code:
OrderController.java
package ***;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.Optional;
#RestController
public class OrderController {
#Autowired
private OrderRepository orderRep;
#GetMapping("/")
public List<Order> index(){
return (List<Order>) orderRep.findAll();
}
#GetMapping("/{id}")
public Order show(#PathVariable int id){
Optional<Order> orderId= orderRep.findById(id);
Order order = orderId.get();
return order;
}
#PostMapping("/search")
public List<Order> search(#RequestBody Map<String, String> body){
String searchItem = body.get("item");
return orderRep.findByTitleContainingOrContentContaining(searchItem);
}
#PostMapping("/")
public Order create(#RequestBody Map<String, String> body){
String item = body.get("item");
int price = Integer.parseInt(body.get("price"));
int quantity = Integer.parseInt(body.get("quantity"));
return orderRep.save(new Order(item, price,quantity));
}
#PutMapping("/{id}")
public Order update(#PathVariable String id, #RequestBody Map<String, String> body){
int orderId = Integer.parseInt(id);
// getting blog
Optional<Order> order = orderRep.findById(orderId);
order.get().setItem(body.get("item"));
order.get().setPrice(Integer.parseInt(body.get("price")));
order.get().setQuantity(Integer.parseInt("quantity"));
return orderRep.save(order.get());
}
#DeleteMapping("/{id}")
public boolean delete(#PathVariable int id){
//int orderId = Integer.parseInt(id);
orderRep.deleteById(id);
return true;
}
}
Order.java
package ***;
import javax.persistence.*;
#Entity
#Table(name = "orders")
public class Order {
//Fields
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name = "item")
private String item;
#Column(name = "price")
private int price;
#Column(name = "quantity")
private int quantity;
//Constructors
public Order() { }
public Order(String item, int price, int quantity) {
this.setItem(item);
this.setPrice(price);
this.setQuantity(quantity);
}
public Order(int id, String item, int price, int quantity) {
this.setId(id);
this.setItem(item);
this.setPrice(price);
this.setQuantity(quantity);
}
//Object to string data
#Override
public String toString() {
return "Order{" +
"id=" + getId() +
", item='" + getItem() + '\'' +
", price='" + getPrice() + '\'' +
", price='" + getQuantity() + '\'' +
'}';
}
//Getters & Setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
OrderRepository.java
package ***;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface OrderRepository extends CrudRepository<Order, Integer> {
// custom query to search to blog post by title or content
List<Order> findByTitleContainingOrContentContaining(String item);
}
application.properties
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/testvoy?useUnicode=true&serverTimezone=UTC&useSSL=true&verifyServerCertificate=false
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name =com.mysql.jdbc.Driver
#spring.jpa.show-sql: true
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.test</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>project</name>
<description>project</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.8</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-asciidoctor</artifactId>
<version>${spring-restdocs.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I would be grateful for any help, thanks in advance
If you check the error, you can see that it comes from there:
List<Order> findByTitleContainingOrContentContaining(String item);
and if you read more closely to the error, you will see:
No property title found for type Order!;
inside here:
Caused by: org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.List com.test.project.OrderRepository.findByTitleContainingOrContentContaining(java.lang.String)! Reason: Failed to create query for method public abstract java.util.List com.test.project.OrderRepository.findByTitleContainingOrContentContaining(java.lang.String)! No property title found for type Order!; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.test.project.OrderRepository.findByTitleContainingOrContentContaining(java.lang.String)! No property title found for type Order!
Infact, if you check your model, there is no title property

Spring Boot #Valid Not Giving Error Message or Has Error is Always set to False

CONTROLLER CLASS CODE.
#GetMapping("/admin/home")
public String adhomePage(#ModelAttribute("schoolModel") SchoolModel school, Model model) {
return "admin/home";
}
#PostMapping("/admin/saveschool")
public String saveSchool(#Valid #ModelAttribute("schoolModel") SchoolModel schoolModel, BindingResult result) {
System.out.println(schoolModel.toString()+">>>>>>>>>>>>>>>>>>>>");
System.out.println(result.hasErrors()+"RESULT HASE ERROR");
System.out.println(result.getAllErrors().toString());
if (result.hasErrors()) {
System.out.println("ERROR");
System.out.println(result.getAllErrors().toString());
}
return "admin/home";
}
MODEL CLASS CODE
package com.gatepass.web.model;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import org.springframework.lang.NonNull;
public class SchoolModel {
#NotEmpty(message = "User's name cannot be empty.")
#NotBlank()
#NonNull()
#Size(min=2, max=3)
private Long id;
#NotEmpty(message = "User's name cannot be empty.")
#Size(min=2, max=2)
private String name;
#NotEmpty(message = "User's name cannot be empty.")
#Size(min=2, max=2)
private String email;
#NotEmpty(message = "User's name cannot be empty.")
#Size(min=2, max=30)
private String mobileNumber;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
#Override
public String toString() {
return "SchoolModel [id=" + id + ", name=" + name + ", email=" + email + ", mobileNumber=" + mobileNumber + "]";
}
}
HTML CODE
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<link th:href="#{/css/style.css}" rel="stylesheet" />
<title>Insert title here</title>
</head>
<body>
<h1>HOME PAGE VIEW FOR ADMIN</h1>
<form th:action="#{/logout}" method="post">
<input type="submit" value="logout">
<input
type="hidden"
th:name="${_csrf.parameterName}"
th:value="${_csrf.token}" />
</form>
<br></br>
<form th:action="#{/admin/saveschool}" th:object="${schoolModel}" method="post">
<input type="text" th:field="*{id}">
<input type="text" th:field="*{name}">
<input type="text" th:field="*{email}">
<input type="text" th:field="*{mobileNumber}">
<br></br>
<input type="submit" value="submit"/>
</form>
</body>
</html>
I am inserting a null value but the validation does not working I don't understand what is the issue I tried #validate also but it not working.
I am new to spring boot please help me out with this problem.
I am trying to add validation rules in the spring boot application I have created a form that contains the school object and this school object is mapped with modelAttribute.
so when I am submitting the post request it should validate the rules which I added in SchoolModel class but it's not working school model have the data but it not validate the data and the binding result have a false result in hase error
new updated code after comments..........
XML FILE
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gatepass.web</groupId>
<artifactId>gatepass</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>GatePassSystem</name>
<description>A project where student will register and they will get their gate pass for outside visiting</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Model CLASS
package com.gatepass.web.model;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
#Valid
public class SchoolModel {
private Long id;
#Valid
#NotEmpty(message = "User's name cannot be empty.")
#Size(min=2, max=2)
private String name;
#Valid
#NotEmpty(message = "User's name cannot be empty.")
#Size(min=2, max=2)
private String email;
#Valid
#NotEmpty(message = "User's name cannot be empty.")
#Size(min=2, max=30)
private String mobileNumber;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
#Override
public String toString() {
return "SchoolModel [id=" + id + ", name=" + name + ", email=" + email + ", mobileNumber=" + mobileNumber + "]";
}
}
CONTROLLER CLASS
package com.gatepass.web.controller;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import com.gatepass.web.model.SchoolModel;
import com.gatepass.web.repo.RoleJpa;
#Validated
#Controller
public class WelcomeController {
#Autowired
RoleJpa roleJpa;
#GetMapping("/user/home")
public String ushomePage() {
System.out.println(SecurityContextHolder.getContext().getAuthentication().toString()+"---USER HOME");
//Optional<Role> r = roleJpa.findById(1L);
return "user/home";
}
#GetMapping("/admin/home")
public String adhomePage(#ModelAttribute("schoolModel") SchoolModel school, Model model) {
return "admin/home";
}
#PostMapping("/admin/saveschool")
public String saveSchool(#Valid #ModelAttribute("schoolModel") SchoolModel schoolModel, BindingResult result) {
System.out.println(schoolModel.toString()+">>>>>>>>>>>>>>>>>>>>");
System.out.println(result.hasErrors()+"RESULT HASE ERROR");
System.out.println(result.getAllErrors().toString());
if (result.hasErrors()) {
System.out.println("ERROR");
System.out.println(result.getAllErrors().toString());
}
return "admin/home";
}
#GetMapping("/manager/home")
public String mghomePage() {
System.out.println(SecurityContextHolder.getContext().getAuthentication().toString()+"---MANAGER HOME");
return "manager/home";
}
}
I Just tried with a small demo project and it's working fine for me.
Controller.
import javax.validation.Valid;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.demo.test.dto.DemoDto;
#RestController
#Validated
public class DemoController {
#PostMapping("/demo")
String getValidationResponse(#Valid #RequestBody DemoDto demoDto) {
return "all Valid";
}
}
Model class
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
#Valid
public class DemoDto {
#Valid
#NotNull
private String name;
#Valid
#NotNull
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
POM.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo.test</groupId>
<artifactId>demovalidator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demovalidator</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
postman request-response.
Valid request
#NotEmpty and #NotBlank() can only work on properties of string type.
#Size is same.
so..
#NonNull(message = "User's name cannot be empty.")
#Min(2)
#Max(3)
private Long id;
Spring example:https://spring.io/guides/gs/validating-form-input/

I type this code {"name":"upul","email":"upul#gmail.com"} in postman as a post request ,

but i got this error,
2021-02-05 12:19:08.944 WARN 8168 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'name' is not present]
dependencies are,
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.sample</groupId>
<artifactId>springboot-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
** Repository is,**
package com.example.sample.springboottest.Model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class User {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private Integer id;
private String name;
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
** Controllers are,**
package com.example.sample.springboottest.Controller;
import com.example.sample.springboottest.Model.User;
import com.example.sample.springboottest.Repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
#Controller
#RequestMapping(path = "/demo")
public class MainController {
#Autowired
private UserRepository userRepository;
#PostMapping(path = "/add")
public #ResponseBody String addNewUser(#RequestParam String name, #RequestParam String email){
User n =new User();
n.setName(name);
n.setEmail(email);
userRepository.save(n);
return "Saved";
}
#GetMapping(path = "/all")
public #ResponseBody Iterable<User> getAllUser(){
return userRepository.findAll();
}
}
** Properties are,**
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_example
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.open-in-view=true
spring.jpa.show-sql=true
Please help me to fix this,
Since you are using #ReuestParam you can't pass JSON like what you did.
In order to pass JSON format change #RequestParam to #RequestBody as below:
#PostMapping(path = "/add")
public #ResponseBody String addNewUser(#RequestBody User user){
// User n =new User();
//
// n.setName(name);
// n.setEmail(email);
// userRepository.save(n);
userRepository.save(user);
return "Saved";
}
And postman result would be as below:
But if you need to use #RequestParam then pass query string as below:
localhost:8811/demo/add?name=upul&email=upul#gmail.com
It seems that you have mixed up #RequestParam with #RequestBody
You seem to want to POST a JSON object to your controller, in which case your method signature should be
public #ResponseBody String addNewUser(#RequestBody User user){
Required String parameter 'name' is not present
Method parameters annotated with #RequestParam are required by default. It looks like while you are calling the API, you are not passing the name query param.
Edit: In this case, we could be passing the user in the request body.

Getting null value in one column with "findById" in Java Spring although it exists in DB

I am very new in Java Spring and have a problem where I can not figure out what am I missing.
For the shake of brevity I will make it short:
I have a controller class with two methods for #GetMapping (get info from a patient in database) and #PostMapping (upload a photo from that patient).
In both methods, at some point I am calling through "findById" to database and populating a "Patient" model class object.
All the attributes of this class are retrieved successfully from Database but there is an attribute of this class (getPhoto()) that gets a null value only in the #PostMapping method.
What am I missing? The code is just the same in both methods.
Thanks very much in advance!!
Controller:
#CrossOrigin(origins="http://localhost:4200", maxAge = 3600)
#RestController
#RequestMapping({"/patients"})
public class PatientController {
#Autowired
IPatientService patientService;
#GetMapping("/{id}")
public ResponseEntity<?> listPatientId(#PathVariable("id") Integer id){
Optional<Patient> patient=null;
Map<String, Object> response=new HashMap<>();
try{
patient=patientService.findById(id);
}catch(DataAccessException e){
response.put("error", e.getMessage().concat(": "+e.getMostSpecificCause().toString()));
new ResponseEntity<Map<String, Object>>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
System.out.println("Patient with id: "+id+" / "+patient.get().getId()+" which photo is: "+patient.get().getPhoto());
/*Some other code*/
}
#PostMapping("/upload")
public ResponseEntity<?> upload(#RequestParam("archive")MultipartFile archive, #RequestParam("id") Integer id){
Optional<Paciente> paciente = Optional.empty();
Map<String, Object> respuesta= new HashMap<>();
try{
patient=patientService.findById(id);
}catch(DataAccessException e){
response.put("error", e.getMessage().concat(": "+e.getMostSpecificCause().toString()));
new ResponseEntity<Map<String, Object>>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
System.out.println("Patient with id: "+id+" / "+patient.get().getId()+" which photo is: "+patient.get().getPhoto());
/*Some other code*/
}
}
Patient class:
#Entity
#Table(name = "patients")
public class Patient {
#Id
#Column
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column
private String photo;
(Getters and setters)
}
Repository:
#Repository
public interface PatientRepository extends JpaRepository<Patient, Integer> {
Iterable<Patient> findByNameContainingOrSurnameContaining(String name, String surname);
}
Service (Interface and Implemantation):
public interface IPatientService {
public List<Patient> findAll();
public Optional<Patient> findById(Integer id);
public Iterable<Patient> findByNameContainingOrSurnameContaining(String term);
}
#Service
public class PatientServiceImpl implements IPatientService {
#Autowired
private PatientRepository patientDao;
#Override
#Transactional(readOnly = true)
public List<Patient> findAll() {
return patientDao.findAll();
}
#Override
public Optional<Patient> findById(Integer id) {
return patienteDao.findById(id);
}
public Iterable<Patient> findByNameContainingOrSurnameContaining(String term){
return patientDao.findByNameContainingOrSurnameContaining(term, term);
}
#Override
public Patient save(Patient patient){
return patientDao.save(patient);
}
#Override
public void deleteById(Integer id) {
patientDao.deleteById(id);
}
}
As stated before, "patient.get().getPhoto()" returns in #GetMapping the actual value stored in the database. But in the method annotated with #PostMapping returns null for that value (Although other attributes seem to work just fine).
This was the backend, but in the frontend I am using Angular, where I call this method in component (I am showing just the parts involved in the uploading photo):
patient: Patient;
constructor(private route: ActivatedRoute, private router: Router, private service: ServiceServicee) {
this.paient = new Patient();
}
uploadPhoto() {
this.service.uploadPhoto(this.selectedPhoto,
this.patient.id).subscribe(patient => {
this.patient = patient;
});
}
Service:
constructor(private http:HttpClient, private router:Router) {
this.urlPatients='http://localhost:8080/patients';
}
uploadPhoto(file: File, id):Observable<Patient>{
let formData= new FormData();
formData.append("archive", file);
formData.append("id", id);
return this.http.post(`${this.urlPatients}/upload`, formData).pipe(
map((response:any)=> response.patient as Patient),
catchError(e=>{
console.error(e.error.mensaje);
return throwError(e);
})
);
}
UPDATE:
Using Postman and making a POST to http://localhost:8080/patients/upload and sending in the body a jpg file (form-data - "archive") and a id number("id"), I got a success with the inserts and the method it didn't worked previously in the backend (patient.get().getPhoto()) worked perfectly this time. With the same code, so I assume that it is as #BiteBat said and it is a problem of the Frontend and how it is calling the Backend.
I simulated the same environment that you created and it works for me as you expect, I leave the code for you to review what your problem. I would think you are incorrectly calling the POST method. Now, I would recommend that you do not save the images in a relational database, because there are alternatives with better performance, such as Google Storage / Local storage or any file storage service.
Structure:
EntryPoint:
package question;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#EnableJpaRepositories
public class JulianPelayoApplication {
public static void main(String[] args) {
SpringApplication.run(JulianPelayoApplication.class, args);
}
}
Controller:
package question.controller;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import question.repository.Patient;
import question.repository.PatientsRepository;
#CrossOrigin(origins="http://localhost:4200", maxAge = 3600)
#RestController
#RequestMapping("/patients")
public class PatientController {
private PatientsRepository patientsRepository;
#Autowired
public PatientController(PatientsRepository patientsRepository) {
this.patientsRepository = patientsRepository;
}
#GetMapping("/{id}")
public ResponseEntity<?> listPatientId(#PathVariable("id") Integer id){
Optional<Patient> patient=null;
Map<String, Object> response=new HashMap<>();
try{
patient = patientsRepository.findById(id);
}catch(DataAccessException e){
response.put("error", e.getMessage().concat(": "+e.getMostSpecificCause().toString()));
new ResponseEntity<Map<String, Object>>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
System.out.println("Patient with id: "+id+" / "+patient.get().getId()+" which photo is: "+patient.get().getPhoto());
return ResponseEntity.ok(patient);
}
#PostMapping(value="/upload")
public ResponseEntity<?> upload(#RequestParam("archive") MultipartFile archive, #RequestParam("id") Integer id){
Optional<Patient> patient = Optional.empty();
Map<String, Object> response = new HashMap<>();
try{
patient = patientsRepository.findById(id);
}catch(DataAccessException e){
response.put("error", e.getMessage().concat(": "+e.getMostSpecificCause().toString()));
new ResponseEntity<Map<String, Object>>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
System.out.println("Patient with id: "+id+" / "+patient.get().getId()+" which photo is: "+patient.get().getPhoto());
return ResponseEntity.ok(patient);
}
}
Repository:
package question.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface PatientsRepository extends CrudRepository<Patient, Integer>{
}
Patient:
#Entity
#Table(name = "patients", schema = "business")
#Getter #Setter
public class Patient {
#Id
#Column
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column
private String photo;
}
Spring.properties:
spring.datasource.url=jdbc:postgresql://localhost/test
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
Pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>question</groupId>
<artifactId>JulianPelayo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>JulianPelayo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Response:
Get
Post

Categories

Resources