i have this class:
#Getter
#Setter
#ToString
#AllArgsConstructor
#NoArgsConstructor
public class ViewOrderRTO {
private List<LineProductModel> products;
private OrderModel order;
}
that i use for display data saved in db. LineProductModel is a class that has these field: total price, quantity,id, a #ManyToOne relationship with productModel and a #Many to one relationship with OrderModel.
The question is: can i use #Query in something like this "SELECT new alongpath.ViewOrderRTO(....) ..." and insert a list of lineProduct and the other fields all in one query? or i have to split the work and get all the single LineProductModel and put in a list first and then create the ViewModel?
btw is a spring boot project and i'm using mysql
I "solved" the problem removing the #ManyToOne mapping inside the LineProductModel and adding the #OneToMany mapping in the Order Model now i have this:
#Entity
#Table(name = "order_commission")
#Getter
#Setter
#ToString
#AllArgsConstructor
#NoArgsConstructor
public class OrderModel {
#Id
#SequenceGenerator(name = "order_sequence",
sequenceName = "order_sequence",
initialValue = 0,
allocationSize = 1
)
#GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "order_sequence")
private Long id;
#OneToMany(cascade = CascadeType.ALL,
fetch = FetchType.EAGER,
orphanRemoval = true)
private List<LineProductModel> linePoducts;
private BigDecimal total;
private LocalDateTime orderedAt;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "fk_user")
private UserModel user;
public OrderModel(List<LineProductModel> lineProducts,
BigDecimal total,
LocalDateTime orderedAt,
UserModel user) {
this.linePoducts = lineProducts;
this.total = total;
this.orderedAt = orderedAt;
this.user = user;
}
}
and this is the json i get while performing a #GetMapping:
{
"id": 0,
"linePoducts": [
{
"id": 0,
"quantity": 2,
"lineProductPrice": 6,
"product": {
"id": 0,
"eanCode": "1111111111111",
"name": "pipo",
"price": 3,
"quantity": 8,
"weight": 10,
"description": "test",
"category": {
"id": 0,
"name": "cibo"
}
}
},
{
"id": 1,
"quantity": 7,
"lineProductPrice": 21,
"product": {
"id": 1,
"eanCode": "2111111111111",
"name": "pipobevanda",
"price": 3,
"quantity": 3,
"weight": 10,
"description": "test",
"category": {
"id": 1,
"name": "bevanda"
}
}
},
{
"id": 2,
"quantity": 1,
"lineProductPrice": 3,
"product": {
"id": 2,
"eanCode": "3111111111111",
"name": "pipoverdura",
"price": 3,
"quantity": 9,
"weight": 10,
"description": "test",
"category": {
"id": 2,
"name": "verdura"
}
}
}
],
"total": 0,
"orderedAt": "2022-08-10T20:48:15",
"user": {
"id": 0,
"firstName": "-------",
"lastName": "------",
"email": "--------",
"password": "------",
"countryOfResidence": "italy",
"birthdate": "-------",
"balance": 100
}
}
i have to make some changes about the information that displays, but is there a better solution or this one is ok?
Related
I want to return the class at the same level here.
As here id, username, password, etc are under userCredentialEntity and so in userDetailEntity key.
{
"userCredentialsEntity": {
"id": 5,
"username": "testuser3",
"password": "$2a$10$yFmeUcE3uTOf9H4TZqWXfO/b8zsTp6sqnWax5iyRXBhlfXF3dSsk2",
"email": "testuser3#gmail.com",
"roles": [
{
"id": 2,
"name": "ROLE_MANAGER"
}
]
},
"userDetailsEntity": {
"userId": 5,
"first_name": "Test",
"last_name": "Singh 3",
"birth_date": "12",
"birth_month": "01",
"birth_year": "2002",
"area": "Chandani Chowk",
"city": "Sahadra",
"district": "Sonbhadra",
"pin_code": 231325,
"mobile_number": "6788762345"
}
}
I have to return this.
{
"id": 5,
"username": "testuser3",
"email": "testuser3#gmail.com",
"roles": [
{
"id": 2,
"name": "ROLE_MANAGER"
}
],
"first_name": "Test",
"last_name": "Singh 3",
"birth_date": "12",
"birth_month": "01",
"birth_year": "2002",
"area": "Chandani Chowk",
"city": "Sahadra",
"district": "Sonbhadra",
"pin_code": 231325,
"mobile_number": "6788762345"
}
And also neglect the password and userId field while returning
The Code for my implementation is:
#Data
public class UserMerged {
private UserCredentialsEntity userCredentialsEntity;
private UserDetailsEntity userDetailsEntity;
}
UserDetailsEntity userDetailsEntity = userDetailService.fetchUserDetails(userId).get();
UserCredentialsEntity userCredentialsEntity = userCredentialsRepository.findByUsername(username);
UserMerged userMerged = new UserMerged();
userMerged.setUserDetailsEntity(userDetailsEntity);
userMerged.setUserCredentialsEntity(userCredentialsEntity);
return ResponseEntity.ok().body(userMerged);
I am new in Spring Boot and doesn't got any satisfactory answer regarding this. Please suggest me any way of achieving this.
Thank You.
First thing first, Whatever your return type of object is, for that you need to create the specific class and then return it.
In your case Modify your UserMerged class with whatever u would like to return and then set the parameters accordingly.
Likely,
Your UserMerged will be
#Data
public class UserMerged {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer Id;
#Column(name="username")
private String username;
#Column(name="email")
private String email;
#Column(name="roles")
private List<Roles> roles;
#Column(name="first_name")
private String first_name;
#Column(name="last_name")
private String last_name;
#Column(name="birth_date")
private String birth_date;
#Column(name="birth_month")
private String birth_month;
#Column(name="birth_year")
private String birth_year;
#Column(name="area")
private String area;
#Column(name="city")
private String city;
#Column(name="district")
private String district;
#Column(name="pin_code")
private Integer pin_code;
#Column(name="mobile_number")
private Integer mobile_number;
And instead of setting the UserDetailsEntity and UserCredentialsEntity you can set your fields from those two classes to UserMerged class.
userMerged.setId(userCredentialsEntity.getId());
userMerged.setUsername(userCredentialsEntity.getUsername());
userMerged.setEmail(userCredentialsEntity.getEmail());
userMerged.setRoles(userCredentialsEntity.getRoles());
userMerged.setFirst_name(userDetailsEntity.getFirst_name());
userMerged.setLast_name(userDetailsEntity.getLast_name());
userMerged.setBirth_date(userDetailsEntity.getBirth_date());
userMerged.setBirth_month(userDetailsEntity.getBirth_month());
userMerged.setBirth_year(userDetailsEntity.getBirth_year());
userMerged.setArea(userDetailsEntity.getArea());
userMerged.setCity(userDetailsEntity.getCity());
userMerged.setDistrict(userDetailsEntity.getDistrict());
userMerged.setPin_code(userDetailsEntity.getPin_code());
userMerged.setMobile_number(userDetailsEntity.getMobile_number());
This will set all parameters you needed, and you can return the object of user merged object.
Here Their is lot much repetation of code exist so instead so please take care of that or you can also add common parameters into one class.
This is a VB.Net project. Cannot seem to get the class library correct for deserializing the response string to the classes.
Error we receive when we try to deserialize is:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'blahblah_Framework_Root.blahblah+Tokenscopelist'
because the type requires a JSON object (e.g. {""name"":""value""}) to deserialize correctly.
Sample response trying to deserialize:
{
"data": {
"expiresAt": "2021-11-27T01:12:05.000Z",
"createdAt": "2021-11-13T01:12:05.000Z",
"identityId": 2347335,
"identity": {
"id": 2347335,
"namespace": {
"id": 7760,
"nickname": "org:random-parking"
}
},
"tokenScopeList": [
{
"org": {
"id": 5995,
"name": "RANDOM Parking",
"opal": "opal:prod:helium:alpha:5995:org:5995",
"parentOrg": null,
"packagePlans": [
{
"id": 50,
"package": {
"id": 14,
"name": "Additional Users Over 500",
"packageFeatures": [
{
"config": null,
"id": 147,
"feature": {
"id": 1,
"name": "Users Included",
"code": "users"
}
}
]
},
"isSelected": true
},
{
"id": 54,
"package": {
"id": 15,
"name": "Elevator I/O Boards",
"packageFeatures": [
{
"config": null,
"id": 175,
"feature": {
"id": 21,
"name": "Elevator I/O Boards",
"code": "elevatorIoBoards"
}
}
]
},
"isSelected": true
},
{
"id": 38,
"package": {
"id": 11,
"name": "Premium",
"packageFeatures": [
{
"config": {
"count": 500
},
"id": 91,
"feature": {
"id": 1,
"name": "Users Included",
"code": "users"
}
},
{
"config": {
"count": 1000000
},
"id": 92,
"feature": {
"id": 2,
"name": "Administrators",
"code": "administrators"
}
}
]
},
"isSelected": true
}
]
},
"user": {
"id": 2502299,
"opal": "opal:prod:helium:alpha:5995:user:2502299"
},
"scope": [
"o5995-admin:r",
"o5995-admin:w",
"o5995-configurations:r",
"o5995-configurations:w",
"o5995-dash:r",
"o5995-dash:w",
"o5995-videoProviderPlayback:w"
]
},
{
"org": {
"id": null,
"name": null
},
"user": {
"id": null,
"opal": null
},
"scope": [
"i2347335:r",
"i2347335:w"
]
}
],
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVw"
},
"meta": {
"accessToken": null
}
}
Using this class definition
Public Class RootobjectLogin
Public Property data As DataumLogin
Public Property meta As Meta
End Class
Public Class DataumLogin
Public Property expiresAt As Date
Public Property createdAt As Date
Public Property identityId As Integer
Public Property identity As Identity
Public Property tokenScopeList() As Tokenscopelist
Public Property token As String
End Class
Public Class Tokenscopelist
Public Property org As Org
Public Property user As User
Public Property scope() As String
End Class
Public Class Packageplan
Public Property id As Integer
Public Property package As Package
Public Property isSelected As Boolean
End Class
Public Class Package
Public Property id As Integer
Public Property name As String
Public Property packageFeatures() As New List(Of Packagefeature)
End Class
Public Class Packagefeature
Public Property config As Config
Public Property id As Integer
Public Property feature As Feature
End Class
Public Class Config
Public Property count As Integer
End Class
Public Class Feature
Public Property id As Integer
Public Property name As String
Public Property code As String
End Class
Public Class User
Public Property id As Integer
Public Property opal As String
End Class
Public Class Org
Public Property id As Integer
Public Property name As String
Public Property opal As String
Public Property parentOrg As Object
Public Property packagePlans() As New List(Of Packageplan)
End Class
Public Class Meta
Public Property accessToken As Accesstoken
End Class
Ideas?
I am working on an assignment to add a new tag to the JSON request that we are going to make a call-out. The request is below.
{
"Version": "1.0",
"RequestingSystemName": "SFORCECS",
"InsuredInformation": {
"Zipcode": "12335",
"StateProvinceCode": "CA",
"PhoneNumber": "(111) 111-2222",
"MiddleName": null,
"LastName": "ABC",
"FirstName": "DEF",
"City": "PLACEWI",
"BirthDate": "1950-01-01",
"AddressLine3": null,
"AddressLine2": null,
"AddressLine1": "111 123 Drive"
},
"BeneficiaryList": [
{
"RelationShipEnum": "Nephew",
"Relationship": 18,
"PrimaryIndicator": 0,
"Percentage": null,
"FullName": "XYZ DEQ"
},
{
"RelationShipEnum": "Niece",
"Relationship": 20,
"PrimaryIndicator": 0,
"Percentage": null,
"FullName": "DEQ XYZ"
}
],
"ApplicationInformation": {
"SignedDateTime": "2010-01-01T01:01:01.000Z",
"ProductIdentifier": "1",
"MarketingSequenceNumber": "11111111111",
"EmailAddress": null,
"ContractNumber": "1111111",
"BasicAmount": "1000",
"AgentID": "12345"
}
}
Now, my task is to change the Beneficiary info request. It should be as shown below.
"BeneficiaryList": {"Beneficiary":[
{
"RelationShipEnum": "Nephew",
"Relationship": 18,
"PrimaryIndicator": 0,
"Percentage": null,
"FullName": "XYZ DEQ"
},
{
"RelationShipEnum": "Niece",
"Relationship": 20,
"PrimaryIndicator": 0,
"Percentage": null,
"FullName": "DEQ XYZ"
}
]},
Can some one help? The apex class that generates the request for beneficiary info is below.
public class ReqBasic{
public class Beneficiary{
public Beneficiary(){}
public Beneficiary(String FullName, Integer PrimaryIndicator, Integer Percentage, Integer Relationship){
this.FullName = FullName;
this.PrimaryIndicator = PrimaryIndicator;
this.Percentage = Percentage;
this.Relationship = Relationship;
}
public Beneficiary(String FullName, String PrimaryIndicator, Integer Percentage, String Relationship){
this.FullName = FullName;
this.setPrimaryIndicatorStr(PrimaryIndicator);
this.Percentage = Percentage;
this.setRelationshipStr(Relationship);
}
}
}
I am not sure what change I need to make to add the beneficiary: tag under the BeneficiaryList. Can some one help?
The code you shared doesn't have what you need but somewhere in the request class you should have a variable called BeneficiaryList which would look like
List< Beneficiary> BeneficiaryList; //or = new List<Beneficiary>(); or Beneficiary[] depending on the coding style
You would need to make a new class called Beneficiaries (or whatever you want) which contains a List of Beneficiary
public class Beneficiaries{
List< Beneficiary> Beneficiary = new List<Beneficiary>();
public Beneficiaries(List<Beneficiary> beneficiaries){
Beneficiary.addAll(beneficiaries);
}
}
Then in your class that is the request set BeneficiaryList from a list of Beneficiary to the new Beneficiaries class
Beneficiaries BeneficiaryList = new Beneficiaries(beneficiaries);
Obviously you implmentation would depend on how your request class is setup and how you add beneficiaries but you should at least create an add(...) method so that you dont have to change too much of the code
I am having a Folder class which in-turn can have many sub-folders. In this case i am trying to make use of same entity that single entity is being used to achieve the same.
Something like below.
Folders
----SubFolder
----SubFolder
Below are the classes.
FolderData.java
#Entity
#JsonIdentityInfo(generator =ObjectIdGenerators.IntSequenceGenerator.class,property="projectId")
public class FolderData {
#Id
#SequenceGenerator(name = "seq-gen", initialValue = 1)
#GeneratedValue(strategy = GenerationType.IDENTITY, generator = "seq-gen")
private Integer parentId;
private int moduleId;
private int subProjectId;
private String folderName;
private Integer folderId;
private int projectId;
#ManyToOne(fetch = FetchType.LAZY,cascade=CascadeType.ALL)
#JoinColumn(name="folder_child")
#JsonIgnore
private FolderData folderData;
#OneToMany(mappedBy = "folderData")
#JsonIgnoreProperties("folderList")
private Set<FolderData> folderList=new HashSet<>();
}
FodlerController.java
#RestController
#RequestMapping("/folder")
public class FodlerController {
#Autowired
private FolderService folderService;
#GetMapping(produces = "application/json")
public List<FolderData> getFolderList(){
return folderService.findAllFromTheList();
}
#PostMapping(produces = "application/json", consumes = "application/json")
public void createFolder(#RequestBody FolderData folderData) {
if(folderData.getId()==null && folderData.getFolderId()==null) {
System.out.println("id is null");
folderData.setFolderId(new Random().nextInt());
folderService.save(folderData);
}
else {
folderService.doChildAddition(folderData);
}
}
}
FolderService.java
#Service
public class FolderService {
#Autowired
private FolderRepo folderRepo;
public FolderData save(FolderData folderData) {
return folderRepo.save(folderData);
}
public FolderData getFolderDataByParentId(Integer id) {
return folderRepo.getOne(id);
}
public List<FolderData> findAllFromTheList() {
return folderRepo.findAll();
}
public FolderData getFolderDataByfolderId(Integer folderId) {
return folderRepo.findFolderByFolderId(folderId);
}
public void doChildAddition(FolderData childFolder) {
FolderData parentFolder=folderRepo.findFolderByFolderId(childFolder.getFolderId());
childFolder.setFolderData(parentFolder);
FolderData childFolderSaved = folderRepo.saveAndFlush(childFolder);
//parentFolder.getFolderList().add(folderRepo.getOne(childFolderSaved.getId()));
//folderRepo.save(parentFolder);
}
}
Json Request for creating parent and the response collected which includes autogenerated folder id:
{
"moduleId":1,
"subProjectId":1,
"folderName":"One",
"projectId":1
}
[
{
"projectId": 0,
"moduleId": 1,
"subProjectId": 1,
"folderName": "One",
"folderId": 963031296,
"folderList": [],
"id": 1
}
]
Creating child for the parent and the response collected.
{
"moduleId":1,
"subProjectId":2,
"folderName":"Two",
"projectId":1,
"folderId": -963031296
}
[
{
"projectId": 0,
"moduleId": 1,
"subProjectId": 1,
"folderName": "One",
"folderId": 963031296,
"folderList": [
{
"projectId": 0,
"moduleId": 1,
"subProjectId": 2,
"folderName": "Two",
"folderId": 963031296,
"id": 2
}
],
"id": 1
},
2
]
For the above response i am getting the No 2 with the response since i am using
#JsonIdentityInfo(generator =ObjectIdGenerators.IntSequenceGenerator.class,property="parentId")
else the whole object would have come instead of 2.
Example output had i not used JsonIdentityInfo
[
{
"projectId": 0,
"moduleId": 1,
"subProjectId": 1,
"folderName": "One",
"folderId": 963031296,
"folderList": [
{
"projectId": 0,
"moduleId": 1,
"subProjectId": 2,
"folderName": "Two",
"folderId": 963031296,
"id": 2
}
],
"id": 1
},
{
"projectId": 0,
"moduleId": 1,
"subProjectId": 2,
"folderName": "Two",
"folderId": 963031296,
"id": 2
}
]
It's easy, #Prash
Since you have used a Set in a undirectional dependency you must supply an uniqueness of a joined (depended) entities. Any set is using hashCode() and equals() to determine an availability of the concurent item that is want to be added. Your FolderData class doesn't have hashCode() and equals() so from the point of view of JVM all the deserialized objects are same and because of the Set nature it's normal to keep only last example
Course.java
#Entity
#Table
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Course {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#NotEmpty
private String description;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "subject_course", joinColumns = #JoinColumn(name = "subject_id", referencedColumnName = "id"), inverseJoinColumns = #JoinColumn(name = "course_id", referencedColumnName = "id"))
private Set<Subject> subjects = new HashSet<Subject>();
---- getter/setter ----
Subject.java
#Entity
#Table
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Subject {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String description;
#ManyToMany(mappedBy = "subjects", fetch=FetchType.EAGER)
#Cascade({CascadeType.DELETE, CascadeType.SAVE_UPDATE})
private Set<Course> courses = new HashSet<Course>();
---- getter/setter ----
Request configuration in Spring:
#RequestMapping(value = "/courses", method = RequestMethod.GET)
public #ResponseBody ResponseEntity<?> getAllCourses() {
List<Course> courses = courseService.getAllCourses();
if (courses.isEmpty()) {
return new ResponseEntity<Message>(new Message("error", "No course found!"), HttpStatus.NOT_FOUND);
}
return new ResponseEntity<List<Course>>(courses, HttpStatus.OK);
}
Hibernate Version: 4.2.0.Final
Spring Version: 3.2.8.RELEASE
Jackson:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.4</version>
</dependency>
Expecting O/P
[{
"id": 1,
"description": "BCA",
"subjects":[{
"id":1,
"description":"Physics",
"courses":[1,2,3] //Either show blank array or only ids
}]
},{
"id": 2,
"description": "BSC",
"subjects":[{
"id":1,
"description":"Physics",
"courses":[1,2,3]
}]
},{
"id": 3,
"description": "BA",
"subjects":[{
"id":1,
"description":"Physics",
"courses":[1,2,3]
}]
},]
But getting O/P:
[
{
"id": 1,
"description": "BCA",
"subjects": [
{
"id": 1,
"description": "Math",
"staffs": [],
"courses": [
{
"id": 4,
"description": "BDA",
"subjects": [
1
],
"students": []
},
{
"id": 3,
"description": "BBA",
"subjects": [
1
],
"students": []
},
1
],
"students": []
}
],
"students": [
{
"id": 1,
"name": "",
"age": 0,
"gender": null,
"course": 1,
"subjects": []
}
]
},
3,
4
]
As per actual o/p, it is stopping the recursion at second level. But my requirement is not to repeat the same objects data from child... It means Course must not repeat its data in Subject's course property. Similarly, if call the same from Subject then subject should not repeat Course subject property value. It is better to skip, if can't then just display id values separated by comma.
Please advise how to fix this issue.
You can use #JsonIgnore in the Subject class like this:
#ManyToMany(mappedBy = "subjects", fetch=FetchType.EAGER)
#Cascade({CascadeType.DELETE, CascadeType.SAVE_UPDATE})
#JsonIgnore
private Set<Course> courses = new HashSet<Course>();