Why am i getting nulls in parameters inside json? - spring

this is small spring-boot project
I am unable to get users parameteres
I still can create other users in db using POST method, but when i am trying get list of all users or only one by id, i am getting json with nulls in users parameters.
I want to get this from getUsers method
{
"id": 1,
"name": testName,
"password": testPassword,
"email": testEmail,
"phoneNumber": testPhoneNumber,
"status": USER
},
Instread of this i am getting
{
"id": null,
"name": null,
"password": null,
"email": null,
"phoneNumber": null,
"status": null
},
Here is my entity class
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id",nullable = false)
private Integer id;
#Column(name = "name",nullable = false)
private String name;
#Column(name = "password",nullable = false)
private String password;
#Column(name = "email",nullable = false)
private String email;
#Column(name = "phoneNumber",nullable = false)
private String phoneNumber;
#Column(name = "status",nullable = false)
private Status status;
}
My controller
#Controller
#RequestMapping
#RequiredArgsConstructor
#Validated
public class UserController {
private final UserService userService;
#Operation(description = "Getting list of users")
#GetMapping(
value = "/v1/users",
produces = {"application/json"}
)
public ResponseEntity<List<UserDto>> getUsers() {
return ResponseEntity.ok(userService.getUsers());
}
My service
#Service
#RequiredArgsConstructor
#Data
public class UserService {
private final UserRepository userRepository;
private final UserMapper userMapper;
public List<UserDto> getUsers() {
return StreamSupport.stream(userRepository.findAll().spliterator(), false)
.map(userMapper::userToUserDto).collect(Collectors.toList());
}

Related

Multipartfile charset=UTF-8 is not supported spring boot api rest

The code was working normally and I've tried in every way to solve it and I couldn't, it may be that after I transformed the MultipartFile into an array this happened
#RestController
#RequestMapping("products")
public class ProductController {
#Autowired
private ProductService productService;
#PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
#Transactional
public ResponseEntity<ShowProductsDTO> registerProduct(
#RequestBody #Valid ProductDTO dto,
#RequestParam(name = "files", required = true) MultipartFile[] files,
UriComponentsBuilder uriBuilder) {
ShowProductsDTO showProductsDTO = null;
try {
showProductsDTO = productService.save(dto, files);
} catch (IOException e) {
e.printStackTrace();
}
var uri = uriBuilder.path("/products/{id}").buildAndExpand(showProductsDTO.id()).toUri();
return ResponseEntity.created(uri).body(showProductsDTO);
}
DTO
public record ProductDTO(
#NotBlank
String name,
#NotBlank
String description,
#NotNull
#NumberFormat
BigDecimal price,
#NumberFormat
#NotNull
Integer quantity,
#NotNull
Boolean active,
#NotNull
Long sub_category_id
) {
}
Error console
Resolved [org.springframework.web.HttpMediaTypeNotSupportedException:
Content-Type
'multipart/form-data;boundary=--------------------------816548045966415708649211;charset=UTF-8'
is not supported]
Postman body > raw > json
{
"name": "Nome do produto",
"description": "descricao do produto",
"price": "2500.00",
"quantity": "2",
"active": "true",
"sub_category_id": "1"
}
Postman > body > form-data
KEY "files", TYPE file, VALUE uma imagem minha em png
Error postman
{
"timestamp": "2023-01-11T06:15:43.455+00:00",
"status": 415,
"error": "Unsupported Media Type",
"message": "Content-Type 'multipart/form-data;boundary=--------------------------056640214920648036756520;charset=UTF-8' is not supported.",
"path": "/products"
}
Product entity
#Table(name = "products")
#Entity(name = "Product")
#Getter
#Setter
#NoArgsConstructor
#EqualsAndHashCode(of = "id")
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(length = 100, unique = true, nullable = false)
private String name;
#Column(nullable = false, columnDefinition = "TEXT")
private String description;
#Column(length = 8, nullable = false, columnDefinition = "NUMERIC(8,2)")
private BigDecimal price;
#Column(nullable = false, columnDefinition = "INT")
private Integer quantity;
#Column(nullable = false, columnDefinition = "BOOLEAN")
private Boolean active;
#CollectionTable(name = "products_files",
joinColumns =
#JoinColumn(name = "product_id", referencedColumnName = "id"))
private List<String> productFiles;
#JoinColumn(name = "sub_category_id")
#ManyToOne(fetch = FetchType.EAGER)
private SubCategory subCategory;
how do I fix this error?
Change your attribute to #PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
and call your api using Postman body > raw > json.
The thing is, Content-Type: form-data handles file requests.

How to insert an object inside another in Spring

I'm trying to insert the Insurance object into **User **through an endpoint in Spring, but either the request asks me for all User attributes or the object is not inserted.
**User Class **
#Entity
#Table(name = "users",
uniqueConstraints = {
#UniqueConstraint(columnNames = "username"),
#UniqueConstraint(columnNames = "email")
})
#AllArgsConstructor
#NoArgsConstructor
#Data
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotBlank
#Size(max = 20)
private String username;
private String documento;
private String telefone;
#Value("${some.key:false}")
private boolean first_acess;
private String formacao;
private String sexo;
private String data_nascimento;
#NotBlank
#Size(max = 50)
#Email
private String email;
#NotBlank
#Size(max = 120)
private String password;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable( name = "user_roles",
joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<>();
#Embedded
private Address address;
#ManyToOne
#JoinColumn(name = "insuranceId")
private Insurance insurance;
Insurance class
#Data
#Entity
#AllArgsConstructor
#NoArgsConstructor
#Table(name = "insurance")
public class Insurance {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long insuranceId;
private String name;
private String valor;
private String maximoDependentes;
private String vencimento;
private String descricao;
}
Request to insert into class
#PostMapping("/User/{id}/addPlan")
public ResponseEntity<User> addPlanToUser(#PathVariable("id") long id, #RequestBody SignInsuranceRequest signInsuranceRequest) {
User user = userRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Not found User with id = " + id));
return new ResponseEntity<>(userRepository.save(user), HttpStatus.OK);
}
Custom request for the solution
public class SignInsuranceRequest {
#ManyToOne
#JoinColumn(name = "insuranceId", insertable = false, updatable = false)
private Insurance insurance;
public Insurance getInsurance() {
return insurance;
}
public void setInsurance(Insurance insurance) {
this.insurance = insurance;
}
}
I already tried to put the User in #RequestBody and just ask for the insurance and it didn't work either
Example of how it was done
#PutMapping("/User/{id}/addPlan")
public ResponseEntity<User> addPlanToUser(#PathVariable("id") long id, #RequestBody User user) {
User _user = userRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Not found User with id = " + id));
_user.setInsurance(user.getInsurance());
return new ResponseEntity<>(userRepository.save(_user), HttpStatus.OK);
}
In this attempt, I would pass the id of an insurance in the body of the request and the ID of the user in the Header but the id of the database was not retrieved.
Response
{
"id": 1,
"username": "user",
"documento": null,
"telefone": null,
"first_acess": false,
"formacao": null,
"sexo": null,
"data_nascimento": null,
"email": "user#user.com",
"password": "$2a$10$DUkVRxFFiR7L2OpwwpxHyOCC.7v/iFLqp66BBqy3AC0lHrVa9lnQK",
"roles": [],
"address": null,
"insurance": {
"insuranceId": 1,
"name": "string",
"valor": "string",
"maximoDependentes": "string",
"vencimento": "string",
"descricao": "string"
}
}
I expected to insert an User class into a Insurance Class(Already created) and return the object of User completed.

How to use a DTO class passing a Embedded class for verification?

How can I tackle a #Embedded class inside of a Model class?
I'm trying to use a DTO to filter and check the requests being sent to the POST mapping.
I want to check, let's say, if the fullName is not blank.
(request body below)
DentistModel.java
public class DentistModel {
#Id
#GeneratedValue(generator = "UUID")
#GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
#Column(name = "dentist_id", updatable = false, nullable = false)
#Type(type = "org.hibernate.type.UUIDCharType")
private UUID id;
#Column(nullable = false, unique = true, length = 10)
private String croNumber;
#Embedded
private Person person;
}
DentistDto.java
public class DentistDto {
#NotBlank
private String croNumber;
}
DentistController.java
#PostMapping
public ResponseEntity<Object> saveDentist(#RequestBody #Valid DentistDto dentistDto) {
if (dentistService.existsByCroNumber(dentistDto.getCroNumber())) {
return ResponseEntity.status(HttpStatus.CONFLICT).body("Conflict: CRO number is already in use.");
}
var dentistModel = new DentistModel();
BeanUtils.copyProperties(dentistDto, dentistModel);
return ResponseEntity.status(HttpStatus.CREATED).body(dentistService.save(dentistModel));
}
Dentist request body
{
"croNumber":"12345",
"person": {
"fullName": "John",
"birthDate": "2000-01-27",
"cpfNumber": "11408247910",
"telephoneNumber": "47996034002",
"emailAddress": "john#gmail.com",
"address": {
"mainAddress": "Rua Amoroso Costa",
"numberAddress": "171",
"neighborHood": "Jardim das Américas",
"complementInfo": "Casa",
"zipCode": "81530-150"
}
}
}

Spring data couchbase return null on one field

I want to do a simple getAll, but I have a null value on an embedded object.
Response :
[
{
"id": "0da716f2-6ef0-404f-9403-4d869a6b6853",
"channelName": "general",
"broadcast": {
"tenantId": "45bd5d1f-f585-44df-b37c-7882c123a492",
"broadcastName": "fix",
"id": null
}
}
]
I cant get the broadcastId, in couchbase web I can see that its present there but I cannot get it when using getAll() nor any other method.
Classes :
#Document
//lombok...
public class Broadcast implements Serializable {
private static final long serialVersionUID = 1L;
#GeneratedValue(strategy = GenerationStrategy.UNIQUE)
//#JsonProperty(access = JsonProperty.Access.READ_ONLY)
//#Schema(accessMode = Schema.AccessMode.READ_ONLY)
private String id;
#Field
private String tenantId;
#Field
private String broadcastName;
}
#Document
//lombok...
public class Channel implements Serializable {
private static final long serialVersionUID = 1L;
#GeneratedValue(strategy = GenerationStrategy.UNIQUE)
private String id;
#Field
private String channelName;
#Field
private Broadcast broadcast;
}

SnippetException: Cannot document response fields as the response body is empty

Here is my Controller:
#PostMapping("post")
#PreAuthorize("hasAuthority('WRITE')")
public ResponseEntity<?> createPost(#RequestBody PostEntity postEntity) {
return new ResponseEntity<>(postService.createPost(postEntity), HttpStatus.CREATED);
}
Service :
#Override
public Post createPost(PostEntity postEntity) {
return postFactory.buildPost(postEntityRepository.save(postEntity));
}
//Post is Immutable class here
public Post buildPost(PostEntity entity) {
return new Post.Builder()
.groupId(entity.getGroupEntity().getGroupId())
.postedBy(entity.getPostedBy().getUsername())
.postType(entity.getType())
.postMedia(entity.getPostMedia())
.postId(entity.getPostId())
.build();
}
Here is my mockMvc:
#BeforeEach
public void setUp(WebApplicationContext webApplicationContext,
RestDocumentationContextProvider restDocumentation) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.apply(documentationConfiguration(restDocumentation))
.alwaysDo(document("{method-name}",
preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
.build();
}
Here is my Test:
this.mockMvc.perform(post("/api/post")
.contentType(MediaTypes.HAL_JSON)
.contextPath("/api")
.content(this.objectMapper.writeValueAsString(postEntity)))
.andExpect(status().isCreated())
.andDo(
document("{method-name}", preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
requestFields(describeCreatePostRequest()),
responseFields(describePostEntityResult())
));
Here is Post call:
#Value.Immutable
#JsonSerialize(as = ImmutablePost.class)
#JsonDeserialize(as = ImmutablePost.class)
#JsonInclude(JsonInclude.Include.NON_NULL)
#Relation(value = "post", collectionRelation = "posts")
public interface Post {
Long getPostId();
String getPostType();
String postedBy();
#Nullable
PostMedia postMedia();
Long groupId();
class Builder extends ImmutablePost.Builder {}
}
PostEntity #Entity class here is json format:
{
"type" : "text",
"postedBy" : {
"username": "sandeep"
},
"postMedia" : {
"mediaType": "text",
"mediaUrl": "null",
"content": "Hi this is testing media content",
"createdAt": 1234,
"updatedAt": 689
},
"groupEntity": {
"groupId": 4
}
}
And Post entity class:
#Entity
#Table(name = "POST")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class PostEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "POST_ID")
private Long postId;
#Column(name = "POST_TYPE")
private String type;
#ManyToOne
#JoinColumn(name = "username", referencedColumnName = "username")
private User postedBy;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "post_media_id", referencedColumnName = "id")
private PostMedia postMedia;
#ManyToOne(cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)
#JoinColumn(name = "GROUP_ID", referencedColumnName = "GROUP_ID")
private GroupEntity groupEntity;
public PostEntity() {
}
}
I have tried
objectMapper.readValue(objectMapper.writeValueAsString(postEntity), ImmutablePost.class);
As well. but still its not working, I am facing same exception:
org.springframework.restdocs.snippet.SnippetException: Cannot document response fields as the response body is empty
at org.springframework.restdocs.payload.AbstractFieldsSnippet.verifyContent(AbstractFieldsSnippet.java:191)
at org.springframework.restdocs.payload.AbstractFieldsSnippet.createModel(AbstractFieldsSnippet.java:147)
at org.springframework.restdocs.snippet.TemplatedSnippet.document(TemplatedSnippet.java:78)
at org.springframework.restdocs.generate.RestDocumentationGenerator.handle(RestDocumentationGenerator.java:191)
The problem is with the "PostMedia" setters "PostMedia" and "GroupEntity". You need to accept strings in the setters parameter and convert them to the corresponding entity. Expecting the setter's arguments as the custom entity type is making the problem.
For example:
public class MyModel {
private CustomEnum myEnum;
public CustomEnum getMyEnum() {
return myEnum;
}
public void setMyEnum(String enumName) {
this.myEnum = CustomEnum.valueOf(enumName);
}
}

Resources