My mongodb query is
db.getCollection("UserDetails").find({
$or:[
{
"username":"xxxx",
"email":"yyyy"
},
{
"username":"aaaa",
"email":"bbbb"
}
...........................................
]
})
Handler Class
public Mono<ServerResponse> getBulkUserDetails(final ServerRequest request){
}
Model Class (UserDetails)
#Getter
#Setter
#EqualsAndHashCode
#Document(collection="UserDetails")
public class UserDetails {
#Id
public String id;
public String firstName;
public String middleName;
public Set<UserEmailDetails> userEmailDetails;
}
#Getter
#Setter
#AllArgsConstructor
#EqualsAndHashCode
#NoArgsConstructor
#JsonIgnoreProperties(ignoreUnknown=true)
public class UserEmailDetails {
public String userdetailid;
public String userName;
public String email;
}
Endpoint details
POST -> /userdetails/usernameandemail/bulk
Sample Input in Request Body as JSON
[
{
"username":"xxxx",
"email":"yyyy"
},
{
"username":"aaaa",
"email":"bbbb"
},
{
"username":"cccc",
"email":"dddd"
}
]
Sample Output as JSON
[
{
"id":"jjsfhjsdhfjshfhsd",
"firstName":"samplefirstname1",
"middleName":"samplemiddlename1",
"userEmailDetails":[
{
"userdetailid":"11111111",
"userName":"xxxx",
"email":"yyyy"
}
]
},
{
"id":"afsdfw423qdrsf3rfsdfsf",
"firstName":"samplefirstname2",
"middleName":"samplemiddlename2",
"userEmailDetails":[
{
"userdetailid":"22222222",
"userName":"aaaa",
"email":"bbbb"
}
]
},
{
"id":"asfwt32rfef23424rwef3fsdfasf",
"firstName":"samplefirstname3",
"middleName":"samplemiddlename3",
"userEmailDetails":[
{
"userdetailid":"33333333",
"userName":"cccc",
"email":"dddd"
}
]
}
]
I need to build a endpoint which takes array of username and email as input and sends the array of userResponses as output using Spring Boot Webflux Reactive Programming
Please help how i can get this implemented in best way using Spring Reactive MongoRepository
Related
I'm using Micronaut Data JDBC and I'm facing an error. I have this entity:
#MappedEntity(value = "document_metadata")
#AllArgsConstructor
#EqualsAndHashCode
public class DocumentMetadataJDBCEntity implements DocumentMetadata {
#Embeddable
#AllArgsConstructor
public static class MetadataPk {
#MappedProperty(value = "document_uid")
#NotNull
private UUID documentUid;
#MappedProperty(value = "metadata_key")
#NotNull
private String metadataKey;
public UUID getDocumentUid() {
return documentUid;
}
public String getMetadataKey() {
return metadataKey;
}
}
#EmbeddedId
private MetadataPk metadataPk;
#NotNull
private String metadataValue;
public MetadataPk getMetadataPk() {
return metadataPk;
}
#Override
public String getMetadataKey() {
return getMetadataPk().getMetadataKey();
}
#Override
public String getMetadataValue() {
return metadataValue;
}
public UUID getDocumentUid() {
return getMetadataPk().getDocumentUid();
}
}
And when inserting I get this error:
io.micronaut.data.exceptions.DataAccessException: SQL error executing INSERT: Batch entry 0 INSERT INTO "document_metadata" ("metadata_key","metadata_value","document_uid","document_uid","metadata_key") VALUES ('id','1234','c960d8de-99a4-40a6-91bf-b0d4a73910d6'::uuid,'c960d8de-99a4-40a6-91bf-b0d4a73910d6'::uuid,'id') was aborted: ERROR: column "document_uid" specified more than once
The code for saving is the next one:
Set<DocumentMetadataJDBCEntity> metadataSet = metadata.entrySet().stream()
.map(e -> new DocumentMetadataJDBCEntity(new DocumentMetadataJDBCEntity.MetadataPk(
savedDocument.getUid(), e.getKey()), e.getValue())).collect(toSet());
Iterable<DocumentMetadataJDBCEntity> persistedMetadata = documentMetadataJDBCRepository.saveAll(metadataSet);
Any idea?
Add #Transient to your convenience accessor (getter) methods:
#Override
#Transient
public String getMetadataKey() {
return getMetadataPk().getMetadataKey();
}
#Transient
public UUID getDocumentUid() {
return getMetadataPk().getDocumentUid();
}
It "tells" Micronaut not to save the return value into the DB.
Im trying to parse trough json string and return values into custom meta data type field on Case. I have created the custom metadata type already, example:
<label>Jordfeil.Casefield</label>
<protected>false</protected>
<values>
<field>CaseField__c</field>
<value xsi:type="xsd:string">Casefield</value>
</values>
<values>
<field>Context__c</field>
<value xsi:type="xsd:string">JORDFEIL</value>
</values>
<values>
<field>JsonField__c</field>
<value xsi:type="xsd:string">key1</value>
</values>
</CustomMetadata>
Json String :
{
"operation": "get-id",
"payload": {
"ApplicationContext": {
"Context": "JORDFEIL",
"SenderId": "xxx",
"subContext": ""
},
"supportIssue": {
"InfoFields": [
{
"Key": "key1",
"Value": "value1"
},
{
"Key": "key2",
"Value": "value2"
},
{
"Key": "key3",
"Value": "value3"
}
],
}
},
"type": "~:CustomerInquiry",
}
My Wrapper class:
public class WebskjemaModel {
public class ApplicationContext {
public String Context;
public String SenderId;
public String subContext;
}
public String operation;
public Payload payload;
public String type;
public class InfoFields {
public String Key;
public String Value;
}
public class Payload {
public ApplicationContext ApplicationContext;
public SupportIssue supportIssue;
}
public class SupportIssue {
public List<InfoFields> InfoFields;
public String assignId;
public String businessObjectType;
public String comment;
public String contactDate;
public String contactName;
public String customerName;
public String customerNo;
public String docClass;
public String format;
public String objectDescription;
public String objectId;
public String subject;
}
public static WebskjemaModel parse(String json) {
return (WebskjemaModel) System.JSON.deserialize(json, WebskjemaModel.class);
}
}
The json string is stored a field in Case called WebskjemaBlob__c.
Below is my class:
public with sharing class WebskjemaCaseCreator {
Map<String, Case> Webskjemastring = new Map<String, Case>();
private Map<Id, Case> cases { get; set; }
private Map<Id, WebskjemaModel> webskjemaModels = new Map<Id, WebskjemaModel>();
public WebskjemaCaseCreator(Map<Id, Case> cases) {
this.cases = cases;
deserializeJson();
mapFields();
}
private void deserializeJson() {
for (Id caseId : cases.keySet()) {
Case c = cases.get(caseId);
WebskjemaModel model = WebskjemaModel.parse(c.Webskjemablob__c);
webskjemaModels.put(caseId, model);
}
}
private void mapFields() {
for (Id caseId : cases.keySet()) {
Case c = cases.get(caseId);
WebskjemaModel model = webskjemaModels.get(caseId);
}
}
private void mapFieldsForSingleCase(Case c, WebskjemaModel model) {
// TODO: Find WebskjemaModel inforfields and loop
// for (list of infofields for this model only){
// TODO: call method mapInfoField
// }
}
private void mapInfoField(Case c, String context, String infoFieldKey, String infoFieldValue) {
// TODO: Find Case field from custom meta data type mapping, based on context and infoFielfKey
// TODO: Put value from inforFieldValue into Case field
}
}
My question is how you get the key value pair from infofields and update the case fields based on the custom meta data type mapping?
I connected my Spring-Boot-Application to a MongoDB. The application is nothing serious, just for getting into working with spring and MongoDB.
The problem it, that my id is a String and I get an Internal Server Error, when I pass the id of a database entry, in order to get it byId...
This is my domain class:
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Document(collection = "songinfo")
public class SongInfo {
#Id
private String id;
private int songId;
private String songName;
private String description;
}
The Controller-Method:
#RequiredArgsConstructor
#RestController
#RequestMapping("/songsinfo")
public class SongsInfoController {
private final SongInfoService songInfoService;
#GetMapping(value = "/{id}", headers = "Accept=application/json", produces =
{MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<SongInfo> getSongInfoById(#PathVariable(value = "id") String id) {
SongInfo songInfo = songInfoService.getSongInfoById(id);
if (songInfo == null)
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
return new ResponseEntity<>(songInfo, HttpStatus.OK);
}
The SongInfoServiceImpl:*
#Override
public SongInfo getSongInfoById(String id) {
return songInfoRepository.findById(id).orElseThrow(NotFoundException::new);
}
This is the SongsInfoRepository:
public interface SongInfoRepository extends MongoRepository<SongInfo, String> {
}
Getting all songinfos from the database is working fine:
But when is pass the id from one of these entries, I get this:
What is wrong here with my implementation?
You're throwing the exception in SongInfoServiceImpl which is not handled in your SongsInfoController Class.
Solution 1: Instead of throwing the exception return null.
SongInfoServiceImpl.java
#Override
public SongInfo getSongInfoById(String id) {
return songInfoRepository.findById(id).orElse(null);
}
Solution 2: Add try catch block
SongsInfoController.java
#RequiredArgsConstructor
#RestController
#RequestMapping("/songsinfo")
public class SongsInfoController {
private final SongInfoService songInfoService;
#GetMapping(value = "/{id}",
headers = "Accept=application/json",
produces = {MediaType.APPLICATION_JSON_VALUE}
)
public ResponseEntity<SongInfo> getSongInfoById(#PathVariable(value = "id") String id) {
SongInfo songInfo = null;
try {
songInfo = songInfoService.getSongInfoById(id);
} catch(Exception e) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(songInfo, HttpStatus.OK);
}
}
I think you need to divide two problem.
Check id parameter SongsInfoController
Inside controller check your parameter is valid through log or sysout
Check getSongInfoById method in SongInfoServiceImpl
Simply getSongInfoById(8752); is get error?
I want to add comment but my reputation is under 50.
If you comment above two solution check result, then I will add additional answer.
I am reading and learning Spring Boot data with MongoDB. I have about 10 records in my database in the following format:
{
"_id" : ObjectId("5910c7fed6df5322243c36cd"),
name: "car"
}
When I open the url:
http://localhost:8090/items
I get an exhaustive list of all items. However, I want to use the methods of MongoRepository such as findById, count etc. When I use them as such:
http://localhost:8090/items/count
http://localhost:8090/items/findById/5910c7fed6df5322243c36cd
http://localhost:8090/items/findById?id=5910c7fed6df5322243c36cd
I get a 404.
My setup is as so:
#SpringBootApplication
public class Application {
public static void main(String[] args) throws IOException {
SpringApplication.run(Application.class, args);
}
}
#Document
public class Item implements Serializable {
private static final long serialVersionUID = -4343106526681673638L;
#Id
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
#RepositoryRestResource(collectionResourceRel = "item", path = "items")
public interface ItemRepository<T, ID extends Serializable> extends MongoRepository<Item, String>, ItemRepositoryCustom {
}
What am I doing wrong? Do I need to implement the methods as defined by MongoRepository or will they be automatically implemented? I am lost and have been trying to figure this out for so long. I do not have any methods in my controller, its empty.
You have to declare the findById method in order for it to be exposed.
Item findById(String id);
Item findByName(String name);
Note that you don't need to implement the methods. SpringBoot will analyse the method name and provide the proper implementation
I had same issue,
After removing #Configuration,#ComponentScan everything worked fine.
I have created a rest Service using Apache Camel Swagger component. The rest service works fine but the request and response schema is not what i intended of.
The schema that i am trying to create is :
{
"GetStudentData": [
{
"RollNumber": "1",
"Name": "ABC",
"ClassName": "VII",
"Grade": "A"
}]
}
For this i have created a model as:
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
#XmlRootElement(name = "GetStudentData")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name="", propOrder={"studentInfo"})
public class StudentInfoWrapper {
#XmlElement(required=true)
private List<Student> studentInfo;
private double visiteddate;
public double getVisiteddate() {
return visiteddate;
}
public void setVisiteddate(double visiteddate) {
this.visiteddate = visiteddate;
}
public List<Student> getStudentInfo() {
return studentInfo;
}
public void setStudentInfo(List<Student> studentInfo) {
studentInfo = studentInfo;
}
}
And my student class is:
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name="", propOrder={"RollNumber", "Name", "ClassName", "Grade"})
public class Student {
private String RollNumber;
private String Name;
private String ClassName;
private String Grade;
public String getRollNumber() {
return RollNumber;
}
public void setRollNumber(String rollNumber) {
RollNumber = rollNumber;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getClassName() {
return ClassName;
}
public void setClassName(String className) {
ClassName = className;
}
public String getGrade() {
return Grade;
}
public void setGrade(String grade) {
Grade = grade;
}
}
So when i load the above service into the swaggerUI it doesn't show the schema that i want.
How can i i get the desired schema. Looking forward to your answers.
Thanks in advance.