Spring boot (data jpa ) i am not able to save eumn value in database - spring

package com.kk.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#ComponentScan(basePackages="com.kk")
#EnableJpaRepositories(basePackages="com.kk.respositry")
#EntityScan(basePackages="com.kk.entity")
#SpringBootApplication
public class SpringBootEnumExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootEnumExampleApplication.class, args);
}
}
package com.kk.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.kk.entity.Account;
import com.kk.service.AccountService;
#Controller
public class AccountController {
#Autowired
private AccountService accountService;
#RequestMapping(value="create",method=RequestMethod.POST)
private #ResponseBody String createAccout(#RequestBody Account account) {
Long l=accountService.save(account);
return "{\"accountId\":l}";
}
}
package com.kk.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import com.kk.enums.AccountRole;
#Entity
#Table(name = "account_tab")
public class Account {
#Id
#GeneratedValue
private Long id;
private String accountHolderName;
private String mobile;
private Integer age;
#Enumerated(EnumType.STRING)
#Column(name = "account_role", length = 40)
private AccountRole accountRole;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAccountHolderName() {
return accountHolderName;
}
public void setAccountHolderName(String accountHolderName) {
this.accountHolderName = accountHolderName;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public AccountRole getAccountRole() {
return accountRole;
}
public void setAccountRole(AccountRole accountRole) {
this.accountRole = accountRole;
}
}
package com.kk.enums;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.kk.enums.utils.AccountRoleDeserializer;
#JsonDeserialize(using = AccountRoleDeserializer.class)
public enum AccountRole {
EMPLOYEE_CUSTOMER("Employee customer"),
JOINTER_ACSCOUNT("Jointer customer"),
PRIMARY_ACCOUNT("Primary customer"),
TENANT_ACCOUNT("Tenant customer");
private final String text;
AccountRole(final String text) {
this.text = text;
}
#Override
public String toString() {
return text;
}
public String getText() {
return this.text;
}
public static AccountRole fromText(String text) {
for (AccountRole r : AccountRole.values()) {
if (r.getText().equals(text)) {
return r;
}
}
throw new RuntimeException("Your AccountRole not valied: "+text );
}
}
package com.kk.enums.utils;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.kk.enums.AccountRole;
public class AccountRoleDeserializer extends JsonDeserializer<AccountRole> {
#Override
public AccountRole deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
ObjectCodec oc = jsonParser.getCodec();
JsonNode node = oc.readTree(jsonParser);
if (node == null) {
return null;
}
String text = node.textValue(); // gives "A" from the request
if (text == null) {
return null;
}
return AccountRole.fromText(text);
}
}
package com.kk.respositry;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.kk.entity.Account;
#Repository
public interface AccountRespositry extends JpaRepository<Account, Long> {
}
package com.kk.service;
import com.kk.entity.Account;
public interface AccountService {
Long save(Account account);
}
package com.kk.service;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.kk.entity.Account;
import com.kk.respositry.AccountRespositry;
#Service
#Transactional
public class AccountServiceImpl implements AccountService{
#Autowired
private AccountRespositry accountRespositry;
#Override
public Long save(Account account) {
account=accountRespositry.save(account);
return account.getId();
}
}
server.port=8088
server.servlet.context-path=/SpringBootEnum/
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url = jdbc:mysql://localhost:3306/Account?useSSL=false
spring.datasource.username = root
spring.datasource.password = root
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
#Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
I am using spring boot (data jpa ) but am getting the wrong value in the database.

The #Enumerated is behaving as expected. It's going to return the name of the enum and that's what gets persisted. Remember JPA uses the name() of the enum and not the toString() even if you have overridden the toString(). I would recommend using an AttributeConverter (JPA 2.1+) to control the persistence of your enum. In your case, create the converter to use the getText() method you already have defined in your Enum.
#Converter(autoApply = true)
public class AccountRoleConverter implements AttributeConverter<AccountRole, String> {
#Override
public String convertToDatabaseColumn(AccountRole role) {
return role.getText();
}
#Override
public AccountRole convertToEntityAttribute(String dbData) {
return AccountRole.fromText(dbData);
}
}
Note: #Converter(autoApply = true), tells JPA provider to use it to map all AccountRole enums.
Now you just need to make sure you remove the #Enumerated from your Account Entity:
#Enumerated(EnumType.STRING)
#Column(name = "account_role", length = 40)
private AccountRole accountRole;
becomes
#Column(name = "account_role", length = 40)
private AccountRole accountRole;
Ok you may ask how you use the converter. Well that is the nice part, you don't have to do anything. The persistence provider will use it for all read and write operations. I hope this helps.

Related

Custom Exception not thrown in controller-method when no data is found in database

My controller always give Internal server error whenever my condition fail, and are suppose to throw custom exception ResourceNotFoundException.
When I call account/1-endpoint (no account with id 1 in database) I expect an ResourceNotFoundException, but instead I get Internal server Error.. I do not understand why ResourceNotFoundException is not thrown, I watched several youtube tutorials on the topic.
Please help by providing possible solutions.
My model classes are
package com.bank2.Model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.annotations.Proxy;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#Entity
#javax.persistence.Table(name="Account")
#Proxy(lazy = false)
#JsonIgnoreProperties(ignoreUnknown = true)
public class Account {
#Id
int accountNumber;
#Column(name="balance")
Double balance;
#Column(name="accountType")
String accountType;
public Account() {
super();
}
#Override
public String toString() {
return "Account [accountNumber=" + accountNumber + ", balance=" + balance + ", accountType=" + accountType + "]";
}
public int getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(int accountNumber) {
this.accountNumber = accountNumber;
}
public Double getBalance() {
return balance;
}
public void setBalance(Double balance) {
this.balance = balance;
}
public String getAccountType() {
return accountType;
}
public void setAccountType(String accountType) {
this.accountType = accountType;
}
public Account(int accountNumber, Double balance, String accountType) {
super();
this.accountNumber = accountNumber;
this.balance = balance;
this.accountType = accountType;
}
}
package com.bank2.Model;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Proxy;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#Entity
#Table(name="Customer")
#Proxy(lazy = false)
#JsonIgnoreProperties(ignoreUnknown = true)
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Integer customerId;
#Column(name="customerName")
String customerName;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL,targetEntity = Account.class)
#JoinColumn(name = "ca_fk",referencedColumnName ="customerId")
private List<Account> accounts;
public Customer() {
super();
}
public Customer(Integer customerId, String customerName, List<Account> accounts) {
super();
this.customerId = customerId;
this.customerName = customerName;
this.accounts = accounts;
}
public Integer getCustomerId() {
return customerId;
}
public void setCustomerId(Integer customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public List<Account> getAccount() {
return accounts;
}
public void setAccount(List<Account> accounts) {
this.accounts = accounts;
}
#Override
public String toString() {
return "Customer [customerId=" + customerId + ", customerName=" + customerName + ", accounts=" + accounts + "]";
}
}
My service classes are
package com.bank2.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bank2.Model.Customer;
import com.bank2.repository.CustomerRepository;
#Service
public class CustomerService {
#Autowired
CustomerRepository customerRepository;
public Customer customerCreate(Customer customer) {
Customer x= customerRepository.save(customer);
return x;
}
}
package com.bank2.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bank2.Model.Account;
import com.bank2.repository.AccountRepository;
#Service
public class AccountService {
#Autowired
AccountRepository accountRepository;
public Account findAccountById(int accountNumber) {
return accountRepository.getById(accountNumber);
}
}
my controller class are
package com.bank2.controller;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.bank2.Exception.ResourceNotFoundException;
import com.bank2.Model.Account;
import com.bank2.ServiceImpl.AccountService;
#RestController
#RequestMapping("/account")
public class AccountController {
#Autowired
AccountService accountService;
#GetMapping("/{accountNumber}")
public ResponseEntity<?> getAccountById(#PathVariable("accountNumber") int accountNumber){
Account acc=accountService.findAccountById(accountNumber);
if(acc==null) {
throw new ResourceNotFoundException("Account [accountNumber="+accountNumber+"] can't be found");
}else {
return new ResponseEntity<>(acc,HttpStatus.FOUND);
}
}
package com.bank2.controller;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.bank2.Exception.ResourceNotFoundException;
import com.bank2.Model.Customer;
import com.bank2.ServiceImpl.CustomerService;
#RestController
#RequestMapping("/customer")
public class CustomerController {
#Autowired
CustomerService customerService;
#PostMapping("/createCust")
public ResponseEntity<?> CreateCustomer(#RequestBody Customer customer){
Customer cus=customerService.customerCreate(customer);
Optional<Customer> cus1 = Optional.ofNullable(cus);
if(cus1.isEmpty()) {
throw new ResourceNotFoundException("customer not created!!");
}else {
return new ResponseEntity<>(cus,HttpStatus.CREATED);
}
}
}
my expection classes are
package com.bank2.Exception;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.http.HttpStatus;
public class ApiErrors {
String message;
List<String> details;
HttpStatus status;
LocalDateTime timestamp;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<String> getDetails() {
return details;
}
public void setDetails(List<String> details) {
this.details = details;
}
public HttpStatus getStatus() {
return status;
}
public void setStatus(HttpStatus status) {
this.status = status;
}
public LocalDateTime getTimestamp() {
return timestamp;
}
public void setTimestamp(LocalDateTime timestamp) {
this.timestamp = timestamp;
}
public ApiErrors() {
super();
// TODO Auto-generated constructor stub
}
public ApiErrors(String message, List<String> details, HttpStatus status, LocalDateTime timestamp) {
super();
this.message = message;
this.details = details;
this.status = status;
this.timestamp = timestamp;
}
#Override
public String toString() {
return "ApiErrors [message=" + message + ", details=" + details + ", status=" + status + ", timestamp="
+ timestamp + "]";
}
}
package com.bank2.Exception;
public class ResourceNotFoundException extends RuntimeException{
/**
*
*/
private static final long serialVersionUID = 1L;
public ResourceNotFoundException() {
super();
}
public ResourceNotFoundException(String message) {
super(message);
}
}
package com.bank2.Exception;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
#ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
#ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<Object> handleResourceNotFoundException(ResourceNotFoundException ex){
String msg=ex.getMessage();
List<String> details=new ArrayList<>();
details.add("Resource not found");
ApiErrors errors=new ApiErrors(msg,details,HttpStatus.BAD_REQUEST,LocalDateTime.now());
return new ResponseEntity<Object>(errors,HttpStatus.BAD_REQUEST);
}
#ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleOther(Exception ex){
String msg=ex.getMessage();
List<String> details=new ArrayList<>();
details.add("Other Exceptions");
ApiErrors errors=new ApiErrors(msg,details,HttpStatus.INTERNAL_SERVER_ERROR,LocalDateTime.now());
return new ResponseEntity<Object>(errors,HttpStatus.INTERNAL_SERVER_ERROR);
}
}
This is the Internal server error I have gotten so far in Postman:
{
"message": "Unable to find com.bank2.Model.Account with id 1; nested exception is javax.persistence.EntityNotFoundException: Unable to find com.bank2.Model.Account with id 1",
"details": [
"Other Exceptions"
],
"status": "INTERNAL_SERVER_ERROR",
"timestamp": "2022-04-02T22:09:28.0486246"
}
My repositories are
'''
package com.bank2.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.bank2.Model.Account;
#Repository
public interface AccountRepository extends JpaRepository<Account, Integer> {
}
'''
'''
package com.bank2.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.bank2.Model.Customer;
#Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
}
'''
From the Documentation JpaRepository.html#getById-ID-
T getById(ID id)
Returns a reference to the entity with the
given identifier. Depending on how the JPA persistence provider is
implemented this is very likely to always return an instance and throw
an EntityNotFoundException on first access. Some of them will reject
invalid identifiers immediately.
The error message you get shows ...nested exception is EntityNotFoundException, so that could be normal...
So you could throw a ResourceNotFoundException in your service when the Account is not found.
#Service
public class AccountService {
public Account findAccountById(int accountNumber) {
try {
return accountRepository.getById(accountNumber);
} catch(EntityNotFoundException e) {
throw new ResourceNotFoundException("Account [accountNumber="+accountNumber+"] can't be found")
}
}

Spring boot application failed to start with exception org.springframework.beans.factory.NoSuchBeanDefinitionException:

I am using spring boot v2.5.2. Below is my folder structure and code. This is simple test project.
My folder structure:
RESTController Class:
package com.user.UserManagementSystem.controller;
import com.user.UserManagementSystem.model.User;
import com.user.UserManagementSystem.service.UserServiceImpl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/api/v1/")
public class UserController {
#Autowired
private UserServiceImpl userRepository;
#GetMapping("/getAllUsers")
public List<User> getAllUsers() {
return userRepository.getUsers();
}
#GetMapping("/")
public String home() {
return "Hello";
}
}
User.java
package com.user.UserManagementSystem.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name= "Users")
public class User {
public User() {
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name ="userName")
private String userName;
#Column(name ="name")
private String name;
#Column(name ="language")
private String language;
#Column(name ="mobileNumber")
private int mobileNumber;
public User(String userName, String name, String language, int mobileNumber) {
this.userName = userName;
this.name = name;
this.language = language;
this.mobileNumber = mobileNumber;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public int getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(int mobileNumber) {
this.mobileNumber = mobileNumber;
}
}
UserRepository.java
package com.user.UserManagementSystem.repository;
import com.user.UserManagementSystem.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface UserRepository extends JpaRepository<User, Long>{
}
UserService.java
package com.user.UserManagementSystem.service;
import com.user.UserManagementSystem.model.User;
import java.util.List;
public interface UserService {
List<User> getUsers();
User getUserById(Long id);
User addUser(User user);
void deleteUser(Long id);
}
UserServiceImpl.java
package com.user.UserManagementSystem.service;
import com.user.UserManagementSystem.repository.UserRepository;
import com.user.UserManagementSystem.model.User;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class UserServiceImpl implements UserService{
#Autowired
UserRepository userRepository;
#Override
public List<User> getUsers() {
return userRepository.findAll();
}
#Override
public User getUserById(Long id) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public User addUser(User user) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void deleteUser(Long id) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
UserManangmentSystemApplication.java
package com.user.UserManangmentSystem;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication(scanBasePackages = {"com.user.UserManangmentSystem", "com.user.UserManagementSystem.controller", "com.user.UserManagementSystem.repository", "com.user.UserManagementSystem.service"})
//#SpringBootApplication
public class UserManangmentSystemApplication {
public static void main(String[] args) {
SpringApplication.run(UserManangmentSystemApplication.class, args);
}
}
application.properties:
spring.datasource.url=jdbc:mariadb://localhost:3306/ums
spring.datasource.username=ums
spring.datasource.password=ums
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDB53Dialect
server.port=8888
debug=true
When it build the project i am getting :
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.user.UserManagementSystem.repository.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1790) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657) ~[spring-beans-5.3.8.jar:5.3.8]
Thanks in Advance.
Typo in your base package name which makes packages different.
Change
com.user.UserManangmentSystem
To
com.user.UserManangementSystem
Correct management spelling.
You have correct package structure it will collect all bean within base package and sub package also. No need explicitly mention package scan. If you have any spell mistakes then that error will occur.

Spring Boot MongoDB get only certain fields from database into model

I am trying to understand how to work with MongoDB and Spring Boot. I have a mongodb with sample data and I want it to return only selected fields and not the entire data.
My mongoDB collection contains data in the format
DAO.java
package com.books.Reading.DAO;
import com.books.Reading.model.booksModel;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
public interface readingListDAO extends MongoRepository<booksModel, String> {
#Query("{'title' : 'Griffon in Action'}")
public booksModel findFirstByOrderByTitleAsc();
}
model.java
package com.books.Reading.model;
import org.springframework.data.mongodb.core.mapping.Document;
#Document
public class booksModel {
String title;
String isbn;
int pageCount;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
}
controller.java
package com.books.Reading.controller;
import com.books.Reading.model.booksModel;
import com.books.Reading.service.readingListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class readingListController {
#Autowired
private readingListService rlService;
#RequestMapping("/")
#ResponseBody
public booksModel getOne(){
return rlService.getOne();
}
}
service.java
package com.books.Reading.service;
import com.books.Reading.model.booksModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class readingListService {
#Autowired
private com.books.Reading.DAO.readingListDAO readingListDAO;
public booksModel getOne(){
System.out.println(readingListDAO.findFirstByOrderByTitleAsc());
return readingListDAO.findFirstByOrderByTitleAsc();
}
}
application.properties
spring.data.mongodb.host=127.0.0.1
spring.data.mongodb.port=27017
spring.data.mongodb.database=book
spring.session.mongodb.collection-name=readinglist
The MongoDB is hosted locally. How can I retrieve only selected fields (title, isbn and pageCount) from the database.
I am very new to Spring Boot, so if there are other errors or best practices, I welcome your feedback.
By default, all the properties of document will be fetched. if you want to ignore some of the properties in the result, you can use filter option.
#Query(value = "{'title' : ?0}", fields = "{'description' : 0}")
BooksModel findBooksModelByTitle(String title);

ContextRefreshedEvent is not being catched

I am setting up a spring boot application with postgres database
The postgres server is up and does not have much to do with the issue.
Following are my classes:
package com.example.demo.service.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.event.ContextStartedEvent;
#SpringBootApplication
public class ServiceConfiguration {
public static void main(String[] args) {
SpringApplication.run(ServiceConfiguration.class, args);
}
}
package com.example.demo.service.config;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableAutoConfiguration
#EntityScan(basePackages = {"com.example.demo.persistence"})
#EnableJpaRepositories(basePackages = {"com.example.demo.repositories"})
#EnableTransactionManagement
public class RepositoryConfiguration {
}
package com.example.demo.repositories;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
import com.example.demo.persistence.Product;
#Component
public interface ProductRepository extends CrudRepository<Product, Integer>{
}
package com.example.demo.persistence;
import javax.persistence.*;
import java.math.BigDecimal;
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#SequenceGenerator(name="product_id_sequence", sequenceName="product_id_sequence", allocationSize=1)
#Column(name="ID")
private Integer id;
#Version
private Integer version;
private String productId;
private String description;
private String imageUrl;
private BigDecimal price;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}
package com.example.demo.bootstrap;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import com.example.demo.persistence.Product;
import com.example.demo.repositories.ProductRepository;
import java.math.BigDecimal;
#Component
public class ProductLoader implements ApplicationListener<ContextRefreshedEvent> {
private ProductRepository productRepository;
private Logger log = Logger.getLogger(ProductLoader.class);
#Autowired
public void setProductRepository(ProductRepository productRepository) {
this.productRepository = productRepository;
}
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.err.println("Flow never comes here !!");
Product shirt = new Product();
shirt.setDescription("Spring Framework Guru Shirt");
shirt.setPrice(new BigDecimal("18.95"));
shirt.setImageUrl("https://springframework.guru/wp-content/uploads/2015/04/spring_framework_guru_shirt-rf412049699c14ba5b68bb1c09182bfa2_8nax2_512.jpg");
shirt.setProductId("235268845711068308");
productRepository.save(shirt);
log.info("Saved Shirt - id: " + shirt.getId());
Product mug = new Product();
mug.setDescription("Spring Framework Guru Mug");
mug.setImageUrl("https://springframework.guru/wp-content/uploads/2015/04/spring_framework_guru_coffee_mug-r11e7694903c348e1a667dfd2f1474d95_x7j54_8byvr_512.jpg");
mug.setProductId("168639393495335947");
productRepository.save(mug);
log.info("Saved Mug - id:" + mug.getId());
}
}
The ProductLoader class is a component and implements ApplicationListener, still the flow never comes in onApplicationEvent(ContextRefreshedEvent event) method.
Can anybody help?
Got the issue resolved.
Added following annotations to the ServiceConfiguration class
#SpringBootApplication(scanBasePackages = {"com.example.demo.bootstrap","com.example.demo.persistence"})
#EnableJpaRepositories(basePackageClasses = {ProductRepository.class})
#EntityScan(basePackageClasses=Product.class)
public class ServiceConfiguration {
public static void main(String[] args) {
SpringApplication.run(ServiceConfiguration.class, args);
}
}

Jersey - get parameter always null

I changed my code according to R4J answer.
I think there's something more to correct since I can't display anything now...
result I get - console is clear (no errors)
Could anyone be so kind and help me find the issue?
Below I describe my project:
DB:
database table "users"
TestUser.java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "USERS")
public class TestUser {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Column(name = "email", nullable = false)
private String email;
#Column(name = "password", nullable = false)
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
TestService.class
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.test.testapp.dao.UserDao;
import com.test.testapp.model.TestUser;
#Component
public class TestService {
#Autowired
UserDao userDao;
public List<TestUser> getUsers() {
return userDao.findAll();
}
}
UserDao.class
import java.util.List;
import javax.persistence.PersistenceException;
import com.test.testapp.model.TestUser;
public interface UserDao /* extends CrudRepository<TestUser, Integer>*/{
public List<TestUser> findAll() throws PersistenceException;
}
UserDaoImpl.java
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import org.jvnet.hk2.annotations.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.test.testapp.dao.UserDao;
import com.test.testapp.model.TestUser;
#Repository("userDao")
#Service
public class UserDaoImpl implements UserDao {
#Autowired
private EntityManager entityManager;
#PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public TestUser findPersonById(Integer id) {
return entityManager.find(TestUser.class, id);
}
#Override
#Transactional
public List<TestUser> findAll() {
try {
return entityManager.createQuery("SELECT u FROM Users u ORDER BY p.id", TestUser.class).getResultList();
} finally {
entityManager.close();
}
}
}
TestWebApi.java
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#Controller
#Path("test")
public interface TestWebApi {
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/")
public Response getUsers();
}
TestWebApiImpl.java
import java.util.List;
import javax.inject.Inject;
import javax.ws.rs.core.Response;
import com.test.testapp.model.TestUser;
import com.test.testapp.service.TestService;
import com.test.testapp.web.TestWebApi;
public class TestWebApiImpl implements TestWebApi {
#Inject
TestService testService;
#Override
public Response getUsers() {
List<TestUser> test = testService.getUsers();
return Response.ok().entity(test).build();
}
}
You are mixing JAX-RS annotations with Spring-MVC annotations. If you want to stick to JAX-RS then your code should look like this:
#Path("users")
#Component
public class UserController {
#Inject
UserService userService;
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/")
public List<User> getUsers() {
return userService.findAll();
}
#GET
#Path("/users/{name}")
#Produces(MediaType.APPLICATION_JSON)
public Response getUserByName(#NotNull #PathParam("name") String username) {
User user = userService.findByName(username);
return Response.ok().entity(user).build();
}
}
Currently, you have #RestController on your Class which makes it a Spring Rest Controller. So Spring scans all methods and finds '#RequestMapping("/user/{name}")' and '#RequestMapping("/users")' so it binds these methods to default GET operations and ignores completely #PathVariable annotation because it comes from JAX-RS not Spring.
Spring-MVC version of your code would be:
#RestController
#RequestMapping("/")
public class UserController {
#Inject
UserService userService;
#RequestMapping(value = "/users", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public List<User> getUsers() {
return userService.findAll();
}
#RequestMapping(value = "/users/{name}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public Response getUserByName(#NotNull #PathVariable("name") String username) {
User user = userService.findByName(username);
return Response.ok().entity(user).build();
}
}

Resources