How to convert 2 DTO to 1 DTO mapstruct - spring

How to convert TestDTO and QuestionDTO to PageTestDTO using mapstruct
I understand that this can be done quickly manually, but I would like to know this method
PageTestDTO
#NoArgsConstructor
#AllArgsConstructor
#Getter
#Setter
public class PageTestDTO {
private List<TestDTO> testDTOList;
private List<QuestionDTO> questionDTOList;
private Pageable pageable;
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
public static class Pageable{
private Integer totalPages;
private Long totalElements;
private Integer number;
}
TestDTO
#NoArgsConstructor
#Getter
#Setter
public class TestDTO {
private Long id;
private String name;
private List<QuestionDTO> questionList;
public TestDTO(Long id, String name) {
this.id = id;
this.name = name;
}
QuestionDTO
#NoArgsConstructor
#Getter
#Setter
public class QuestionDTO {
private Long id;
private String question;
private List<AnswerDTO> answersList = new ArrayList<>();
public QuestionDTO(Long id, String question){
this.id = id;
this.question = question;
}

Related

Post Request with Enum and composite key

I'm working on an exercise where i have to create CRUD operations.
I have a User table, a Role table and a UserRole table where i have the primary keys of those two entities.
I also have a RoleEnum with roles that have to be assigned to the User.
The problem that i'm gettin is that every time I insert a new user is a 200ok response but the role returns null and so it doesn't add it to the UserRole table as well.
I need help in solving the problem.
User Entity
#Data
#Entity
#NoArgsConstructor
#AllArgsConstructor
#Table(name = "utente")
public class Utente implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long matricola;
#Column(nullable = false)
private String nome;
#Column(nullable = false)
private String cognome;
#Column(nullable = false)
private String email;
#Column(name = "ruoloUtente", nullable = false)
#OneToMany(mappedBy = "matricolaUtente")
#JsonIgnore
private List<UtenteRuolo> ruoloUtente;
}
Role Entity
#Data
#Entity
#NoArgsConstructor
#AllArgsConstructor
#Table(name = "ruolo")
public class Ruolo implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "tipo_ruolo")
private String nome;
#Column(name = "utente_ruolo")
#OneToMany(mappedBy = "nomeRuolo")
private Set<UtenteRuolo> utenteRuolo;
}
UserRole class
#Data
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "utente_ruolo")
public class UtenteRuolo implements Serializable {
#EmbeddedId
private UtenteRuoloId utenteRuoloId;
#ManyToOne
#MapsId("matricola")
#JoinColumn(name = "matricola_utente", nullable = false)
private Utente matricolaUtente;
#ManyToOne
#MapsId("id")
#JoinColumn(name = "nome_ruolo", nullable = false)
private Ruolo nomeRuolo;
}
UserRoleId class
#Embeddable
#Data
#EqualsAndHashCode
#AllArgsConstructor
#NoArgsConstructor
public class UtenteRuoloId implements Serializable {
#Column(name = "matricola")
private Long matricola;
#Column(name = "id")
private Long id;
}
RoleEnum class
public enum RuoliEnum {
#JsonProperty
REFERENTE("REFERENTE"),
CONSULTATORE("CONSULTATORE"),
APPROVATORE("APPROVATORE");
#JsonProperty
private String value;
RuoliEnum(String value) { this.value = value; }
#JsonCreator
public static RuoliEnum fromValue(String text) {
for (RuoliEnum ruoli: RuoliEnum.values()) {
if (String.valueOf(ruoli.value).equalsIgnoreCase(text.trim())) {
return ruoli;
}
}
return null;
}
}
I also have all DTO's and the UserDTO has the RoleEnum instead of the List of class UserRole.
UserService
#Service
public class UtenteService {
#Autowired
private UtenteRepository utenteRepository;
#Autowired
private UtenteMap utenteMap;
public UtenteDto addUtente(UtenteDto utente) {
Utente u = utenteMap.fromDtoToModel(utente);
if(u != null) {
return utenteMap.fromModelToDto(utenteRepository.save(u));
}
return null;
}
UserController
#RestController
#RequestMapping("utente")
public class UtenteController {
#Autowired
private UtenteService utenteService;
#PostMapping("/addUtente")
public ResponseEntity addUtente(#Nullable #RequestBody UtenteDto utente) {
if(utente != null) {
return ResponseEntity.ok(utenteService.addUtente(utente));
} else {
return ResponseEntity.badRequest().body("utente non inserito correttamente");
}
}
this is a postman insert example:
{
"matricola" : 11,
"nome" : "aaa",
"cognome" : "bb",
"email" : "eee#mail.com",
"ruolo" : "APPROVATORE"
}
and this is the postman response with 200ok status:
{
"matricola": 11,
"nome": "aaa",
"cognome": "bb",
"email": "eee#mail.com",
"ruolo": null
}
the code doesn't tell me about any kind of error and i need to keep the UserRole table because it's required for this kind of exercise.
I tried everything I could but since I never worked like this with enums and this kind of table relations I don't know what's missing to complete it.

Spring Data JPA separate createOn and updateOn

my auditing works pretty nice but need to change create listener in that way to obtain null values in first update.
#MappedSuperclass
#Getter
#Setter
#ToString
#EntityListeners(AuditingEntityListener.class)
public abstract class AbstractEntity{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Version
private int version;
#CreatedBy
private String createdBy;
#LastModifiedBy
private String updatedBy;
#CreatedDate
private LocalDateTime createdAt;
#LastModifiedDate
private LocalDateTime updatedAt;
}
#Entity
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#ToString
public class TestProfile extends AbstractEntity{
private String username;
}
Right now during create entity, the "updatedBy" and "updatedAt" is also fullfilled with duplicated values from "createdBy" and "createdAt". Should I change my default implementation to #PrePersist and #PreUpdate?
Here is my JpaConfig
#Configuration
#EnableJpaAuditing(auditorAwareRef = "auditorAware")
public class AuditingConfig`enter code here` {
#Bean
public AuditorAware<String> auditorAware() {
return () -> Optional.of(((UserDetails) SecurityContextHolder
.getContext().getAuthentication().getPrincipal()).getUsername());
}
}

RequestDto keep getting Null in Jpa

I'm trying to make invoice in my project.to make it, I need to POST all info that I already put in the DB. I'm trying to use #RequestBody using by requestDto but it keep getting null.
#Data
#Getter
public class InvoiceRequestDto {
private String note;
private AddressRequest addressRequest;
private BuyerRequest buyerRequest;
private SellerRequest sellerRequest;
private OrderRequest orderRequest;
other request in InvoiceRequestDto also look like this.
#Data
#Getter
public class BuyerRequest {
private String companyName;
private String email;
private String buyerManager;
private String buyerManagerNumber;
private String faxNumber;
this is service, I debugged in here and getting null from all requestDto in InvoiceRequestDto.
#Transactional
public Invoice postInvoice(InvoiceRequestDto invoiceRequestDto) {
try {
Buyer buyerPost = buyerRepository.findByBuyerManager(invoiceRequestDto.getBuyerRequest().getBuyerManager());
Seller sellerPost = sellerRepository.findBySellerManager(invoiceRequestDto.getSellerRequest().getSellerManager());
OrderItem orderPost = orderRepository.getByOrderNumber(invoiceRequestDto.getOrderRequest().getOrderNumber());
Invoice newInvoice = new Invoice(invoiceRequestDto.getNote(), orderPost, buyerPost, sellerPost);
Invoice saved = invoiceRepository.save(newInvoice);
return saved;
} catch (Exception e) {
e.printStackTrace();
return null;
}
this is controller.
#PostMapping("api/order/new")
public ResponseEntity<Long> postInvoice(#RequestBody InvoiceRequestDto invoiceRequestDto){
Long result = invoiceService.postInvoice(invoiceRequestDto).getId();
return ResponseEntity.ok(result);
this is Invoice Entity.
#Getter
#Entity
public class Invoice extends BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "invoice_id")
private Long id;
#ManyToOne
#JoinColumn(name = "buyer_id")
private Buyer buyer;
#ManyToOne
#JoinColumn(name = "seller_id")
private Seller seller;
#ManyToOne
#JoinColumn(name = "product_id")
private Product product;
#ManyToOne
#JoinColumn(name = "delivery_id")
private Delivery delivery;
#ManyToOne
#JoinColumn(name = "orderItem_id")
private OrderItem orderItem;
private boolean finalized;
private String note;
#Builder
public Invoice(String note, OrderItem orderPost, Buyer buyerPost, Seller sellerPost){
this.note = note;
this.orderItem = orderPost;
this.buyer = buyerPost;
this.seller = sellerPost;
}
Instead of using external class like this
#Data
#Getter
public class BuyerRequest {
private String companyName;
private String email;
private String buyerManager;
private String buyerManagerNumber;
private String faxNumber;
Try to use inner static classes in your InvoiceRequestDto like below and try again.
#Data
#AllArgsConstructor
#NoArgsConstructor
public class InvoiceRequestDto {
private String note;
private AddressRequest addressRequest;
private BuyerRequest buyerRequest;
private SellerRequest sellerRequest;
private OrderRequest orderRequest;
#Data
#AllArgsConstructor
#NoArgsConstructor
public static class AddressRequest {
// neccessary fields
}
#Data
#AllArgsConstructor
#NoArgsConstructor
public static class BuyerRequest {
// neccessary fields
}
#Data
#AllArgsConstructor
#NoArgsConstructor
public static class SellerRequest {
// neccessary fields
}
#Data
#AllArgsConstructor
#NoArgsConstructor
public static class OrderRequest {
// neccessary fields
}
}

Why is my mapped DTO List null? What is the best way to map and persist Child Lists?

I have a simple problem - but I think "I am standing on the tube".
I have a spring boot rest api with JPA, Modelmapper, Entities and DTOs.
But the mapping doesn't work.
Entities:
#Getter
#Setter
#MappedSuperclass
public class AbstractEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
#Getter
#Setter
#Entity(name = "contacts")
public class Contact extends AbstractEntity {
#NotBlank
private String firstName;
#NotBlank
private String lastName;
#Valid
#OneToMany(mappedBy = "contact", cascade = CascadeType.ALL, orphanRemoval = true)
private List<PhoneNumber> phoneNumberList;
}
#Getter
#Setter
#Entity(name = "phone_numbers")
public class PhoneNumber extends AbstractEntity {
#NotBlank
private String label;
#NotBlank
private String number;
#ManyToOne
#JoinColumn(name = "contact_id", referencedColumnName = "id")
#Setter(value = AccessLevel.NONE)
private Contact contact;
}
The DTOs:
#Getter
#Setter
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class ContactDTO {
private Long id;
private String firstName;
private String lastName;
List<PhoneNumberDTO> phoneNumberDTOList = new ArrayList<>();
}
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class PhoneNumberDTO {
private Long id;
private String label;
private String number;
}
My ModelMapperConfig:
#Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(AccessLevel.PRIVATE);
return modelMapper;
}
Repo:
public interface ContactRepository extends JpaRepository<Contact, Long{
}
Service (only the create method):
#Override
public ContactDTO createOne(ContactDTO contactDTO) {
Contact contact = modelMapper.map(contactDTO, Contact.class);
contactRepository.save(contact);
return contactDTO;
}
Is this the correct way to persist the Contact with its multiple phonenumbers?
And how can I create a simple mapping?
If i want to persist it, there comes an error:
Column 'contact_id' cannot be null

How to create sub resource with #RestRepositoryResource

We are working on a Spring Boot API.
We use #RestRepositoryResource annotation to generate endpoints.
#RepositoryRestResource(collectionResourceRel = "datarow", path = "datarow")
public interface DataRowRepository extends MongoRepository<DataRow, String>
}
In the previous example, we create a endpoint /api/datarow.
But we want to change resource path like this : /api/dataset/{id}/datarow. Is it possible with #RestRepositoryResource ?
See our model :
public class Datarow {
#Getter #Setter
private String id;
#Getter #Setter
private String datasetId;
#Getter #Setter
private Address address;
}
public class Dataset {
#Getter #Setter
private String id;
#Getter #Setter
private String name;
#Getter #Setter
private String filePath;
#Getter #Setter
private Date uploadDate;
}
See our repository :
#RepositoryRestResource(collectionResourceRel = "datarow", path = "datarow")
public interface DatarowRepository extends MongoRepository<Datarow, String> {
}
Thanks !

Resources