Pull Request Doesn't update repository - java

I am trying to change a Perfil object in PerfilRepository by sending the following request with the following code:
package br.com.bandtec.projetocaputeam.controller;
import br.com.bandtec.projetocaputeam.dominio.*;
import br.com.bandtec.projetocaputeam.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
#RestController
#RequestMapping("/caputeam")
public class CaputeamController {
//USER CLASS
public abstract class Perfil {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "nome")
#NotNull
#Size(min = 5,max = 30)
#Pattern(regexp = "^[a-zA-Z\s]*$", message = "Nome inválido! Digite apenas letras e espaçamento") //Permite apenas letras e espaço
private String nome;
#NotNull
#CPF
private String cpf;
#Column(name = "email")
#NotNull
#Email
private String email;
#NotNull
#Size(min = 5,max = 12)
private String senha;
private Integer telefone;
#DecimalMin("0")
#DecimalMax("5")
private Double avaliacao;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "id_endereco")
private Endereco endereco;
#NotNull
private String tipoPerfil;
#OneToOne(cascade = CascadeType.ALL)
private Categoria categoriaAutonomo;
//Getters
public Integer getId() {
return id;
}
public String getNome() {
return nome;
}
public String getCpf() {
return cpf;
}
public String getEmail() {
return email;
}
public String getSenha() {
return senha;
}
public Integer getTelefone() {
return telefone;
}
public Double getAvaliacao() {
return avaliacao;
}
public Endereco getEndereco() {
return endereco;
}
public String getTipoPerfil() {
return tipoPerfil;
}
public Categoria getCategoriaAutonomo() {
return categoriaAutonomo;
}
//Setters
public void setTipoPerfil(String tipoPerfil) {
this.tipoPerfil = tipoPerfil;
}
public void setNome(String nome) {
this.nome = nome;
}
public void setCpf(String cpf) {
this.cpf = cpf;
}
public void setEmail(String email) {
this.email = email;
}
public void setSenha(String senha) {
this.senha = senha;
}
public void setTelefone(Integer telefone) {
this.telefone = telefone;
}
public void setAvaliacao(Double avaliacao) {
this.avaliacao = avaliacao;
}
public void setEndereco(Endereco endereco) {
this.endereco = endereco;
}
public void setCategoriaAutonomo(Categoria categoriaAutonomo) {
this.categoriaAutonomo = categoriaAutonomo;
}
}
//--- REPOSITORIES
#Autowired
private PerfilService perfilService = new PerfilService();
//--- USUARIOS
#GetMapping("/usuarios")
public ResponseEntity getUsuario(){
return perfilService.getPerfisRepository();
}
#PostMapping("/cadastrar-usuario")
public ResponseEntity cadastrarUsuario(#RequestBody #Valid Perfil novoPerfil){
return perfilService.cadastrarUsuario(novoPerfil);
}
#PutMapping("/usuarios/{id}")
public ResponseEntity alterarUsuario(#RequestBody #Valid Perfil usuarioAlterado, #PathVariable int id){
return perfilService.alterarPerfil(usuarioAlterado,id);
}
And thats my method for changing my perfil object
public ResponseEntity alterarPerfil(Perfil perfilAlterado, int id){
perfisRepository.findById(id).map(perfil -> {
perfil.setNome(perfilAlterado.getNome());
perfil.setEmail(perfilAlterado.getEmail());
perfil.setTelefone(perfilAlterado.getTelefone());
return ResponseEntity.ok().build();
});
return ResponseEntity.badRequest().body("Alteração inválida!");
}
Im sending my put request in postman like that:
{
"id": 1,
"nome": "Beatriz Barros",
"cpf": "103.725.810-05",
"email": "bia#hotmail.com",
"senha": "121520",
"telefone": 1134577777,
"avaliacao": 4.9,
"endereco": {
"id": 1,
"cep": "03311111",
"bairro": "Vila Poeira",
"logradouro": "RuaFlor",
"numeroLogradouro": 7,
"complemento": null,
"uf": "sp",
"cidade": "SaoPaulo"
},
"tipoPerfil": "autonomo",
"categoriaAutonomo": {
"id": 1,
"nome": "Jardineiro",
"descricao": null
},
"precoAutonomo": 0.0
}
But it always returns status 400 bad request!
I already tried to send only the fields I want to change (name, email and phone) but it also didn't work
I also tried to send with and without the ID and nothing to work
How can I send a correct request?

Well, that's actually what you're doing.
perfisRepository.findById(id).map(perfil -> {
perfil.setNome(perfilAlterado.getNome());
perfil.setEmail(perfilAlterado.getEmail());
perfil.setTelefone(perfilAlterado.getTelefone());
return ResponseEntity.ok().build();
});
perfil -> { /* */ } is actually a lambda expression or in other words: an anonymous method. So instead of returning in the alterarPerfil method, you're returning in the anonymous method.
I've never worked with Spring, but from reading the docs, I assume that perfisRepository is implementing the CrudRepository interface.
The right code should be something like:
Perfil oldObject = perfisRepository.findById(id).get();
if(oldObject == null) return ResponseEntity.badRequest().body("Alteração inválida!");
oldObject.setNome(perfilAlterado.getNome());
oldObject.setEmail(perfilAlterado.getEmail());
/* and so on - you probably want to use reflection or a helping class to save you some time here */
// For a given entity, save will act as update too.
perfisRepository.save(oldObject);
return ResponseEntity.ok().build();
Since in your code, you aren't persisting any change.

Related

NotBlank validation error in float java (spring boot)

I'm trying to develop an API with an order model and one of the requirements in my model is "price" which takes a float instead of a string
this is the model
package com.api.order_control.models;
import jakarta.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.UUID;
#Entity
#Table(name = "TB_ORDER")
public class OrderModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
#Column(nullable = false, length = 11)
private String customerName;
#Column(nullable = false, length = 15)
private String phoneNumber;
#Column(nullable = false, length = 25)
private String address;
#Column(nullable = false, length = 10)
private String doorNumber;
#Column(nullable = true, length = 5)
private String block;
#Column(nullable = false, length = 30)
private String order;
#Column(nullable = false)
private Float price;
#Column(nullable = false)
private LocalDateTime registrationDate;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDoorNumber() {
return doorNumber;
}
public void setDoorNumber(String doorNumber) {
this.doorNumber = doorNumber;
}
public String getBlock() {
return block;
}
public void setBlock(String block) {
this.block = block;
}
public String getOrder() {
return order;
}
public void setOrder(String order) {
this.order = order;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
public LocalDateTime getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(LocalDateTime registrationDate) {
this.registrationDate = registrationDate;
}
}
this is the dto package
package com.api.order_control.dtos;
import jakarta.validation.constraints.NotBlank;
public class OrderDto {
#NotBlank
private String customerName;
#NotBlank
private String phoneNumber;
#NotBlank
private String address;
#NotBlank
private String doorNumber;
#NotBlank
private String block;
#NotBlank
private String order;
#NotBlank
private Float price;
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String doorNumber() {
return doorNumber;
}
public void doorNumber(String doorName) {
this.doorNumber = doorName;
}
public String getBlock() {
return block;
}
public void setBlock(String block) {
this.block = block;
}
public String getOrder() {
return order;
}
public void setOrder(String order) {
this.order = order;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
}
I created my post method in my controller, but when I test it in my postman I get this error in the terminal:
jakarta.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'jakarta.validation.constraints.NotBlank' validating type 'java.lang.Float'. Check configuration for 'price'
I understand that the problem is in float, but I can't understand what's wrong with this code.
update: controller
package com.api.order_control.controllers;
import com.api.order_control.dtos.OrderDto;
import com.api.order_control.models.OrderModel;
import com.api.order_control.services.OrderService;
import jakarta.validation.Valid;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.ZoneId;
#RestController
#CrossOrigin(origins = "*", maxAge = 3600)
#RequestMapping("/order")
public class OrderController {
final OrderService orderService;
public OrderController(OrderService orderService) {
this.orderService = orderService;
}
#PostMapping
public ResponseEntity<Object> saveOrder(#RequestBody #Valid OrderDto orderDto) {
var orderModel = new OrderModel();
BeanUtils.copyProperties(orderDto, orderModel);
orderModel.setRegistrationDate(LocalDateTime.now(ZoneId.of("UTC")));
return ResponseEntity.status(HttpStatus.CREATED).body(orderService.save(orderModel));
}
}
You need to use #NotNull for Float. The documentation for #NotBlank states:
The annotated element must not be null and must contain at least one non-whitespace character. Accepts CharSequence.
So, as long as you don't use #NotBlank on a String or Char it won't work.
If you need additional validations on the value of the float, you can use #Min, #Max, #Positive and more.

Dynamodb Mapper Save functions not creating the item in table

I tried using the dynamodbmapper for crud operations over the table. When I am using the save functionality from the mapper code getting executed with out any error or exceptions but when I scan the table records were not reflecting what could be the possible error I am doing in below way
try{
User user = new User();
/* added some dummy data to user object*/
static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
static DynamoDBMapper dynamoDB = new DynamoDBMapper(client, new DynamoDBMapperConfig(DynamoDBMapperConfig.SaveBehavior.CLOBBER));
dynamoDB.save(user);
}catch(Exception e){
}
My class object
#DynamoDBTable(tableName = "users")
public class User {
private String id;
private String user_id;
private String email;
private String name;
private String mobile_no;
private Integer createdDate;
private Integer modifiedDate;
#DynamoDBHashKey(attributeName = "id")
public String getId(){
return id;
}
public void setId(String id) {
this.id = id;
}
#DynamoDBAttribute(attributeName = "user_id")
public String getUser_id() {
return user_id;
}
public void setUser_id_ref(String user_id) {
this.user_id = user_id;
}
#DynamoDBAttribute(attributeName = "email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#DynamoDBAttribute(attributeName = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#DynamoDBAttribute(attributeName = "mobile_no")
public String getMobile_no() {
return mobile_no;
}
public void setMobile_no(String mobile_no) {
this.mobile_no = mobile_no;
}
#DynamoDBAttribute(attributeName = "created_date")
public Integer getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Integer createdDate) {
this.createdDate = createdDate;
}
#DynamoDBAttribute(attributeName = "modified_date")
public Integer getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(Integer modifiedDate) {
this.modifiedDate = modifiedDate;
}
For scanning i have used the command
aws dynamodb scan --table-name users
Result for the above command is coming as below
{
"Items": [],
"Count": 0,
"ScannedCount": 0,
"ConsumedCapacity": null
}
Table Description
aws dynamodb describe-table --table-name users
{
"Table": {
"AttributeDefinitions": [
{
"AttributeName": "id",
"AttributeType": "S"
}
],
"TableName": "users",
"KeySchema": [
{
"AttributeName": "id",
"KeyType": "HASH"
}
],
"TableStatus": "ACTIVE",
"CreationDateTime": "2022-09-29T19:33:02.692000+05:30",
"ProvisionedThroughput": {
"LastDecreaseDateTime": "2022-09-29T19:45:29.763000+05:30",
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
}
}
How ever I tried creating a test class where I just have hashkey attribute and tried saving the data it got persisted
package com.moneyview.model.dynamo;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAutoGeneratedKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
#DynamoDBTable(tableName = "users")
public class UserTest {
private String id;
#DynamoDBHashKey(attributeName = "id")
public String getId(){
return id;
}
public void setId(String id) {
this.id = id;
}
}
test code for inserting
public void testinsertItem(){
try{
UserTest test = new UserTest();
test.setId("8a8180967e8b5112017e8b99268702df");
dynamoDB.save(test);
}catch (Exception e){
System.out.println("Something went wrong while inserting the records to DynamoDb");
}
}
When I tried scanning the table
aws dynamodb scan --table-name users
Result:
{
"Items": [
{
"id": {
"S": "8a8180967e8b5112017e8b99268702df"
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}
not sure where I am doing wrong or if there is any issue in the config please help me
The code which you shared is correct, and the item should be persisted.
However, you would need to show your full class, and confirm how you are checking the item exists?
You mention it doesn't exist when your Scan? Are you scanning from your code directly after writing? Check that you have made your Scan Strongly Consistent to ensure you get the latest value.
https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html#DDB-Scan-request-ConsistentRead
If this does not resolve the issue, I will be able to help you further when you share the rest of your code.
Reviewing your updated code it seems pretty fine, I did notice some issues with the setters you defined, but i'm not certain that is your issue. The below code snippet works for me:
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.datamodeling.*;
import java.util.List;
public class UserOverflow {
public static void main(String[] args){
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDBMapper dynamoDB = new DynamoDBMapper(client, new DynamoDBMapperConfig(DynamoDBMapperConfig.SaveBehavior.CLOBBER));
User myUser = new User();
myUser.setId("1");
try{
dynamoDB.save(myUser);
}catch(Exception e){
System.out.println(e.getMessage());
}
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
.withConsistentRead(Boolean.TRUE);
try{
List<User> scanResult = dynamoDB.scan(User.class, scanExpression);
for (User user : scanResult) {
System.out.println(user.getId());
}
}catch (Exception e){
System.out.println(e.getMessage());
}
}
#DynamoDBTable(tableName = "users")
public static class User {
private String id;
private String user_id;
private String email;
private String name;
private String mobile_no;
private Integer createdDate;
private Integer modifiedDate;
#DynamoDBHashKey(attributeName = "id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#DynamoDBAttribute(attributeName = "user_id")
public String getUserId() {
return user_id;
}
public void setUserId(String user_id) {
this.user_id = user_id;
}
#DynamoDBAttribute(attributeName = "email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#DynamoDBAttribute(attributeName = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#DynamoDBAttribute(attributeName = "mobile_no")
public String getMobileNo() {
return mobile_no;
}
public void setMobileNo(String mobile_no) {
this.mobile_no = mobile_no;
}
#DynamoDBAttribute(attributeName = "created_date")
public Integer getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Integer createdDate) {
this.createdDate = createdDate;
}
#DynamoDBAttribute(attributeName = "modified_date")
public Integer getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(Integer modifiedDate) {
this.modifiedDate = modifiedDate;
}
}
}
I'm not sure if your did not have log statements inside your catch block but that is one thing you should definitely add. Should that fail, I would take a look at the following:
IAM policy, do you have the correct permissions
Internet access, does where you are executing the code from have a path to the DynamoDB endpoint?

add a dynamic column to an entity without saving it to the table

I have a model class like the following:
package com.example.model;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.example.helpers.StringMapConverter;
#Entity
#Table(name = "buildingcompanies")
public class Buildcompanies {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name = "shortname")
private String shortname;
#Column(name = "fullname")
private String fullname;
#Column(name = "address")
private String address;
#Column(name = "telephone")
private String telephone;
#Column(name = "website")
private String website;
#Column(name = "sociallinks")
#Convert(converter = StringMapConverter.class)
private Map<String, String> sociallinks;
#Column(name = "foundationyear")
private String foundationyear;
public Buildcompanies() {
}
public Buildcompanies(String shortname, String fullname, String address, String telephone, String website,
Map<String, String> map, String foundationyear) {
this.shortname = shortname;
this.fullname = fullname;
this.address = address;
this.telephone = telephone;
this.website = website;
this.sociallinks = map;
this.foundationyear = foundationyear;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getShortname() {
return shortname;
}
public void setShortname(String shortname) {
this.shortname = shortname;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public Map<String, String> getSociallinks() {
return sociallinks;
}
public void setSociallinks(Map<String, String> sociallinks) {
this.sociallinks = sociallinks;
}
public String getFoundationyear() {
return foundationyear;
}
public void setFoundationyear(String foundationyear) {
this.foundationyear = foundationyear;
}
}
And the method in a controller to show the output:
public ResponseEntity<List<Buildcompanies>> getAllCompanies(#RequestParam(required = false) String name) {
try {
List<Buildcompanies> companies = new ArrayList<Buildcompanies>();
int test=0;
if (name == null)
{
buildcompaniesRepository.findAll().forEach(companies::add);
}
else
buildcompaniesRepository.findByShortnameContaining(name).forEach(companies::add);
if (companies.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(companies, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
It does show an output everythin is just fine:
[
{
"id": 81,
"shortname": "testing",
"fullname": "test",
"address": "addrtest",
"telephone": "380979379992",
"website": "www.site.com",
"sociallinks": {
"facebook": "fb.com"
},
"foundationyear": "1991"
}
]
And I want to calculate each companies rating while showing data to the end user. So the output should be as follows:
[
{
"id": 81,
"shortname": "testing",
"fullname": "test",
"address": "addrtest",
"telephone": "380979379992",
"website": "www.site.com",
"sociallinks": {
"facebook": "fb.com"
},
"foundationyear": "1991",
"rating": "1.5"
}
]
Is it posible to add the rating column dynamicly to the company list or I should to create rating column in database, update method for it in the controller, iterate over the findAll() results and call it each time user tryes to acces /list endpoint?
You have two options:
You may introduce a new attribute in the Buildcompanies class for the purpose and annotate it with #Transient.
This will denote that the attribute need not be persisted in the DB and JPA won't attempt to create a column in the table.
The recommended approach is to not use the Entity class as a response object. You should ideally have a domain object and the database response should be mapped to this object. While mapping you can apply whatever custom details you want to add to it.
Just add #Transient annotation to your dynamic field. There is no corresponding column required in the database. The value of the transient column exists only in runtime.
In general, it is a bad idea to share the entity as a JSON with an external system for many reasons. Use intermediate DTO instead. There are a lot of libraries that allow configurable auto-mapping from entity to DTO (ModelMapper is pretty good for me).

Http status 400, for Spring MVC Rest Api

I'm sending http post request Spring REST API and it is returning http status 400. I have checked every thing I can but still can't solve this. Can someone please help me?
Here is payload of request:
{name: "ewew", description: "addad", dateOfPurchase: "2020-02-02T19:00:00.000Z",…}
name: "ewew"
description: "addad"
dateOfPurchase: "2020-02-02T19:00:00.000Z"
paymentSource: {id: 4, title: "Cash", createdAt: 1494097200000,…}
price: 434343
residualValue: 121211
type: "Vehicle"
usefulLife: 5
#RequestMapping(value="add",method = RequestMethod.POST)
public ResponseEntity add(#Valid #RequestBody FixedAsset fixedAsset, BindingResult bindingResult, HttpServletRequest request){
System.out.println("recieved");
HashMap response = new HashMap();
boolean success = false;
List errors = new ArrayList();
HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
String message = "";
Map data = new HashMap();
Claims claims = (Claims) request.getAttribute("claims");
try
{
User user = userService.findById((Integer) claims.get("id"));
if (!bindingResult.hasErrors())
{
if (fixedAssetService.getByName(fixedAsset.getName()) == null)
{
fixedAssetService.create(fixedAsset);
success = true;
message = "Account Type successfully added";
httpStatus = HttpStatus.OK;
} else
{
message = "Fill the form properly";
errors.add(new ErrorMessage("name", "Account Type with same name already exists"));
}
} else
{
for (FieldError error : bindingResult.getFieldErrors())
{
message = "Fill the form properly";
errors.add(new ErrorMessage(error.getField(), error.getDefaultMessage()));
}
}
} catch (Exception e)
{
errors.add(new ErrorMessage("error", e.getMessage()));
e.printStackTrace();
}
response.put("success", success);
response.put("errors", errors);
response.put("message", message);
response.put("data", data);
return new ResponseEntity(response, httpStatus);
}
This is my model class:
package com.bmis.app.model;
import javax.persistence.*;
import java.util.Date;
#Entity
#Table(name = "fixed_asset")
public class FixedAsset {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public User getAddedBy() {
return addedBy;
}
public void setAddedBy(User addedBy) {
this.addedBy = addedBy;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public float getUsefulLife() {
return usefulLife;
}
public void setUsefulLife(float usefulLife) {
this.usefulLife = usefulLife;
}
public float getResidualValue() {
return residualValue;
}
public void setResidualValue(float residualValue) {
this.residualValue = residualValue;
}
public Account getPayment_source() {
return payment_source;
}
public void setPayment_source(Account payment_source) {
this.payment_source = payment_source;
}
public float getDepreciation() {
return depreciation;
}
public void setDepreciation(float depreciation) {
this.depreciation = depreciation;
}
public float getAccumulatedDepreciation() {
return accumulatedDepreciation;
}
public void setAccumulatedDepreciation(float accumulatedDepreciation) {
this.accumulatedDepreciation = accumulatedDepreciation;
}
public void setDateOfPurchase() {
this.createdAt = new Date();
}
public Date getDateOfPurchase() {
return this.createdAt;
}
#Column(name = "name")
private String name;
#Column(name = "description")
private String description ;
#Column(name="status")
private String status;
#Column(name = "type")
private String type;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "added_by", referencedColumnName = "id")
private User addedBy;
#Column(name = "price")
private float price;
#Column(name = "useful_life")
private float usefulLife;
#Column(name ="residual_value" )
private float residualValue;
#Column(name="depreciation")
private float depreciation;
#Column(name="accumulated_depreciation")
private float accumulatedDepreciation;
#Column(name = "created_at")
private Date createdAt;
public void setCreatedAt() {
this.createdAt = new Date();
}
public Date getCreatedAt() {
return this.createdAt;
}
#Column(name = "date_of_purchase")
private Date dateOfPurchase;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "payment_source", referencedColumnName = "id")
private Account payment_source;
}
Here is frontend:
addFixedAsset(){
if (this.fixedAssetFormGroup.valid) {
this.fixedAsset.name = this.f.name.value;
this.fixedAsset.description=this.f.description.value;
this.fixedAsset.type=this.f.type.value;
this.fixedAsset.price=this.f.price.value;
this.fixedAsset.usefulLife=this.f.usefulLife.value;
this.fixedAsset.residualValue=this.f.residualValue.value;
this.fixedAsset.dateOfPurchase=this.f.dateOfPurchase.value;
this.fixedAsset.paymentSource=this.f.paymentSource.value;
console.log(this.fixedAsset);
this.fixedAssetService.create(this.fixedAsset)
.subscribe(
(successResponse: any) => {
this.messageService.add({
severity: "info",
summary: "Success",
detail: "Fixed asset Successfully Added"
});
this._router.navigate(["/loggedIn", "accounts", "list-fixed-asset"]);
},
errorResponse => {
console.log(errorResponse);
this.messageService.add({
severity: "error",
summary: "Error",
detail: "Fixed Asset Not Added. "
});
},
);
}
}
public create(fixedAsset:FixedAsset) {
return this.http.post(this.appService.getApiUrl() + "api/fixed-asset/add", JSON.stringify(fixedAsset, this.appService.jsonStringifier));
}

Content type 'application/json;charset=UTF-8' not supported

I am creating a newsletter API using java spring framework. Whenever I am hitting the API as a post with request model getting this excetion org.springframework.web.HttpMediaTypeNotSupportedException.
This is my newsletter model
#Entity
#Table(name = "ns_newsletters")
public class Newsletter extends DomainObject {
#Id
#GeneratedValue(strategy = GenerationType.TABLE, generator = "newsletter_gen")
#TableGenerator(name = "newsletter_gen", table = "ns_newsletter_id_gen", pkColumnName = "GEN_NAME", valueColumnName = "GEN_VAL", pkColumnValue = "NewsletterId_Gen", initialValue = 1, allocationSize = 1)
#Column(name = "subscriber_id")
private int subscriberId;
#Column(name = "subscriber_email_address")
private String subscriberEmailAddress;
#Column(name = "is_subscribe")
public boolean isSubscribe;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "gender")
private String gender;
#JsonManagedReference
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "ns_newsletter_mailer_list_linkage", joinColumns = {#JoinColumn(name = "subscriber_id")},
inverseJoinColumns = {#JoinColumn(name = "newsletter_mailer_id")})
private Set<NewsletterMailerList> mailerLists;
public Newsletter() {
super();
}
public Newsletter(String createdBy, Timestamp creationDate, int version, Timestamp lastModifiedDate,
String lastModifiedBy, RecordStatus recordStatus) {
super(createdBy, creationDate, version, lastModifiedDate, lastModifiedBy, recordStatus);
}
public Newsletter(Set<NewsletterMailerList> mailerLists, int subscriberId, String subscriberEmailId, boolean isSubscribe, String firstName, String lastName, String sex) {
super();
this.subscriberId = subscriberId;
this.subscriberEmailAddress = subscriberEmailId;
this.isSubscribe = isSubscribe;
this.firstName = firstName;
this.lastName = lastName;
this.gender = sex;
this.mailerLists = mailerLists;
}
public int getSubscriberId() {
return subscriberId;
}
public void setSubscriberId(int subscriberId) {
this.subscriberId = subscriberId;
}
public String getSubscriberEmailAddress() {
return subscriberEmailAddress;
}
public void setSubscriberEmailAddress(String subscriberEmailAddress) {
this.subscriberEmailAddress = subscriberEmailAddress;
}
public boolean isSubscribe() {
return isSubscribe;
}
public void setSubscribe(boolean subscribe) {
isSubscribe = subscribe;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Set<NewsletterMailerList> getMailerLists() {
return mailerLists;
}
public void setMailerLists(Set<NewsletterMailerList> mailerLists) {
this.mailerLists = mailerLists;
}
}
This is my NewsletterMailerList model
#Entity
#Table(name = "ns_newsletter_mailer_list")
public class NewsletterMailerList extends DomainObject {
#Id
#GeneratedValue(strategy = GenerationType.TABLE, generator = "newsletter_mailer_list_gen")
#TableGenerator(name = "newsletter_mailer_list_gen", table = "ns_newsletter_mailer_list_id_gen", pkColumnName = "GEN_NAME", valueColumnName = "GEN_VAL", pkColumnValue = "NewsletterMailerList_Gen", initialValue = 1000, allocationSize = 1)
#Column(name = "newsletter_mailer_id")
private int newsletterMailerId;
#Column(name = "mailer_list_name")
private String mailerListName;
#Column(name = "description")
private String description;
#JsonBackReference
#ManyToMany(cascade = CascadeType.ALL, mappedBy = "mailerLists")
private Set<Newsletter> newsletters;
public Set<Newsletter> getNewsletter() {
return newsletters;
}
public void setNewsletter(Set<Newsletter> newsletters) {
this.newsletters = newsletters;
}
public int getNewsletterMailerId() {
return newsletterMailerId;
}
public void setNewsletterMailerId(int newsletterMailerId) {
this.newsletterMailerId = newsletterMailerId;
}
public String getMailerListName() {
return mailerListName;
}
public void setMailerListName(String mailerListName) {
this.mailerListName = mailerListName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Newsletter> getNewsletters() {
return newsletters;
}
public void setNewsletters(Set<Newsletter> newsletters) {
this.newsletters = newsletters;
}
}
I give contain type as application/json.
I am new to do this kind of stuff. Please help me why I am getting this error. If you need anything more let me know.
This is Newsletter Controller
package com.neostencil.modules.newslettermanagement.controller;
import com.neostencil.framework.base.BaseResponse;
import com.neostencil.framework.enums.StatusType;
import com.neostencil.framework.utilities.common.CollectionUtil;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
#RestController
#RequestMapping(value = "api/v1")
#Api(value = "Newsletter", description = "Rest API for Newsletter
operations", tags = "Newsletter API")
public class NewsletterController {
#Autowired
NewsletterService newsletterService;
#RequestMapping(value = "/newsletters", method = RequestMethod.POST)
public ResponseEntity<BaseResponse> addNewsletter(RequestEntity<SingleNewsletterRequest> request) {
ResponseEntity<BaseResponse> response = null;
BaseResponse baseResponse = new BaseResponse();
List<String> messages = new ArrayList<>();
if (request.getBody() == null) {
baseResponse.setStatus(StatusType.NOT_FOUND);
messages.add("Newsletter request is empty or null");
baseResponse.setMessages(messages);
response = new ResponseEntity<BaseResponse>(baseResponse, HttpStatus.BAD_REQUEST);
} else {
Newsletter newsletter = request.getBody().getNewsletter();
Set<NewsletterMailerList> mailerLists = request.getBody().getNewsletter().getMailerLists();
if (CollectionUtil.isEmpty(mailerLists) || !mailerLists.contains(MailerListType.list_1) || !mailerLists.contains(MailerListType.list_2)) {
NewsletterMailerList newsletterMailerList1 = new NewsletterMailerList();
newsletterMailerList1.setMailerListName(MailerListType.list_1);
NewsletterMailerList newsletterMailerList2 = new NewsletterMailerList();
newsletterMailerList2.setMailerListName(MailerListType.list_2);
mailerLists.add(newsletterMailerList1);
mailerLists.add(newsletterMailerList2);
newsletter.setMailerLists(mailerLists);
}
newsletterService.addNewsletter(newsletter);
baseResponse.setStatus(StatusType.SUCCESSFUL);
messages.add("Newsletter added successfully");
baseResponse.setMessages(messages);
response = new ResponseEntity<BaseResponse>(baseResponse, HttpStatus.OK);
}
return response;
}
}
This is request class
public class SingleNewsletterRequest {
Newsletter newsletter;
public Newsletter getNewsletter() {
return newsletter;
}
public void setNewsletter(Newsletter newsletter) {
this.newsletter = newsletter;
}
}
In my case the issue occurred due to some functional methods of the DTO have the names that follow Java Beans naming conventions, e.g. isValid().
It was absent in a request json-representation and then, when it's deserialized in back-end side the issue occurred.
So, try to check if any Java Beans methods (get*, set*, is*) has no their counterparts in respective front-end objects and avoid such methods (I've just changed the name to simply valid()).
Hopefully this helps.
In your POST method add the consumes attribute
#RequestMapping(value = "/newsletters", method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<BaseResponse> addNewsletter(RequestEntity<SingleNewsletterRequest> request) {
....
}
this will assumes that the HTTP request you are creating actually has
Content-Type:application/json instead of text/plain
Answered here: https://stackoverflow.com/a/50567626/8956733
Try to remove #JsonManagedReference
A bit weird, but it did help me as well (see my comment below).

Categories