I am trying to update my database (postgresql) in my spring boot app with some form information that I will get from an angular 8 form. How can I complete the code below to do so ?
PS : I have no access to the front devs, so no access to the angular code.
My Entity :
#Entity
#Data
#Table(name = "person")
#AllArgsConstructor
#NoArgsConstructor
public class PersonEntity implements java.io.Serializable {
#Id
#Column(name = "id_person")
private int idPerson;
#Column(name = "name")
private String name;
#Column(name = "alive")
private Boolean alive;
}
My Mapping class :
#Data
public class PersonForm {
#NotBlank
private String idPerson;
#NotBlank
private String name;
private boolean alive;
}
My Repository :
#Repository
public interface IPersonRepository extends JpaRepository<PersonEntity, String> {
}
My Controller :
#RequestMapping(value = "person")
public class PersonController {
private final PersonService personService;
public PersonController(PersonService personService) {this.personService = personService;}
#PostMapping(value = "savePerson")
#ResponseBody
public ResponseEntity<PersonEntity> savePerson(#RequestBody final PersonForm form) {
return ?
}
}
My Service :
#Transactional
#Service
public class PersonService {
#Autowired
private IPersonRepository personRepository;
public IPersonRepository(IPersonRepository personRepository) {
this.personRepository = personRepository;
}
Maybe this is enough to work.
Have others ways to do it, this is only example that complements your line of thought.
If you get a compilation error or another error, let me know :)
First you need create your object PersonEntity and sent it to your service.
#RequestMapping(value = "person")
public class PersonController {
private final PersonService personService;
public PersonController(PersonService personService) {this.personService = personService;}
#PostMapping(value = "savePerson")
#ResponseBody
public ResponseEntity<PersonEntity> savePerson(#RequestBody final PersonForm form) {
PersonEntity entity = new PersonEntity(form);
entity = personService.save(entity);
return ResponseEntity.ok(entity);
}
}
In your service, you will call the save method from repository implementation.
#Transactional
#Service
public class PersonService {
#Autowired
private IPersonRepository personRepository;
public IPersonRepository(IPersonRepository personRepository) {
this.personRepository = personRepository;
}
public PersonEntity save(PersonEntity entity) {
return personRepository.save(entity);
}
}
After it you will create ResponseEntity in the method PersonController.savePerson
Related
I am using Jasypt to encrypt some of the fields before saving into MongoDB, below are my codes.
In my code, I have included JaVers and I'm using it for audit purpose.
In the onBeforeSave() method, I have encrypted some of the fields before save in a index in MongoDB and this part is working fine. The part not working is, when JaVers create the audit, the fields that I encrypted are still in clear text, in jv_snapshot index. May I know how can I config JaVers so that it will be able to record the audit same as the onBeforeSave()?
PersonService.createPerson() this method should be creating a new record in Javers, but it is clear text. Can anyone please help or advise?
#Configuration
public class JasyptConfig{
#Bean
public AES256TextEncryptor aes256Encryptor(){
AES256TextEncryptor encryptor = new AES256TextEncryptor();
encryptor.setPassword("password");
return encryptor;
}
}
#Component
public class MongoBeforeSave extends AbstractMongoEventListener<Object>{
#Autowired
AES256TextEncryptor encryptor;
#Override
public void onBeforeSave(BeforeSaveEvent<Object> event){
Document eventObj = event.getDocument();
List<String> fields = Arrays.asList("address,creditcard".split(","));
for(String key: eventObj.keySet()){
if(fields.contains(key)){
String text = eventObj.get(key).toString();
eventObj.put(key, encryptor.encrypt(text));
}
}
super.onBeforeSave(event);
}
}
#Getter
#Setter
public class NewPersonDTO{
private String name;
private String address;
private String creditcard;
}
#Getter
#Setter
public class Person{
private String name;
private String address;
private String creditcard;
}
#RestController
#RequestMapping("/person")
public class PersonController{
private final PersonService personService;
#PostMapping
public void createPerson(#RequestBody NewPersonDTO newPerson){
personService.createPerson(newPerson);
}
}
#Service
#RequiredArgsConstructor
public class PersonService{
private final PersonRepository personRepository;
public void createPerson(NewPersonDTO newPerson){
Person p = new Person();
//then transfer the fields value from NewPersonDTO to Person
personRepository.save(p);
}
}
#Repository
#JaversSpringDataAuditable
public interface PersonRepository extends MongoRepository<Person, String>{
}
I'm a bit new to Spring Boot and I'm trying to create model/repo/service/serviceImp/controller type of architecture.
After I try to make a this get request:
http://localhost:8080/api/v1/people/name?name=steve
and I get this error (I created a couple of people in DB):
"java.lang.NullPointerException: Cannot invoke \"com.project.Springbootbackend.service.PeopleService.findAllByName(String)\" because \"this.peopleService\" is null\r\n\tat com.project.Springbootbackend.controller.PeopleController.findAllByName(PeopleController.java:24)
This is my code:
People(entity)
#Entity
public class People {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "name")
private String name;
#Column(name = "surname")
private String surname;
#Column(name = "email")
private String email;
...
//constructor + get/set
PeopleController
#RestController
#RequestMapping("/api/v1/people")
#RequiredArgsConstructor
public class PeopleController {
private PeopleService peopleService;
#GetMapping("/name")
public ResponseEntity<List<People>> findAllByName(#RequestParam String name) {
return ResponseEntity.ok().body(peopleService.findAllByName(name));
}
}
PeopleRepo
public interface PeopleRepository extends JpaRepository<People, Integer> {
List<People> findAllByName(String name);
}
PeopleService
public interface PeopleService {
List<People> findAllByName(String name);
}
PeopleServiceImp
#RequiredArgsConstructor
#Service
public class PeopleServiceImp implements PeopleService {
PeopleRepository peopleRepository;
#Override
public List findAllByName(String name) {
return (List) ResponseEntity.ok(peopleRepository.findAllByName(name));
}
}
Thx guys in advance.
*SOLUTION:
Entity, service & repository is the same.
ServiceImp and controller changes are down belowe:
Controller:
#RestController
#RequestMapping("/api/v1/people")
public class PeopleController {
private PeopleService peopleService;
public PeopleController(PeopleService peopleService) {
this.peopleService = peopleService;
}
#GetMapping("/name")
public ResponseEntity<List<People>> findAllByName(#RequestParam String name) {
return ResponseEntity.ok().body(peopleService.findAllByName(name));
}
}
ServiceImp
#Service
public class PeopleServiceImp implements PeopleService {
private PeopleRepository peopleRepository;
public PeopleServiceImp(PeopleRepository peopleRepository) {
this.peopleRepository = peopleRepository;
}
#Override
public List<People> findAllByName(String name) {
List<People> people = peopleRepository.findAllByName(name);
return people;
}
}
Your constructor does not inject the service, because of the RequiredArgsConstructor (see Link) needs special treatment. Therefore, use final:
#RestController
#RequestMapping("/api/v1/people")
#RequiredArgsConstructor
public class PeopleController {
private final PeopleService peopleService;
#GetMapping("/name")
public ResponseEntity<List<People>> findAllByName(#RequestParam String name) {
return ResponseEntity.ok().body(peopleService.findAllByName(name));
}
}
Same here:
#RequiredArgsConstructor
#Service
public class PeopleServiceImp implements PeopleService {
private final PeopleRepository peopleRepository;
#Override
public List findAllByName(String name) {
return (List) ResponseEntity.ok(peopleRepository.findAllByName(name));
}
}
Additional hint, use a typed list:
#Override
public List<People> findAllByName(String name) {
return ResponseEntity.ok(peopleRepository.findAllByName(name));
}
Try like this:
#Autowired
private PeopleService peopleService;
#Autowired
private PeopleRepository peopleRepository;
You also need to add the #SpringBootApplication annotation in the main class of the application.
Something like that:
#SpringBootApplication
class PeopleApplication {
public static void main(String[] args) {
...
Take a look at this article about automatic dependency injection in Spring:
https://www.baeldung.com/spring-autowire
You missed the autowiring annotation in the controller to inject the service which may make this.peopleService to be null.
#Autowired
private PeopleService peopleService;
You also need to do autowire in your serviceimpl class
#Autowired
private PeopleRepository peopleRepository;
I am trying to use dependency injection in Java Spring Boot. Receiving Error below in controller in this line. productService.updateProduct(product);
Error: Change 1st parameter of abstract method from Product to Optional
How can this be resolved?
public class Product {
#Getter #Setter public #Id #GeneratedValue Long productId;
#Getter #Setter public String productName;
#Getter #Setter public String productDescription;
Product() {}
Product(String productName, String productDescription) {
this.productName = productName;
this.productDescription = productDescription;
}
}
Interface:
public interface IProductService {
public Product updateProduct(Product product);
}
Service:
#Service
public class ProductService implements IProductService {
#Override
public Product updateProduct(Product product){
product.productName = "test12345";
return product;
}
}
Controller:
class ProductController {
ProductRepository repository;
#Autowired IProductService productService;
ProductController(IProductService productService, ProductRepository repository) {
this.productService = productService;
this.repository = repository;
}
#GetMapping("/products/{id}")
Product one(#PathVariable Long id) {
var product = repository.findById(id);
var finalProduct = productService.updateProduct(product); // error in this line
return finalProduct;
}
And check whether your Repository class return Optional<Product>. because findbyId return type of optional. Then your have to use like below.
Optional<Product> product = repository.findById(id);
And Better to add #Autowire #Controller annotation no need constructor.
#Controller
class ProductController {
#Autowired
private ProductRepository repository;
#Autowire
private IProductService productService;
}
I want to get some data from Neo4j using Spring boot, but I always get nothing. In other words, it seems that java cannot get the data from the neo4j database.
The code is written according to the neo4j Spring tutorial.https://neo4j.com/developer/spring-data-neo4j/
domain class
#NodeEntity
public class Weather {
#Id
#GeneratedValue
private Long id;
private String name;
#Relationship(type = "HAS_INSTANCE")
private List<Instance> instances = new ArrayList<>();
#Relationship(type = "HAS_CHARACTERISTIC")
private List<Characteristic> characteristics = new ArrayList<>();
...
}
repository class
#RepositoryRestResource(collectionResourceRel = "weathers", path = "weathers")
public interface WeatherRepository extends Neo4jRepository<Weather, Long> {
}
service class
#Service
public class WeatherService {
private final WeatherRepository weatherRepository;
public WeatherService(WeatherRepository weatherRepository){
this.weatherRepository = weatherRepository;
}
#Transactional(readOnly = true)
public Iterable<Weather> findAll(){
Iterable<Weather> result = weatherRepository.findAll();
return result;
}
}
controller class
#RestController
#RequestMapping("/")
public class WeatherController {
private final WeatherService weatherService;
public WeatherController(WeatherService weatherService){
this.weatherService = weatherService;
}
#GetMapping("/findAll")
public Iterable<Weather> findAll(){
return weatherService.findAll();
}
}
And the username and password configuration are in the application.properties.
Could someone help me about it? Thanks!
In my database I have two tables airport and calendar connected by foreight key airport_id. I want to get json response with data from two tables for the determined airport_id=273
For example I want to get data for Airport with airport_id and Calendar with foreight key airport_id equels 273. Actually, I've got empty response from localhost:8080. I didn't get any error, just a blank page, like on the picture below. What I do wrong? Thank you in advance!
Airport.java
#Entity
#Table(name = "airport")
public class Airport {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer airport_id;
#Column(name = "departureAirport")
private String departureAirport;
#Column(name = "destinationAirport")
private String destinationAirport;
#OneToMany(mappedBy = "airport")
#JsonManagedReference("airport")
private List<Calendar> calendars; ....
Calendar.java
#Entity
#Table(name = "calendar")
public class Calendar {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer calendar_id;
#Column(name = "departureTime")
private Time departureTime;
#Column(name = "destinationTime")
private Time destinationTime;
#ManyToOne(targetEntity = Airport.class)
#JoinColumn(name = "airport_id")
#JsonBackReference("airport")
private Airport airport; ....
CalendarController.java
public class CalendarController {
#Autowired
CalendarService calendarService;
#Autowired
AirportService airportService;
#GetMapping(value = "/search/{airport_id}")
public List<Calendar> getCalendars(#PathVariable("airport_id") Integer airport_id) {
Airport airport = airportService.findOne(airport_id);
return calendarService.findOne(airport);
}}
CalendarRepository.java
public interface CalendarRepository extends CrudRepository<Calendar, Integer> {
Calendar getOne(int calendar_id);
List<Calendar> findByAirport(Airport airport_id);
}
CalendarService.java
public interface CalendarService {
List<Calendar> findOne(Airport airport_id);
}
CalendarServiceImpl.java
#Service
public class CalendarServiceImpl implements CalendarService {
#Autowired
CalendarRepository repository;
#Autowired
AirportRepository airportRepository;
#Override
public List<Calendar> getCalendars(Integer airport_id) {
Airport airport = airportRepository.getOne(airport_id);
return repository.findByAirport(airport);
}}
Update
AirpostService.java
public interface AirportService {
Airport findOne(int airport_id);
}
AirportRepository.java
public interface AirportRepository extends CrudRepository<Airport, Integer> {
Airport getOne(Integer airport_id);
}
The problem is not your Hibernate, but your Controller. You just need to add the #Responsebody annotation to your method. The #ResponseBody annotation tells a controller that the object returned is automatically serialized into JSON.
#GetMapping(value = "/search/{airport_id}")
#ResponseBody
public List<Calendar> getCalendars(#PathVariable("airport_id") Integer airport_id) {
Airport airport = airportService.findOne(airport_id);
return calendarService.findOne(airport);
}}