Spring Data Elastic Search : Repository findById Returning Not Found - spring

I am trying to setup a Spring Data Elastic Project. Here is my document...
{
"_index": "_idx1",
"_type": "_doc",
"_id": "440986688",
"_version": 9,
"_seq_no": 22175768,
"_primary_term": 25,
"found": true,
"_source": {
"dto": {
"evidencePath": "path",
"disclosurePath": "dPath",
"allowedCommands": [],
"actionText": "View - No action required",
"closedNokReason": null,
"closedNokComment": null,
"evidenceDocuments": [
{
"identifier": "7355580062",
"purpose": "COMMENT",
"description": "Task submitted",
"date": "2022/01/20 15:57:54",
"dateISO": null,
"provider": "Andrew",
"contentStreamMimeType": "v_comment",
"contentStreamLength": 14,
"fileName": "comment_29160_1893869507.txt",
"downloader": null,
"downloaded": null,
"wfdId": null,
"draft": false,
"controlOwner": null,
"controlEmail": null,
"controlProvisionId": null,
"type": "COMMENT"
}
],
"referenceDocuments": [
],
"message": null,
"type": "Dash",
"owner": "Andrew "
},
"id": 440986688,
"guiKey": "ap_apr_review_",
"followupAllowed": false,
"lastFollowup": null,
"consolidatedMetric": "Review",
"riskCategory": "Unassigned",
"disclosureData": true,
"disclosureDataActionText": "This is submitted. ",
"disclosureDataRows": [
{
"identifier": "4290018.00001",
"evProvProcessId": "440986688",
"usPersonEmployee": "Yes"
}
],
"disclosureDataEnrichments": true,
"ftdDelegateEmails": null,
"ftdOwnerEmails": null,
"reviewRequired": true,
"gateDate": 1645814815901,
"wspNumber": null,
"wspBook": null,
"wspSubBook": null,
"other": {},
"actionType": "FYI",
"actionTypes": [],
"allowedActions": [],
"action": false,
"actionText": "View - No action required",
"wfdId": 111964,
"message": ""
}
}
Here is my ma document mapping...
#Document(indexName = "_idx1")
public class TaskBean {
#Field(type = FieldType.Nested)
private DtoBean dto;
#Id
private String id;
#Field(type = FieldType.Text)
private String wsp;
#Field(type = FieldType.Text)
private String wspId;
#Field(type = FieldType.Text)
private String control;
#Field(type = FieldType.Text)
private String evProvComment;
#Field(type = FieldType.Text)
private String reason;
#Field(type = FieldType.Text)
private String delegate;
#Field(type = FieldType.Text)
private String delegateEmail;
#Field(type = FieldType.Text)
private String delegationType;
#Field(type = FieldType.Text)
private String delegateId;
#Field(type = FieldType.Text)
private String owner;
#Field(type = FieldType.Text)
private String ownerEmail;
#Field(type = FieldType.Text)
private String ownerUBR;
#Field(type = FieldType.Text)
private List<String> wspApplicability;
#Field(type = FieldType.Text)
private String commit;
#Field(type = FieldType.Text)
private String templateFiles;
#Field(type = FieldType.Text)
private String alertText;
#Field(type = FieldType.Text)
private String guiKey;
#Field(type = FieldType.Text)
private String followupAllowed;
#Field(type = FieldType.Text)
private String lastFollowup;
#Field(type = FieldType.Text)
private String consolidatedMetric;
#Field(type = FieldType.Text)
private String riskCategory;
#Field(type = FieldType.Text)
private String disclosureData;
#Field(type = FieldType.Text)
private String disclosureDataActionText;
#Field(type = FieldType.Nested)
private List<DisclosureRow> disclosureDataRows;
#Field(type = FieldType.Text)
private String disclosureDataEnrichments;
#Field(type = FieldType.Text)
private String ftdDelegateEmails;
#Field(type = FieldType.Text)
private String ftdOwnerEmails;
#Field(type = FieldType.Text)
private String reviewRequired;
#Field(type = FieldType.Text)
private String gateDate;
#Field(type = FieldType.Text)
private String wspNumber;
#Field(type = FieldType.Text)
private String wspBook;
#Field(type = FieldType.Text)
private String wspSubBook;
#Field(type = FieldType.Text)
private String other;
#Field(type = FieldType.Text)
private String actionType;
#Field(type = FieldType.Text)
private List<String> actionTypes;
#Field(type = FieldType.Text)
private List<String> allowedActions;
#Field(type = FieldType.Text)
private String action;
#Field(type = FieldType.Text)
private String actionText;
#Field(type = FieldType.Text)
private String wfdId;
#Field(type = FieldType.Text)
private String message;
}
My configuration class....
#Configuration
#EnableElasticsearchRepositories(basePackages = "com.mi.repository")
public class ReactiveRestClientConfig {
#Value("${elasticsearch.host}")
private String EsHost;
#Value("${elasticsearch.port}")
private int EsPort;
#Value("${elasticsearch.user}")
private String user;
#Value("${elasticsearch.password}")
private String password;
#Bean
public RestHighLevelClient client() {
//System.out.println(EsHost);
InetSocketAddress proxyAddress = null;
try {
proxyAddress = new InetSocketAddress( InetAddress.getByName(EsHost), EsPort) ;
}catch(Exception e) {
}
ClientConfiguration clientConfiguration
= ClientConfiguration.builder()
.connectedTo(proxyAddress)
.withConnectTimeout(Duration.ofSeconds(50))
.withSocketTimeout(Duration.ofSeconds(50))
.withBasicAuth(EsUser, EsPassword)
.build();
return RestClients.create(clientConfiguration).rest();
}
#Bean
public ElasticsearchOperations elasticsearchTemplate() {
return new ElasticsearchRestTemplate(client());
}
}
And finally, Service class...
#Component
public class TaskService {
#Autowired
private TaskBeanRepository taskBeanRepository;
public TaskBean findById(String id) {
Optional<TaskBean> taskBean = taskBeanRepository.findById(id);
if(taskBean.isPresent()) {
return taskBean.get();
}
return null;
}
}
I have created a controller and calling this method through REST. Even after passing correct Id 440986688 to this method it is returning 404 not found. Any issue with my mapping?

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 do a ManyToMany relationship insert

I am studying spring boot data using this API SWAPI, I did almost things but now I dont know how to map the relationship about two lists, above you can see my code and entities.
Entity Film
#Data
#Entity
public class Film extends Persistent<Long> {
private String title;
#JsonProperty(value = "episode_id")
private int episodeId;
#JsonProperty(value = "opening_crawl")
#Column(columnDefinition = "CLOB")
private String openingCrawl;
private String director;
private String producer;
#JsonDeserialize(converter = StringToLocalDateConverter.class)
#JsonProperty(value = "release_date")
private LocalDate releaseDate;
#JsonDeserialize(converter = ApiURLToEntitiesConverter.class)
#ManyToMany(mappedBy = "films")
private List<Person> characters;
#JsonDeserialize(converter = StringToLocalDateTimeConverter.class)
private LocalDateTime created;
#JsonDeserialize(converter = StringToLocalDateTimeConverter.class)
private LocalDateTime edited;
private String url;
}
Entity Person
#Data
#Entity
public class Person extends Persistent<Long> {
private String name;
private String height;
private String mass;
#JsonProperty(value = "hair_color")
private String hairColor;
#JsonProperty(value = "skin_color")
private String skinColor;
#JsonProperty(value = "eye_color")
private String eyeColor;
#JsonProperty(value = "birth_year")
private String birthYear;
private String gender;
#JsonDeserialize(converter = ApiURLToEntityConverter.class)
#JoinColumn(name = "planet_id", foreignKey = #javax.persistence.ForeignKey(name = "none"))
#OneToOne(optional = true)
private Planet homeworld;
#JsonDeserialize(converter = ApiURLToEntitiesConverter.class)
#ManyToMany
#JoinTable(
name = "film_person",
joinColumns = #JoinColumn(name = "film_fk", referencedColumnName = "id", nullable = true),
inverseJoinColumns = #JoinColumn(name = "person_fk", referencedColumnName = "id", nullable = true))
private List<Film> films;
#JsonDeserialize(converter = StringToLocalDateTimeConverter.class)
private LocalDateTime created;
#JsonDeserialize(converter = StringToLocalDateTimeConverter.class)
private LocalDateTime edited;
private String url;
}
I am trying to use the spring jpa method to saveAll
#Override
public List<T> insertAll(List<T> entities) {
for (Persistent entity : entities) {
Set<ConstraintViolation<Persistent>> violations = validator.validate(entity);
if (violations != null && !violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}
return repository.saveAll(entities);
}
Converter Method
#Override
public List convert(List<String> s) {
if (s == null || s.isEmpty()) {
return null;
}
List objetos = new LinkedList();
for (String url : s) {
if (url.contains("people")) {
objetos.add(Util.getPerson(url));
}
if (url.contains("planets")) {
objetos.add(Util.getPlanet(url));
}
if (url.contains("starships")) {
objetos.add(Util.getStarship(url));
}
if (url.contains("vehicles")) {
objetos.add(Util.getVehicle(url));
}
if (url.contains("species")) {
objetos.add(Util.getSpecie(url));
}
}
return objetos;
}
}
Util method
public static Person getPerson(String characterApiUrl) {
if (characterApiUrl == null || characterApiUrl.isEmpty()) {
return null;
}
Person person = new Person();
person.setId(StringUtil.getIdEntity(characterApiUrl, "people/"));
return person;
}
The relationship table is being created but no populated

Hibernate | Mapping data type "byte" with enum attribute converter not working - error: No Dialect mapping for JDBC type: 277630005

Using spring boot version: 2.2.6.RELEASE | Database: SqlServer 2008 | org.hibernate.dialect.SQLServer2008Dialect.
When using a converter for mapping the enumeration of a column of the type "TINYINT" that would be referring to "Byte" in java is presenting the following error:
No Dialect mapping for JDBC type: 277630005, when hibernate ddl for initial db.
However, when doing the direct mapping as Byte without using enumeration, it works correctly.
Converter:
#Converter
public class CharacterClassConverter implements AttributeConverter<CharacterClassIndicator, Byte> {
#Override
public Byte convertToDatabaseColumn(CharacterClassIndicator characterClassIndicator) {
return characterClassIndicator != null ? characterClassIndicator.getCode() : null;
}
#Override
public CharacterClassIndicator convertToEntityAttribute(Byte code) {
return Stream.of(CharacterClassIndicator.values())
.filter(value -> value.getCode().equals(code))
.findFirst()
.orElseThrow(UnsupportedOperationException::new);
}
}
Enum:
public enum CharacterClassIndicator {
DARK_WIZARD(0, "DK", "Dark Wizard"),
SOUL_MASTER(1, "SM", "Soul Master"),
GRAND_MASTER(2, "GM", "Grand Master"),
DARK_KNIGHT(16, "DK", "Dark Knight"),
BLADE_KNIGHT(17, "BK", "Blade Knight"),
BLADE_MASTER(18, "BM", "Blade Master"),
FAIRY_ELF(32, "FE", "Fairy Elf"),
MOUSE_ELF(33, "ME", "Mouse Elf"),
HIGH_ELF(34, "HE", "High Elf"),
DARK_LORD(48, "DL", "Dark Lord"),
LORD_EMPEROR(49, "LE", "Lord Emperor"),
MAGIC_GLADIATOR(64, "MG", "Magic Gladiator"),
DUEL_MASTER(65, "DM", "Duel Master");
private final Byte code;
private final String initials;
private final String name;
CharacterClassIndicator(Integer code, String initials, String name) {
this.code = code.byteValue();
this.initials = initials;
this.name = name;
}
public Byte getCode() {
return code;
}
public String getInitials() {
return initials;
}
public String getName() {
return name;
}
}
The entity code:
#Entity
#Table(name = "Character")
public class Character {
#Id
#Column(name = "AccountID")
private String id;
#Column(name = "Name")
private String name;
#Column(name = "Class")
#Convert(converter = CharacterClassConverter.class) // if remove this line and change type to Byte, works correctly
private CharacterClassIndicator characterClass;
#Column(name = "cLevel")
private Integer level;
#Column(name = "Strength")
private Short strenght;
#Column(name = "Dexterity")
private Short dexterity;
#Column(name = "Vitality")
private Short vitality;
#Column(name = "Energy")
private Short energy;
#Column(name = "Resets")
private Integer resets;
.... gets and setters
}
Would anyone have an idea how to solve?
Use columnDefinition
#Column(name = "Class", columnDefinition = "TINYINT")

Cannot execute query in GraphQL

I'm trying to get into GraphQL and I followed a tutorial for a simple GraphQL + Spring + MySQL application, and I remade it for my own database. But when I try to execute my findAllDocuments query, I get this response in Postman:
"data": null,
"errors": [
{
"message": "Validation error of type FieldUndefined: Field 'findAllDocuments' in type 'query' is undefined # 'findAllDocuments'",
"locations": [
{
"line": 2,
"column": 5,
"sourceName": null
}
],
"description": "Field 'findAllDocuments' in type 'query' is undefined",
"validationErrorType": "FieldUndefined",
"queryPath": [
"findAllDocuments"
],
"errorType": "ValidationError",
"path": null,
"extensions": null
}
]
}
This is the entity I'm trying to get (it has some complex datatypes like Group or Media, that have similar implementation as Document class, I didn't include them to save space):
#Table(name = "documents")
public class Document {
#Id
#Column(name = "doc_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "title")
private String title;
#Column(name = "data")
private String data;
#Column(name = "data_asc")
private String dataAsc;
#Column(name = "external_link")
private String externalLink;
#OneToMany
#JoinColumn(name = "doc_id")
private List<DocumentForum> forums;
#Column(name = "navbar")
private String navbar;
#Column(name = "date_created")
private Date dateCreated;
#Column(name = "publish_start")
private Date publishStart;
#Column(name = "publish_end")
private Date publishEnd;
#OneToOne
#JoinColumn(name = "user_id")
private UserDetails author;
#OneToOne
#JoinColumn(name = "group_id")
private Group group;
#OneToMany(mappedBy = "document")
private List<Media> media;
#Column(name = "temp_id")
private Integer tempId;
#Column(name = "views_total")
private int viewsTotal;
#Column(name = "views_month")
private int viewsMonth;
#Column(name = "searchable")
private boolean searchable;
#Column(name = "available")
private boolean available;
#Column(name = "cacheable")
private boolean cacheable;
#Column(name = "file_name")
private String fileName;
#Column(name = "file_change")
private Date fileChange;
#Column(name = "sort_priority")
private int sortPriority;
#Column(name = "header_doc_id")
private int headerDocId;
#Column(name = "menu_doc_id")
private int menuDocId;
#Column(name = "footer_doc_id")
private int footerDocId;
#Column(name = "password_protected")
private String passwordProtected;
#Column(name = "html_head")
private String htmlHead;
#Column(name = "perex_place")
private String perexPlace;
#Column(name = "perex_image")
private String perexImage;
#Column(name = "perex_group")
private String perexGroup;
#Column(name = "show_in_menu")
private boolean showInMenu;
#Column(name = "event_date")
private Date eventDate;
#Column(name = "virtual_path")
private String virtualPath;
#Column(name = "sync_id")
private int syncId;
#Column(name = "sync_status")
private int syncStatus;
#Column(name = "logon_page_doc_id")
private int logonPageDocId;
#Column(name = "right_menu_doc_id")
private int rightMenuDocId;
#Column(name = "field_a")
private String fieldA;
#Column(name = "field_b")
private String fieldB;
#Column(name = "field_c")
private String fieldC;
#Column(name = "field_d")
private String fieldD;
#Column(name = "field_e")
private String fieldE;
#Column(name = "field_f")
private String fieldF;
#Column(name = "field_g")
private String fieldG;
#Column(name = "field_h")
private String fieldH;
#Column(name = "field_i")
private String fieldI;
#Column(name = "field_j")
private String fieldJ;
#Column(name = "field_k")
private String fieldK;
#Column(name = "field_l")
private String fieldL;
#Column(name = "disable_after_end")
private boolean disableAfterEnd;
#Column(name = "forum_count")
private int forumCount;
#Column(name = "field_m")
private String fieldM;
#Column(name = "field_n")
private String fieldN;
#Column(name = "field_o")
private String fieldO;
#Column(name = "field_p")
private String fieldP;
#Column(name = "field_q")
private String fieldQ;
#Column(name = "field_r")
private String fieldR;
#Column(name = "field_s")
private String fieldS;
#Column(name = "field_t")
private String fieldT;
#Column(name = "require_ssl")
private boolean requireSsl;
#Column(name = "root_group_l1")
private Integer rootGroupL1;
#Column(name = "root_group_l2")
private Integer rootGroupL2;
#Column(name = "root_group_l3")
private Integer rootGroupL3;
*********SETTER AND GETTERS*********
This is the .graphqls file for Document class:
scalar Date
type Document{
id: Int!
title: String!
data: String!
dataAsc: String!
externalLink: String!
forums: [DocumentForum]!
navbar: String!
dateCreated: Date!
publishStart: Date
publishEnd: Date
author: UserDetails!
group: Group!
media: [Media]!
tempId: Int!
viewsTotal: Int!
viewsMonth: Int!
searchable: Boolean!
available: Boolean!
cacheable: Boolean!
fileName: String
fileChange: Date
sortPriority: Int!
headerDocId: Int!
menuDocId: Int!
footerDocId: Int!
passwordProtected: String
htmlHead: String!
perexPlace: String!
perexImage: String!
perexGroup: String
showInMenu: Boolean!
eventDate: Date
virtualPath: String!
syncId: Int!
syncStatus: Int!
logonPageDocId: Int!
rightMenuDocId: Int!
fieldA: String!
fieldB: String!
fieldC: String!
fieldD: String!
fieldE: String!
fieldF: String!
fieldG: String!
fieldH: String!
fieldI: String!
fieldJ: String!
fieldK: String!
fieldL: String!
disableAfterEnd: Boolean!
forumCount: Int!
fieldM: String!
fieldN: String!
fieldO: String!
fieldP: String!
fieldQ: String!
fieldR: String!
fieldS: String!
fieldT: String!
requireSsl: Boolean!
rootGroupL1: Int
rootGroupL2: Int
rootGroupL3: Int
}
type Query {
findAllDocuments: [Document]!
}
This is the Query resolver class:
public class Query implements GraphQLQueryResolver {
private final DocumentRepository documentRepository;
private final DocumentForumRepository documentForumRepository;
private final GroupRepository groupRepository;
private final MediaRepository mediaRepository;
private final UserDetailsRepository userDetailsRepository;
#Autowired
public Query(DocumentRepository documentRepository,
DocumentForumRepository documentForumRepository,
GroupRepository groupRepository,
MediaRepository mediaRepository,
UserDetailsRepository userDetailsRepository){
this.documentRepository = documentRepository;
this.documentForumRepository = documentForumRepository;
this.groupRepository = groupRepository;
this.mediaRepository = mediaRepository;
this.userDetailsRepository = userDetailsRepository;
}
public Iterable<Document> findAllDocuments(){
return documentRepository.findAll();
}
public Iterable<DocumentForum> findAllDocumentForums(){
return documentForumRepository.findAll();
}
public Iterable<Group> findAllGroups(){
return groupRepository.findAll();
}
public Iterable<Media> findAllMedia(){
return mediaRepository.findAll();
}
}
And this is the DocumentResolver class:
public class DocumentResolver implements GraphQLResolver<Document> {
private DocumentForumRepository documentForumRepository;
private GroupRepository groupRepository;
private MediaRepository mediaRepository;
private UserDetailsRepository userDetailsRepository;
#Autowired
public DocumentResolver(DocumentForumRepository documentForumRepository,
GroupRepository groupRepository,
MediaRepository mediaRepository,
UserDetailsRepository userDetailsRepository){
this.documentForumRepository = documentForumRepository;
this.groupRepository = groupRepository;
this.mediaRepository = mediaRepository;
this.userDetailsRepository = userDetailsRepository;
}
public List<DocumentForum> getForums(Document document){
return documentForumRepository.findAllById(document.getId());
}
public UserDetails getAuthor(Document document) throws ObjectNotFoundException {
Optional<UserDetails> optionalUserDetails = userDetailsRepository.findById(document.getId());
if(optionalUserDetails.isPresent()){
return optionalUserDetails.get();
}else{
throw new ObjectNotFoundException();
}
}
public Group getGroup(Document document) throws ObjectNotFoundException {
Optional<Group> optionalGroup = groupRepository.findById(document.getId());
if(optionalGroup.isPresent()){
return optionalGroup.get();
}else{
throw new ObjectNotFoundException();
}
}
public List<Media> getMedia(Document document) {
return mediaRepository.findAllById(document.getId());
}
}
The query I try to send from Postman:
{
findAllDocuments{
id
title
data
}
}
Everything works in my smaller project and I can't pinpoint what's the problem here. If anything else is needed, please let me know and I'll provide it. Thank you.

Persisting data with JPA with existing datas

I want to persist an object like this one :
{
"paymentMode": "CREDIT CARD",
"totalAmount": 158.0,
"orderProducts": [
{
"productKeyId": "HycaR7sPeecIMZEewanuK0jzPo7S33",
"name": "Cornish crab salad, brown crab mayonnaise, toasted muffin",
"price": 20.0,
"qty": 1,
"imgPath": "pathImage",
"category": {
"categoryKeyId": "23ume70Fu6yqyGUWfQkW110P4ko3gZ",
"name": "Starter"
}
},...
],
"seller": {
"userKeyId": "qmNR5g2TD8Ja5KvA1DCQWzYj55nvbP",
"firstName": "David",
"lastName": "Vera",
"email": "david.vera#9online.fr",
"addresses": [
{
"addressKeyId": "2t7x0bFgP5B9Qb2ymnLL5aPZVwMFhJ",
"city": "Vancouver",
"country": "Canada",
"streetName": "123 street name",
"postalCode": "ABCCBA",
"type": "billing",
},...
]
},
"createdAt": "2019-10-22T09:48:06.000+0000"
}
Some object are already stored in Database such as seller, addresses, products and product category.
I created : Orders tables
#Entity
#Table(name="orders")
#Getter #Setter
public class OrderEntity implements Serializable {
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
#Column(nullable = false, unique = true)
private String orderKeyId;
// A sale belong to one seller
#ManyToOne(fetch = FetchType.LAZY)
private UserEntity seller;
private String paymentMode;
private double totalAmount;
#OneToMany(mappedBy = "pk.order")
#Valid
private List<OrderProductEntity> orderProducts;
}
An order_product table (pivot table):
#Entity
#Table(name="order_product")
#Getter #Setter
public class OrderProductEntity {
#EmbeddedId
#JsonIgnore
private OrderProductPK pk;
#Column(nullable = false)
private Integer qty;
// default constructor
public OrderProductEntity() {
super();
}
public OrderProductEntity(OrderEntity order, ProductEntity product, Integer quantity) {
pk = new OrderProductPK();
pk.setOrder(order);
pk.setProduct(product);
this.qty = quantity;
}
#Transient
public ProductEntity getProduct() {
return this.pk.getProduct();
}
...
}
And a product table
#Entity
#Table(name="products")
#Getter #Setter
public class ProductEntity implements Serializable {
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
#Column(nullable = false)
private String productKeyId;
// many to one relationship with category
#ManyToOne
#JoinColumn(name = "category_id")
private CategoryEntity category;
#Column(nullable = false)
private String name;
#Column(nullable = false)
private double price;
#Column(nullable = false)
private int qty;
private String imgPath;
#JsonManagedReference
#OneToMany(mappedBy = "pk.product", fetch = FetchType.EAGER)
#Valid
private List<OrderProductEntity> orderProducts;
}
The userEntity class :
#Entity
#Table(name = "users")
#Getter #Setter
public class UserEntity implements Serializable {
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
#Column(nullable = false, unique = true)
private String userKeyId;
#Column(nullable = false, length = 50)
private String firstName;
#Column(nullable = false, length = 50)
private String lastName;
#Column(nullable = false, length = 120, unique = true)
private String email;
#Column(nullable = false)
private String encryptedPassword;
private String emailVerificationToken;
// column definition do not work for all database engine. So set the value to false is the same
// #Column(nullable = false, columnDefinition = "boolean default false")
#Column(nullable = false)
private Boolean emailVerificationStatus = false;
// One user can have Many Addresses
#OneToMany(mappedBy = "userDetails", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JsonManagedReference
private List<AddressEntity> addresses;
}
And finally the embedded class :
#Embeddable
#Getter #Setter
#ToString
public class OrderProductPK implements Serializable {
private static final long serialVersionUID = 476151177562655457L;
#ManyToOne(optional = false, fetch = FetchType.LAZY)
#JoinColumn(name = "order_id")
private OrderEntity order;
#ManyToOne(optional = false, fetch = FetchType.LAZY)
#JoinColumn(name = "product_id")
private ProductEntity product;
...
}
I created a controller method to persist orders in a MySQL database:
public OrderRest createOrder(#RequestBody OrderRequestModel orderRequestModel) throws Exception {
OrderRest returnValue = new OrderRest();
ModelMapper modelMapper = new ModelMapper();
OrderDto orderDto = modelMapper.map(orderRequestModel, OrderDto.class);
OrderDto createdOrder = orderService.createOrder(orderDto);
returnValue = modelMapper.map(createdOrder, OrderRest.class);
// 5. Return the expected object
return returnValue;
}
I have an orderDTO object that contains several fields (including ID).
public class OrderDto implements Serializable {
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
private Long id;
private String orderKeyId;
private String paymentMode;
private double totalAmount;
private List<ProductDto> orderProducts;
private UserDto seller;
private Date createdAt;
}
My productDTO object
public class ProductDto implements Serializable {
// ommit this member and do not generate getter / setter
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
private Long id;
private String productKeyId;
private String name;
private double price;
private int qty;
private String imgPath;
private CategoryDto category = new CategoryDto();
}
The UserDto :
#Getter #Setter
#ToString
public class UserDto implements Serializable {
// ommit this member and do not generate getter / setter
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
private long id;
private String userKeyId;
private String firstName;
private String lastName;
private String email;
private String password;
private String encryptedPassword;
private String emailVerificationToken;
private Boolean emailVerificationStatus = false;
private List<AddressDto> addresses;
// private List<RoleDto> roles;
}
the controller is calling my service layer :
#Override
public OrderDto createOrder(OrderDto orderDto) {
// create a new order
ModelMapper modelMapper = new ModelMapper();
OrderEntity orderEntity = modelMapper.map(orderDto, OrderEntity.class);
String orderKeyId = utils.generateOrderKeyId(30);
orderEntity.setOrderKeyId(orderKeyId);
orderEntity.setCreatedAt(orderDto.getCreatedAt());
orderEntity.setPaymentMode(orderDto.getPaymentMode());
orderEntity.setTotalAmount(orderDto.getTotalAmount());
// set the seller
UserEntity userEntity = modelMapper.map(orderDto.getSeller(), UserEntity.class);
orderEntity.setSeller(userEntity);
List<OrderProductEntity> orderProductEntities = new ArrayList<>();
// set the products
for (int i = 0; i < orderDto.getOrderProducts().size(); i++) {
ProductDto productDto = orderDto.getOrderProducts().get(i);
OrderProductEntity orderProductEntity = modelMapper.map(orderDto.getOrderProducts().get(i), OrderProductEntity.class);
orderProductEntities.add(orderProductEntity);
orderDto.getOrderProducts().set(i, productDto);
}
orderEntity.setOrderProducts(orderProductEntities);
OrderEntity storedOrder = orderRepository.save(orderEntity);
OrderDto returnValue = modelMapper.map(storedOrder, OrderDto.class);
return returnValue;
}
I have 3 issues :
I save the order in the database but the seller is not persisted
In the order product table datas are not persisted.
And i obtain an error message in my rest response :
"trace": "org.modelmapper.MappingException: ModelMapper mapping errors: Converter org.modelmapper.internal.converter.CollectionConverter#685b36d6 failed to convert java.util.List to java.util.List.error...

Resources