I have one stackOverflow error with relation OneToMany - spring

I have one stackOverflowerror, between two entities, one entities is client, and other's is annonce, annonce, having one author client, with relation entities list column join...
If i asking for list of client, the stack over coming with listing from annonce and relist altime in annonce with author, and that's is circulary...How to avoid that's and keep one listing form annonce by each client ?...
Client:
#Entity
#Table(name = "client")
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#Builder
public class Client implements UserDetails {
#Id
#GeneratedValue(generator = "UUID")
#GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
#Column(length = 16, name = "client_id", nullable = false, updatable = false)
private UUID client_id;
#Column(nullable = false)
private String username;
#Column(nullable = false)
private String firstname;
#Column(nullable = false)
private String lastname;
#Column(unique = true, nullable = false)
private String email;
#Column(nullable = false)
private String password;
#Column(nullable = false)
private String nationalite;
#Column(nullable = false)
private String rue;
#Column(nullable = false)
private String numero;
#Column(nullable = false)
private String cp;
#Column(nullable = false)
private String ville;
#Column(nullable = false)
private String pays;
#Column(nullable = true)
private String tel;
#Column(nullable = true)
private String imgType;
#Column(columnDefinition = "BLOB")
private byte[] profilePicture;
#Column(nullable = false)
private Boolean accountNonExpired;
#Column(nullable = false)
private Boolean accountNonLocked;
#Column(nullable = false)
private Boolean credentialsNonExpired;
#Column(nullable = false)
private Boolean enabled;
#ElementCollection(targetClass = Role.class, fetch = FetchType.EAGER)
#CollectionTable(name = "roles", joinColumns = #JoinColumn(name = "client_id"))
#Enumerated(EnumType.STRING)
private List<Role> roles;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "createdAt", insertable = false, columnDefinition = "DATETIME DEFAULT NOW()")
private Date createdAt;
#Column(name = "updateAt", nullable = true, columnDefinition = "DATETIME")
private Date updateAt;
#OneToMany(mappedBy = "cartFrom")
private Collection<Cart> cartList = new ArrayList<>();
Here-->
#OneToMany(mappedBy = "author", targetEntity = Annonce.class, orphanRemoval = true, cascade = CascadeType.ALL)
private Collection<Annonce> annonceList = new ArrayList<>();
#OneToMany(mappedBy = "conversationOf")
private Collection<Conversation> conversationList = new ArrayList<>();
#OneToMany(mappedBy = "orderedFrom")
private Collection<Ordered> orderedList = new ArrayList<>();
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
}
Annonce :
#Entity
#Table(name = "annonce")
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Builder
public class Annonce {
#Id
#GeneratedValue(generator = "UUID")
#GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
#Column(length = 16, name = "annonce_id", nullable = false, updatable = false)
private UUID annonce_id;
#Column(nullable = false)
private String name;
#Column(nullable = false)
private String title;
#Column(nullable = false)
private String description;
#Column(nullable = false)
private double price;
#Column(nullable = false)
private int quantity;
#Column(nullable = false)
private String salesTerms;
And here -->
#ManyToOne
#JoinColumn(name = "author_client_id")
private Client author;
#OneToOne(mappedBy = "annonce", fetch = FetchType.LAZY)
#JoinColumn(name = "annoncepicture_id", nullable = false)
private AnnoncePicture annoncepicture;
#ManyToMany
#JoinTable(name = "annonce_carts",
joinColumns = #JoinColumn(name = "annonce_id"),
inverseJoinColumns = #JoinColumn(name = "cart_id"))
private List<Cart> cartList = new ArrayList<>();
#OneToMany(mappedBy = "conversationOnAnnonce")
private Collection<Conversation> conversationList = new ArrayList<>();
#ManyToMany(mappedBy = "annonceList")
private List<Categorie> categorieList = new ArrayList<>();
#Enumerated
#ElementCollection(fetch = FetchType.LAZY)
private List<State> states;
#OneToMany(mappedBy = "noteFor")
private Collection<Note> noteList;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "createdAt", insertable = false, columnDefinition = "DATETIME DEFAULT NOW()")
private Date createdAt;
#Column(name = "updateAt", nullable = true, columnDefinition = "DATETIME")
private Date updateAt;
#Column(nullable = false)
private String categorie;
}
and than here is explain of problem...
"client_id": "58b80786-29d3-4ba9-b657-659cc32890a4",
"username": "shimshaker#gmail.com",
"firstname": "Christophe",
"lastname": "Cuypers",
"email": "shimshaker#gmail.com",
"password": "$2a$10$chNqhZ73r.kfEU/ZJ7M7XeU3Dck.q9XMRXUURc0ZnWMggJFRZat/m",
"nationalite": "Français",
"rue": "Rue de Beauraing",
"numero": "11B6",
"cp": "6920",
"ville": "Wellin",
"pays": "France",
"tel": "474/474.206",
"imgType": null,
"profilePicture": null,
"accountNonExpired": true,
"accountNonLocked": true,
"credentialsNonExpired": true,
"enabled": true,
"roles": [
"ADMIN",
"CLIENT",
"BUYER",
"MODERATOR"
],
"createdAt": "2022-04-11T12:01:59.000+00:00",
"updateAt": null,
"cartList": [],
"annonceList": [
{
"annonce_id": "a41a271c-f9bb-4644-894d-fc5245c2b054",
"name": "Ordinateur",
"title": "Vielle ordinateur",
"description": "Vielle ordinateur avec écran",
"price": 250.0,
"quantity": 1,
"salesTerms": "A prendre sur place",
"author": {
"client_id": "58b80786-29d3-4ba9-b657-659cc32890a4",
"username": "shimshaker#gmail.com",
"firstname": "Christophe",
"lastname": "Cuypers",
"email": "shimshaker#gmail.com",
"password": "$2a$10$chNqhZ73r.kfEU/ZJ7M7XeU3Dck.q9XMRXUURc0ZnWMggJFRZat/m",
"nationalite": "Français",
"rue": "Rue de Beauraing",
"numero": "11B6",
"cp": "6920",
"ville": "Wellin",
"pays": "France",
"tel": "474/474.206",
"imgType": null,
"profilePicture": null,
"accountNonExpired": true,
"accountNonLocked": true,
"credentialsNonExpired": true,
"enabled": true,
"roles": [
"ADMIN",
"CLIENT",
"BUYER",
"MODERATOR"
],
"createdAt": "2022-04-11T12:01:59.000+00:00",
"updateAt": null,
"cartList": [],
"annonceList": [
{
"annonce_id": "a41a271c-f9bb-4644-894d-fc5245c2b054",
"name": "Ordinateur",
"title": "Vielle ordinateur",
"description": "Vielle ordinateur avec écran",
"price": 250.0,
"quantity": 1,
"salesTerms": "A prendre sur place",
"author": {
"client_id": "58b80786-29d3-4ba9-b657-659cc32890a4",
"username": "shimshaker#gmail.com",
"firstname": "Christophe",
"lastname": "Cuypers",
"email": "shimshaker#gmail.com",
"password": "$2a$10$chNqhZ73r.kfEU/ZJ7M7XeU3Dck.q9XMRXUURc0ZnWMggJFRZat/m",
"nationalite": "Français",
"rue": "Rue de Beauraing",
"numero": "11B6",
"cp": "6920",
"ville": "Wellin",
"pays": "France",
"tel": "474/474.206",
"imgType": null,
"profilePicture": null,
"accountNonExpired": true,
"accountNonLocked": true,
"credentialsNonExpired": true,
"enabled": true,
"roles": [
"ADMIN",
"CLIENT",
"BUYER",
"MODERATOR"
],
"createdAt": "2022-04-11T12:01:59.000+00:00",
"updateAt": null,
"cartList": [],
"annonceList": [
{
"annonce_id": "a41a271c-f9bb-4644-894d-fc5245c2b054",
"name": "Ordinateur",
"title": "Vielle ordinateur",
"description": "Vielle ordinateur avec écran",
"price": 250.0,
"quantity": 1,
"salesTerms": "A prendre sur place",
"author": {
"client_id": "58b80786-29d3-4ba9-b657-659cc32890a4",
"username": "shimshaker#gmail.com",
"firstname": "Christophe",
"lastname": "Cuypers",
"email": "shimshaker#gmail.com",
"password": "$2a$10$chNqhZ73r.kfEU/ZJ7M7XeU3Dck.q9XMRXUURc0ZnWMggJFRZat/m",
"nationalite": "Français",
"rue": "Rue de Beauraing",
"numero": "11B6",
"cp": "6920",
"ville": "Wellin",
"pays": "France",
"tel": "474/474.206",
"imgType": null,
"profilePicture": null,
"accountNonExpired": true,
"accountNonLocked": true,
"credentialsNonExpired": true,
"enabled": true,
"roles": [
"ADMIN",
"CLIENT",
"BUYER",
"MODERATOR"
],
Thanks for your helps...Have great day...

Use FetchType.LAZY on the members which cause the circularity. Also, if you log the entity at any time or have any identity checks, also use #ToString.Exclude and #EqualsAndHashCode.Exclude (or, better, annotate the classes with #EqualsAndHashCode(onlyExplicitlyIncluded = true) and the id members with #EqualsAndHashCode.Include()).

Related

Deeply complicated JPA mapping producing tables with NULL values

Below are the entities (assume getters and setters):
#Entity
#Table(name="report_yearly")
public class AnalyticsReportYearly
{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long reportId;
private long viewId;
private long startYear;
private long endYear;
#JsonManagedReference
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name="data_id", referencedColumnName = "dataId")
private AnalyticsData data;
#JsonManagedReference
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name="column_header_id", referencedColumnName = "columnHeaderId")
private AnalyticsColumnHeader columnHeader;
}
#Entity
#Table(name="report_monthly")
public class AnalyticsReportMonthly
{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long reportId;
private long viewId;
private long startYear;
private long startMonth;
private long endYear;
private long endMonth;
#JsonManagedReference
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name="data_id", referencedColumnName = "dataId")
private AnalyticsData data;
#JsonManagedReference
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name="column_header_id", referencedColumnName = "columnHeaderId")
private AnalyticsColumnHeader columnHeader;
}
Above are the two top level entities. Either yearly or monthly reports are generated.
Below are the further nestings :
#Entity
#Table(name="report_data")
public class AnalyticsData
{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long dataId;
#JsonProperty
private boolean isDataGolden;
private long rowCount;
#JsonManagedReference
#OneToMany(mappedBy = "maximums",cascade=CascadeType.ALL)
private List<AnalyticsValue> maximums = new ArrayList<>();
#JsonManagedReference
#OneToMany(mappedBy = "minimums",cascade=CascadeType.ALL)
private List<AnalyticsValue> minimums = new ArrayList<>();
#JsonManagedReference
#OneToMany(mappedBy = "totals",cascade=CascadeType.ALL)
private List<AnalyticsValue> totals = new ArrayList<>();
#JsonManagedReference
#OneToMany(mappedBy = "analyticsData",cascade=CascadeType.ALL)
private List<AnalyticsRow> rows = new ArrayList<>();
#JsonBackReference
#OneToOne(mappedBy="data")
private AnalyticsReportMonthly analyticsReportMonthly;
#JsonBackReference
#OneToOne(mappedBy="data")
private AnalyticsReportYearly analyticsReportYearly;
getIsDataGolden() ; setIsDataGolden()
}
#Entity
#Table(name="report_column_header")
public class AnalyticsColumnHeader
{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long columnHeaderId;
#ElementCollection
#CollectionTable(name="column_header_dimensions",joinColumns=#JoinColumn(name="column_header_id"))
#Column(name="header_dimension")
private List<String> dimensions = new ArrayList<String>();
#JsonManagedReference
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "metric_header_id", referencedColumnName = "metricHeaderId")
private AnalyticsMetricHeader metricHeader;
#JsonBackReference
#OneToOne(mappedBy = "columnHeader")
private AnalyticsReportYearly analyticsReportYearly;
#JsonBackReference
#OneToOne(mappedBy = "columnHeader")
private AnalyticsReportMonthly analyticsReportMonthly;
}
Below are the further nested entities for AnalyticsData:
#Entity
#Table(name="report_data_values")
public class AnalyticsValue
{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long valueId;
#ElementCollection
#CollectionTable(name="data_values",joinColumns=#JoinColumn(name="data_value_id"))
#Column(name="data_value")
private List<String> values = new ArrayList<String>();
#JsonBackReference
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="data_maximums_id")
private AnalyticsData maximums;
#JsonBackReference
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="data_minimums_id")
private AnalyticsData minimums;
#JsonBackReference
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="data_totals_id")
private AnalyticsData totals;
#JsonBackReference
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="row_id")
private AnalyticsRow analyticsRow;
}
#Entity
#Table(name="report_row")
public class AnalyticsRow
{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long rowId;
#ElementCollection
#CollectionTable(name="row_dimensions",joinColumns=#JoinColumn(name="row_id"))
#Column(name="row_dimension")
private List<String> dimensions = new ArrayList<String>();
#JsonManagedReference
#OneToMany(mappedBy = "analyticsRow",cascade=CascadeType.ALL)
private List<AnalyticsValue> metrics = new ArrayList<>();
#JsonBackReference
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="data_id")
private AnalyticsData analyticsData;
}
Below the nesting for AnalyticsColumnHeader :
#Entity
#Table(name="report_metric_header")
public class AnalyticsMetricHeader
{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long metricHeaderId;
#JsonManagedReference
#OneToMany(mappedBy = "analyticsMetricHeader",cascade=CascadeType.ALL)
private List<AnalyticsMetricHeaderEntry> metricHeaderEntries = new ArrayList<>();
#JsonBackReference
#OneToOne(mappedBy = "metricHeader")
private AnalyticsColumnHeader analyticsColumnHeader;
}
#Entity
#Table(name="report_metric_header_entry")
public class AnalyticsMetricHeaderEntry
{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long metricHeaderEntryId;
private String name;
private String type;
#JsonBackReference
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="METRIC_HEADER_ID")
private AnalyticsMetricHeader analyticsMetricHeader;
}
All of the tables have data except 'report_data_values'(Entity:AnalyticsValue), where it has the value_id auto-generated values. But row_id,data_maximums_id,data_minimums_id,data_totals_id are all NULL.
Below is the JSON that I am supposed to store :
{
"columnHeader": {
"dimensions": [
"ga:userAgeBracket"
],
"metricHeader": {
"metricHeaderEntries": [
{
"name": "Users",
"type": "INTEGER"
},
{
"name": "New Users",
"type": "INTEGER"
},
{
"name": "Page Views",
"type": "INTEGER"
},
{
"name": "Sessions",
"type": "INTEGER"
},
{
"name": "Average Session Duration",
"type": "TIME"
},
{
"name": "Bounce Rate",
"type": "PERCENT"
}
]
}
},
"data": {
"isDataGolden": true,
"maximums": [
{
"values": [
"1864099",
"594855",
"13718093",
"6622035",
"228.37076740102023",
"75.14374842506706"
]
}
],
"minimums": [
{
"values": [
"297293",
"97265",
"2945414",
"1076230",
"110.43645338547087",
"58.1395240794254"
]
}
],
"rowCount": 6,
"rows": [
{
"dimensions": [
"18-24"
],
"metrics": [
{
"values": [
"899425",
"441934",
"3560704",
"2008022",
"110.43645338547087",
"75.14374842506706"
]
}
]
},
{
"dimensions": [
"25-34"
],
"metrics": [
{
"values": [
"1864099",
"594855",
"12278420",
"6622035",
"133.32916150397875",
"73.01240479701482"
]
}
]
},
{
"dimensions": [
"35-44"
],
"metrics": [
{
"values": [
"1465642",
"411498",
"13718093",
"6213080",
"173.1176128425837",
"65.26962472718844"
]
}
]
},
{
"dimensions": [
"45-54"
],
"metrics": [
{
"values": [
"1210565",
"310384",
"10417304",
"5046694",
"161.0130176309481",
"68.25864615528502"
]
}
]
},
{
"dimensions": [
"55-64"
],
"metrics": [
{
"values": [
"598618",
"191724",
"4071168",
"1920737",
"162.661150381338",
"67.63612092649852"
]
}
]
},
{
"dimensions": [
"65+"
],
"metrics": [
{
"values": [
"297293",
"97265",
"2945414",
"1076230",
"228.37076740102023",
"58.1395240794254"
]
}
]
}
],
"totals": [
{
"values": [
"6335642",
"2047660",
"46991103",
"22886798",
"155.15735189343656",
"68.89865502373901"
]
}
]
}
}
These are the relevant details.
Note : I have been getting '415 Unsupported Media Type' because I added '#JsonManagedReference' and '#JsonBackReference'. I have added those because for a previous project I couldn't retrieve the JSON from the front end.
But now I am just trying to send the above JSON, so I could remove those annotations. Before adding those annotations, it saved successfully but I the values are NULL as I mentioned above.
Please help. Thanks in advance.

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"
}
}
}

unrelated data from the Many-to-Many With a New Entity concept

Problem summary
I am getting unrelated data from the Many-to-Many With a New Entity concept for the first two cases.
Fetching a particular company and associated users of the company.
Fetching particular user and associated company.
Not able to feth company and user whose company status is not equal to 3 (CompanyStatus=1 "Pending" ,CompanyStatus=2 "Other",CompanyStatus=1 "Active")
To work on this Many-to-Many With a New Entity concept I have used Company, User, and CompanyUserMapping as an entity.
The blog that I have referred https://www.baeldung.com/jpa-many-to-many section 4.2
As mentioned above I have created Company, User, and CompanyUserMapping as below
Company
#Getter
#Setter
#Entity
public class Company {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long companyId;
private String companyName;
private String companyDescription;
private String companyWebsite;
private String companyEmailDomain;
private Integer companyTypeID;
private Integer numberOfEmployeesID;
private String companyLogo;
private Integer companyStatus;
private Boolean active;
#OneToMany(mappedBy = "company",fetch = FetchType.EAGER)
Set<CompanyUserMapping> companyUserMapping;
}
User
#Getter
#Setter
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userId;
private String firstName;
private String lastName;
private String email;
private String encryptedEmail;
private String username;
private String password;
private String userStatus;
private String guid;
private Boolean isNotlocked;
private Date lastLogin;
private String profilePic;
#OneToMany(mappedBy = "user",fetch = FetchType.EAGER)
Set<CompanyUserMapping> companyUserMapping;
}
CompanyUserMapping
#Getter
#Setter
#Entity
public class CompanyUserMapping {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long companyUserMappingId;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "company_id")
private Company company;
#ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
#JoinColumn(name = "user_id")
private User user;
private String role;
private String [] authorities;
private boolean isExternal;
private boolean isActive;
private Long customerId;
}
Then I inserted two companies and a user in each of them. Then I have also inserted a common user for both of the companies.
{
"companyId": 1,
"companyName": "ABC company",
"companyUsers": [
{
"companyUserMappingId": 1,
"company": 1,
"user": {
"userId": 1,
"email": "sachintendulkar#gmail.com",
"companyUserMapping": [
1
]
},
"active": true,
"external": false
},
{
"companyUserMappingId": 3,
"company": 1,
"user": {
"userId": 3,
"email": "shanewarne#gmail.com",
"companyUserMapping": [
3,
{
"companyUserMappingId": 4,
"company": {
"companyId": 2,
"companyName": "XYZ company",
"companyUsers": [
{
"companyUserMappingId": 2,
"company": 2,
"user": {
"userId": 2,
"email": "sehwag#gmail.com",
"companyUserMapping": [
2
]
},
"active": true,
"external": false
},
4
]
},
"user": 3,
"active": true,
"external": false
}
]
},
"active": true,
"external": false
}
]
}
In the above JSON, ABC and XYZ are two companies and a common user for both of the companies is shanewarne#gmail.com
As mentioned in the summary If I try to pull a particular company(ABC company) and associated users, it also brings another company and users which is unrelated.
To resolve this problem I have Implemented like below
public CompanyDto getConsolidatedCompanyData(Long companyId) {
Company existingCompany = companyRepository.findById(companyId).orElseThrow(() -> new ResourceNotFoundException("Company not found for the companyId :: "+companyId));
CompanyDto companyDto=new CompanyDto();
companyDto.setCompanyId(existingCompany.getCompanyId());
companyDto.setCompanyName(existingCompany.getCompanyName());
Set<CompanyUserMappingDto> companyUserMappingDtoList=new LinkedHashSet<>();
Set<CompanyUserMapping> companyUserMappingList=existingCompany.getCompanyUserMapping();
for (CompanyUserMapping cum : companyUserMappingList) {
CompanyUserMappingDto companyUserMappingDto=new CompanyUserMappingDto();
companyUserMappingDto.setCompanyUserMappingId(cum.getCompanyUserMappingId());
CompanyUserDto cdto=new CompanyUserDto();
cdto.setUserId(cum.getUser().getUserId());
cdto.setEmail(cum.getUser().getEmail());
companyUserMappingDto.setUser(cdto);
companyUserMappingDto.setActive(cum.isActive());
companyUserMappingDto.setExternal(cum.isExternal());
companyUserMappingDtoList.add(companyUserMappingDto);
}
companyDto.setAssociatedUsers(companyUserMappingDtoList);
return companyDto;
}
In the same way, if I try to fetch a particular user and associated company I am getting related data so I have implemented code
private UserDto getConslidatedUserData(Long userId) {
User existingUser = userRepository.findById(userId).orElseThrow(() -> new ResourceNotFoundException("User not found for the userId :: "+userId));
Set<UserCompanyMappingDto> associatedCompanies=new HashSet<>();
UserDto userDto=new UserDto();
userDto.setUserId(existingUser.getUserId());
userDto.setEmail(existingUser.getEmail());
Set<CompanyUserMapping> companyUserMapping=existingUser.getCompanyUserMapping();
for (CompanyUserMapping companyUserMapping2 : companyUserMapping) {
UserCompanyMappingDto userCompanyMappingDto=new UserCompanyMappingDto();
userCompanyMappingDto.setCompanyUserMappingId(companyUserMapping2.getCompanyUserMappingId());
UserCompanyDto userCompanyDto=new UserCompanyDto();
userCompanyDto.setCompanyId(companyUserMapping2.getCompany().getCompanyId());
userCompanyDto.setCompanyName(companyUserMapping2.getCompany().getCompanyName());
userCompanyMappingDto.setCompany(userCompanyDto);
associatedCompanies.add(userCompanyMappingDto);
}
userDto.setAssociatedCompanies(associatedCompanies);
return userDto;
}
Do I need to improvise Implementation for the first two cases?

Resources