How to do paging on Object that isn't Entity? - java

I'm trying to do paging, very similar to the option of #RepositoryRestResource
but only on object that isn't Entity.
the code:
public class FloorplanDevice {
private String FloorplanName;
private Long FloorplanId;
private Long DeviceId;
private String DeviceName;
private String macAddress;
private Long groupId;
private LocatableType deviceType;
public String getFloorplanName() {
return FloorplanName;
}
public void setFloorplanName(String floorplanName) {
FloorplanName = floorplanName;
}
public Long getFloorplanId() {
return FloorplanId;
}
public void setFloorplanId(Long floorplanId) {
FloorplanId = floorplanId;
}
public Long getDeviceId() {
return DeviceId;
}
public void setDeviceId(Long deviceId) {
DeviceId = deviceId;
}
public String getDeviceName() {
return DeviceName;
}
public void setDeviceName(String deviceName) {
DeviceName = deviceName;
}
public String getMacAddress() {
return macAddress;
}
public void setMacAddress(String macAddress) {
this.macAddress = macAddress;
}
public Long getGroupId() {
return groupId;
}
public void setGroupId(Long groupId) {
this.groupId = groupId;
}
public LocatableType getDeviceType() {
return deviceType;
}
public void setDeviceType(LocatableType deviceType) {
this.deviceType = deviceType;
}
public FloorplanDevice() {
}
public FloorplanDevice(String floorplanName, Long floorplanId, Long deviceId, String deviceName, String macAddress, Long groupId, LocatableType deviceType) {
FloorplanName = floorplanName;
FloorplanId = floorplanId;
DeviceId = deviceId;
DeviceName = deviceName;
this.macAddress = macAddress;
this.groupId = groupId;
this.deviceType = deviceType;
}
}
This object doesn't have Repository but it has controller:
#RequestMapping(
path = arrayOf("/floorplanDevice/{groupId}", "/floorplanDevice/{groupId}/"),
method = arrayOf(RequestMethod.GET))
open fun getFloorplanDevice(#PathVariable("groupId") groupId: Long): ResponseEntity<*>{
var floorplanDevice= floorplanService.getFloorplanDevice(groupId)
return ResponseEntity(floorplanDevice, HttpStatus.OK)
}
So how can I do Paging to this object with page number and size (if it possible sorting also)?
I'm using java Spring
Thank you

Try something like this:
public Page<FloorplanDevice> getFloorplanDevice(#PathVariable("groupId") Long groupId,
#PageableDefault Pageable pageable)
List<FloorplanDevice> list = floorplanService.getFloorplanDevice(groupId);
MutableSortDefinition sort = pageable.getSort() != null ?
StreamSupport.stream(pageable.getSort().spliterator(), false)
.findFirst()
.map(it -> new MutableSortDefinition(it.getProperty(), it.isIgnoreCase(), it.isAscending()))
.orElse(null)
: null;
PagedListHolder<FloorplanDevice> pageHolder = new PagedListHolder<>(list, sort);
pageHolder.setPage(pageable.getPageNumber());
pageHolder.setPageSize(pageable.getPageSize());
pageHolder.resort();
List<FloorplanDevice> content = pageHolder.getPageList();
Page<FloorplanDevice> page = new PageImpl<>(content, pageable, list.size());
return page;
}

Solution:
This is my solution by using PageListHolder.
#RequestMapping(
path = arrayOf("/floorplanDevice/{groupId}/page/{pageNum}/size/{sizeNum}", "/floorplanDevice/{groupId}/page/{pageNum}/size/{sizeNum}/"),
method = arrayOf(RequestMethod.GET))
open fun getFloorplanDevicePage(#PathVariable("groupId") groupId: Long, #PathVariable("pageNum") pageNum: Int,#PathVariable("sizeNum") sizeNum: Int): ResponseEntity<*>{
var floorplanDevice= floorplanService.getFloorplanDevice(groupId)
var paging= PagedListHolder<FloorplanDevice>(floorplanDevice)
var setsize= paging.setPageSize(sizeNum)
if(paging.pageCount>pageNum){
var setpage=paging.setPage(pageNum)}
else{
return throw RuntimeException("page: $pageNum is too big, insert smaller page from 0 to ${paging.pageCount-1}")
}
var pageList= paging.pageList
return ResponseEntity(pageList, HttpStatus.OK)
}

Related

Spring Data Neo4j 4.2 query for labels or node id always return null

Currently, I'm building a graph visualization app using Spring Boot & Neo4j. But when I call a method from my entity Neo4jRepository to get NodeEntity labels, it always returns a null value. Is the problem in my node entity?
This is my node entity
#NodeEntity(label="Personnel")
public class PersonnelNode {
private Long id;
#Labels
private Set<String> labels;
#GraphId
private Long personnelId;
private String personnelKey;
private String personnelNameIN;
private Boolean isTeamLeader;
private Boolean isQA;
private Boolean isSuperUser;
private Short companyGroupId;
private Boolean isActive;
private Timestamp created;
private String createdBy;
private Timestamp lastModified;
private String lastModifiedBy;
#Relationship(type="PERSONNEL_TASK", direction=Relationship.OUTGOING)
private TaskNode personnelTasks;
private Long employeeDataId;
public PersonnelNode() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Set<String> getLabels() {
return labels;
}
public void setLabels(Set<String> labels) {
this.labels = labels;
}
public Long getPersonnelId() {
return personnelId;
}
public void setPersonnelId(Long personnelId) {
this.personnelId = personnelId;
}
public String getPersonnelKey() {
return personnelKey;
}
public void setPersonnelKey(String personnelKey) {
this.personnelKey = personnelKey;
}
public String getPersonnelNameIN() {
return personnelNameIN;
}
public void setPersonnelNameIN(String personnelNameIN) {
this.personnelNameIN = personnelNameIN;
}
public Boolean getIsTeamLeader() {
return isTeamLeader;
}
public void setIsTeamLeader(Boolean isTeamLeader) {
this.isTeamLeader = isTeamLeader;
}
public Boolean getIsQA() {
return isQA;
}
public void setIsQA(Boolean isQA) {
this.isQA = isQA;
}
public Boolean getIsSuperUser() {
return isSuperUser;
}
public void setIsSuperUser(Boolean isSuperUser) {
this.isSuperUser = isSuperUser;
}
public Short getCompanyGroupId() {
return companyGroupId;
}
public void setCompanyGroupId(Short companyGroupId) {
this.companyGroupId = companyGroupId;
}
public Boolean getIsActive() {
return isActive;
}
public void setIsActive(Boolean isActive) {
this.isActive = isActive;
}
public Timestamp getCreated() {
return created;
}
public void setCreated(Timestamp created) {
this.created = created;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Timestamp getLastModified() {
return lastModified;
}
public void setLastModified(Timestamp lastModified) {
this.lastModified = lastModified;
}
public String getLastModifiedBy() {
return lastModifiedBy;
}
public void setLastModifiedBy(String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
public Long getEmployeeDataId() {
return employeeDataId;
}
public void setEmployeeDataId(Long employeeDataId) {
this.employeeDataId = employeeDataId;
}
public TaskNode getPersonnelTasks() {
return personnelTasks;
}
public void setPersonnelTasks(TaskNode personnelTasks) {
this.personnelTasks = personnelTasks;
}
}
My Dao Class
#Component
public class PersonnelNodeDao implements IPersonnelNodeDao {
private PersonnelNodeRepository personnelRepository;
#Autowired
public PersonnelNodeDao(PersonnelNodeRepository personnelRepository) {
this.personnelRepository = personnelRepository;
}
#Override
public PersonnelNode getByEmployeeDataId(Long employeeDataId) {
return personnelRepository.findByEmployeeDataId(employeeDataId);
}
#Override
public PersonnelNode getByPersonnelId(Long personnelId) {
return personnelRepository.findByPersonnelId(personnelId);
}
#Override
public Object getLabelsByPersonnelId(Long personnelId) {
return personnelRepository.getLabelsByPersonnelId(personnelId);
}
}
And this is my Neo4jRepository Class
public interface PersonnelNodeRepository extends Neo4jRepository<PersonnelNode, Long> {
#Query(""
+"MATCH (p:Personnel)-[r:PERSONNEL_EMPLOYEE]->(e:Employee) "
+ "WHERE e.employeeDataId = {0} RETURN p")
PersonnelNode findByEmployeeDataId(Long employeeDataId);
#Query("MATCH (p:Personnel) WHERE p.personnelId = {0} RETURN p, ID(p), labels(p)")
PersonnelNode findByPersonnelId(Long personnelId);
#Query(""
+ "MATCH p=(n:Personnel)-[r:PERSONNEL_TASK]->(t:Task {isActive: true}) "
+ "<-[pt:PROJECT_TASK]-(j:Project) "
+ "WHERE n.personnelId= {0} "
+ "RETURN nodes(p) as nodes, rels(p) as relationships")
List<Graph<PersonnelNode>> getPersonnelLoadTaskGraphByEmployeeDataId(Long employeeDataId);
#Query("MATCH (p:Personnel) WHERE p.personnelId = {0} RETURN labels(p)")
Object getLabelsByPersonnelId(Long personnelId);
}
This is my service that calls the method
Object nodePersonnel = personnelNodeDao.getLabelsByPersonnelId(Long.valueOf("2"));
The result is same when i set return variable with my node entity in my service also in my repository, its always return null value
PersonnelNode nodePersonnel = personnelNodeDao.getByPersonnelId(Long.valueOf("2"));
Actually my problem is, just for this entity. For antoher entity i could get the node id and the labels. This is the data return for personnel entity.
Data Retrun From PersonnelRepository
FYI I'm using Spring Data Neo4j 4.2, spring boot 1.5.2 and ogm 2.1. Thank you before.

Jackson XML - Can't deserialize Boolean

I'm trying to parse XML content with Jackson but I have some difficulties with Boolean value.
This is a part of my XML content :
<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body xmlns:ns1="http://somecontent">
<wsResponse xmlns="http://somecontent">
<responseType>SUCCESS</responseType>
<response>
<successfullResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="InterchangeSearchResponse">
<totalResult>1</totalResult>
<returnedResults>1</returnedResults>
<pageIndex>1</pageIndex>
<interchanges>
<interchange>
<depositId>somecontent</depositId>
<interchangeId>somecontent</interchangeId>
<depositDate>2021-03-26T11:45:05.000+01:00</depositDate>
<depositSubject>dépôt WS</depositSubject>
<numADS>number</numADS>
<adsDate>2021-03-26T11:45:05.000+01:00</adsDate>
<alias>contentAsString</alias>
<version xsi:nil="true"/>
<isTest>false</isTest>
<deposantAccount>
<name>someString</name>
</deposantAccount>
<teleProcedure>someString</teleProcedure>
<statesHistory>
This is my XML structure as class :
#JacksonXmlProperty(localName = "Body")
private Body body;
public Body getBody() {
return body;
}
public void setBody(Body body) {
this.body = body;
}
}
#JacksonXmlRootElement
public class Body {
#JacksonXmlProperty(localName = "Fault")
private Fault fault;
private WsResponse wsResponse;
public Fault getFault() {
return fault;
}
public void setFault(Fault fault) {
this.fault = fault;
}
public WsResponse getWsResponse() {
return wsResponse;
}
public void setWsResponse(WsResponse wsResponse) {
this.wsResponse = wsResponse;
}
}
#JacksonXmlRootElement(localName = "wsResponse")
public class WsResponse {
private String responseType;
private Response response;
public String getResponseType() {
return responseType;
}
public void setResponseType(String responseType) {
this.responseType = responseType;
}
public Response getResponse() {
return response;
}
public void setResponse(Response response) {
this.response = response;
}
}
#JacksonXmlRootElement
public class Response {
private SuccessfulResponse successfullResponse;
private ErrorResponse errorResponse;
public SuccessfulResponse getSuccessfullResponse() {
return successfullResponse;
}
public void setSuccessfullResponse(SuccessfulResponse successfullResponse) {
this.successfullResponse = successfullResponse;
}
public ErrorResponse getErrorResponse() {
return errorResponse;
}
public void setErrorResponse(ErrorResponse errorResponse) {
this.errorResponse = errorResponse;
}
}
#JacksonXmlRootElement
public class SuccessfulResponse {
/**
* Response when add document success
*/
private String depositId;
/**
* Response when get interchanges by deposit id success
*/
private String type;
private Integer totalResult;
private Integer returnedResults;
private Integer pageIndex;
private Interchanges interchanges;
/**
* Response when get declaration details success
*/
private DeclarationTdfc declarationTdfc;
public SuccessfulResponse() {}
public SuccessfulResponse(String depositId) {
this.depositId = depositId;
}
public SuccessfulResponse(String type, Integer totalResult, Integer returnedResults, Integer pageIndex, Interchanges interchanges) {
this.type = type;
this.totalResult = totalResult;
this.returnedResults = returnedResults;
this.pageIndex = pageIndex;
this.interchanges = interchanges;
}
public SuccessfulResponse(DeclarationTdfc declarationTdfc) {
this.declarationTdfc = declarationTdfc;
}
public SuccessfulResponse(String depositId, String type, Integer totalResult, Integer returnedResults,
Integer pageIndex, Interchanges interchanges, DeclarationTdfc declarationTdfc) {
super();
this.depositId = depositId;
this.type = type;
this.totalResult = totalResult;
this.returnedResults = returnedResults;
this.pageIndex = pageIndex;
this.interchanges = interchanges;
this.declarationTdfc = declarationTdfc;
}
public String getDepositId() {
return depositId;
}
public void setDepositId(String depositId) {
this.depositId = depositId;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getTotalResult() {
return totalResult;
}
public void setTotalResult(Integer totalResult) {
this.totalResult = totalResult;
}
public Integer getReturnedResults() {
return returnedResults;
}
public void setReturnedResults(Integer returnedResults) {
this.returnedResults = returnedResults;
}
public Integer getPageIndex() {
return pageIndex;
}
public void setPageIndex(Integer pageIndex) {
this.pageIndex = pageIndex;
}
public Interchanges getInterchanges() {
return interchanges;
}
public void setInterchanges(Interchanges interchanges) {
this.interchanges = interchanges;
}
public DeclarationTdfc getDeclarationTdfc() {
return declarationTdfc;
}
public void setDeclarationTdfc(DeclarationTdfc declarationTdfc) {
this.declarationTdfc = declarationTdfc;
}
}
public class Interchanges {
#JacksonXmlProperty(localName = "interchange")
#JacksonXmlElementWrapper(useWrapping = false)
private List<Interchange> interchange;
public Interchanges() { super(); }
public Interchanges(List<Interchange> interchange) {
super();
this.interchange = interchange;
}
public List<Interchange> getInterchange() {
return interchange;
}
public void setInterchange(List<Interchange> interchange) {
this.interchange = interchange;
}
}
public class Interchange {
private String depositId;
private Integer interchangeId;
//#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = SelfmedConstants.Dates.ENGLISH_DATETIME_PATTERN)
private String depositDate;
private String depositSubject;
private String numADS;
//#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = SelfmedConstants.Dates.ENGLISH_DATETIME_PATTERN)
private String adsDate;
private String alias;
//#JacksonXmlProperty(isAttribute = true)
private String version;
#JsonSerialize(using = BooleanSerializer.class)
#JsonDeserialize(using = BooleanDeserializer.class)
#JacksonXmlProperty(localName = "isTest")
private Boolean isTest;
#JacksonXmlProperty(localName = "name")
#JacksonXmlElementWrapper(localName = "deposantAccount")
private List<String> name;
private String teleProcedure;
private StatesHistory statesHistory;
#JacksonXmlProperty(localName = "declarationId")
#JacksonXmlElementWrapper(localName = "declarationIds")
private List<String> declarationId;
public Interchange() {
}
public Interchange(String depositId, Integer interchangeId, String depositDate, String depositSubject, String numADS,
String adsDate, String alias, String version, Boolean isTest, List<String> name, String teleProcedure,
StatesHistory statesHistory, List<String> declarationId) {
this();
this.depositId = depositId;
this.interchangeId = interchangeId;
this.depositDate = depositDate;
this.depositSubject = depositSubject;
this.numADS = numADS;
this.adsDate = adsDate;
this.alias = alias;
this.version = version;
this.isTest = isTest;
this.name = name;
this.teleProcedure = teleProcedure;
this.statesHistory = statesHistory;
this.declarationId = declarationId;
}
public String getDepositId() {
return depositId;
}
public void setDepositId(String depositId) {
this.depositId = depositId;
}
public Integer getInterchangeId() {
return interchangeId;
}
public void setInterchangeId(Integer interchangeId) {
this.interchangeId = interchangeId;
}
public String getDepositDate() {
return depositDate;
}
public void setDepositDate(String depositDate) {
this.depositDate = depositDate;
}
public String getDepositSubject() {
return depositSubject;
}
public void setDepositSubject(String depositSubject) {
this.depositSubject = depositSubject;
}
public String getNumADS() {
return numADS;
}
public void setNumADS(String numADS) {
this.numADS = numADS;
}
public String getAdsDate() {
return adsDate;
}
public void setAdsDate(String adsDate) {
this.adsDate = adsDate;
}
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public Boolean getIsTest() {
return isTest;
}
public void setIsTest(Boolean isTest) {
this.isTest = isTest;
}
public void setIsTest(String isTest) {
this.isTest = Boolean.valueOf(isTest);
}
public List<String> getName() {
return name;
}
public void setName(List<String> name) {
this.name = name;
}
public String getTeleProcedure() {
return teleProcedure;
}
public void setTeleProcedure(String teleProcedure) {
this.teleProcedure = teleProcedure;
}
public StatesHistory getStatesHistory() {
return statesHistory;
}
public void setStatesHistory(StatesHistory statesHistory) {
this.statesHistory = statesHistory;
}
public List<String> getDeclarationId() {
return declarationId;
}
public void setDeclarationId(List<String> declarationId) {
this.declarationId = declarationId;
}
}
As you can see in the Interchange class, I try some stuff but nothing work.
I generate my class like that :
JacksonXmlModule xmlModule = new JacksonXmlModule();
xmlModule.setDefaultUseWrapper(false);
XmlMapper xmlMapper = new XmlMapper(xmlModule);
xmlMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
xmlMapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES);
System.out.println(responseAsString);
Envelope envelope = xmlMapper.readValue(responseAsString, new TypeReference<>() {
But when I try to parse my content, I got this exception :
Cannot construct instance of payload.response.Interchange (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('false')
at [Source: (StringReader); line: 20, column: 28] (through reference chain: payload.response.Envelope["Body"]->payload.response.Body["wsResponse"]->payload.response.WsResponse["response"]->payload.response.Response["successfullResponse"]->payload.response.SuccessfulResponse["interchanges"]->payload.response.Interchanges["interchange"]->java.util.ArrayList[1])
I try a lot of things but nothing work so I'm wondering if the problem may be not here...
If you have any solution or leads to explore, please let me know !
Thank.
According to JavaBean spec you have to name getter isTest().

Retrofit + Observable - Expected BEGIN_ARRAY but was BEGIN_OBJECT

I'm trying to use New York Times API with Retrofit using Observable. But I'm getting this error when trying to use datas.
Can someone help me see where I'm wrong, please ?
Here is my ApiServices interface:
#GET("svc/topstories/v2/home.json?api-key=HiddenApiKeyJustForThisMessage")
Observable<TopStoryResult> getTopStories();
#GET("svc/topstories/v2/home.json?api-key=HiddenApiKeyJustForThisMessage")
Observable<List<NewsItem>> getResults();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.nytimes.com/")
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
Here is my ApiStreams class
public static Observable<TopStoryResult> streamFetchTopStories(){
ApiServices mApiServices = ApiServices.retrofit.create(ApiServices.class);
return mApiServices.getTopStories()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.timeout(10, TimeUnit.SECONDS);
}
public static Observable<List<NewsItem>> streamFetchNews(){
ApiServices mApiServices = ApiServices.retrofit.create(ApiServices.class);
return mApiServices.getResults()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.timeout(10, TimeUnit.SECONDS);
}
And this is what I'm trying to do in my MainActivity. For now I just want to display in a TextView the list of each Title...
//------------------------
// Update UI
//------------------------
private void updateUIWhenStartingHttpRequest() {
this.textView.setText("Downloading...");
}
private void updateUIWhenStopingHttpRequest(String response) {
this.textView.setText(response);
}
//------------------------
// Rx Java
//------------------------
private void executeRequestWithRetrofit(){
this.updateUIWhenStartingHttpRequest();
this.disposable = ApiStreams.streamFetchNews()
.subscribeWith(new DisposableObserver<List<NewsItem>>(){
#Override
public void onNext(List<NewsItem> topStories) {
Log.e("TAG", "On Next");
updateUIWithResult(topStories);
}
#Override
public void onError(Throwable e) {
Log.e("ERROR", Log.getStackTraceString(e));
}
#Override
public void onComplete() {
Log.e("TAG", "On Complete !");
}
});
}
private void updateUIWithResult(List<NewsItem> newsItemList){
StringBuilder mStringBuilder = new StringBuilder();
for (NewsItem news : newsItemList){
Log.e("TAG", "UPDATE UI" + news.getTitle());
mStringBuilder.append("- " + news.getTitle() + "\n");
}
updateUIWhenStopingHttpRequest(mStringBuilder.toString());
}
[EDIT]
There are my two models for TopStories and NewsItem
TopStories:
private String status;
private String copyright;
private String section;
private String lastUpdated;
private Integer numResults;
private List<NewsItem> results = null;
public String getStatus() {return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getCopyright() {
return copyright;
}
public void setCopyright(String copyright) {
this.copyright = copyright;
}
public String getSection() {
return section;
}
public void setSection(String section) {
this.section = section;
}
public String getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(String lastUpdated) {
this.lastUpdated = lastUpdated;
}
public Integer getNumResults() {
return numResults;
}
public void setNumResults(Integer numResults) {
this.numResults = numResults;
}
public List<NewsItem> getResults() {
return results;
}
public void setResults(List<NewsItem> results) {
this.results = results;
}
NewsItem:
private String section;
private String subsection;
private String title;
private String url;
private String byline;
private String updated_date;
private String created_date;
private String published_date;
private String material_type_facet;
private String kicker;
#SerializedName("abstract")
private String abstract_string;
private List<Multimedia> multimedia;
private transient String des_facet;
private transient String org_facet;
private transient String per_facet;
private transient String geo_facet;
public NewsItem() {
}
public NewsItem(String url) {
this.url = url;
}
public NewsItem(String section, String subsection, String title, String url, String byline, String updated_date, String created_date, String published_date, String material_type_facet, String kicker) {
this.section = section;
this.subsection = subsection;
this.title = title;
this.url = url;
this.byline = byline;
this.updated_date = updated_date;
this.created_date = created_date;
this.published_date = published_date;
this.material_type_facet = material_type_facet;
this.kicker = kicker;
}
public String getSection() {
return section;
}
public void setSection(String section) {
this.section = section;
}
public String getSubsection() {
return subsection;
}
public void setSubsection(String subsection) {
this.subsection = subsection;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getByline() {
return byline;
}
public void setByline(String byline) {
this.byline = byline;
}
public String getUpdated_date() {
return updated_date;
}
public void setUpdated_date(String updated_date) {
this.updated_date = updated_date;
}
public String getCreated_date() {
return created_date;
}
public void setCreated_date(String created_date) {
this.created_date = created_date;
}
public String getPublished_date() {
return published_date;
}
public void setPublished_date(String published_date) {
this.published_date = published_date;
}
public String getMaterial_type_facet() {
return material_type_facet;
}
public void setMaterial_type_facet(String material_type_facet) {
this.material_type_facet = material_type_facet;
}
public String getKicker() {
return kicker;
}
public void setKicker(String kicker) {
this.kicker = kicker;
}
public String getAbstract() {
return abstract_string;
}
public void setAbstract(String abstract_string) {
this.abstract_string = abstract_string;
}
public List<Multimedia> getMultimedia() {
return multimedia;
}
public void setMultimedia(List<Multimedia> multimedia) {
this.multimedia = multimedia;
}
public String getDes_facet() {
return des_facet;
}
public void setDes_facet(String des_facet) {
this.des_facet = des_facet;
}
public String getOrg_facet() {
return org_facet;
}
public void setOrg_facet(String org_facet) {
this.org_facet = org_facet;
}
public String getPer_facet() {
return per_facet;
}
public void setPer_facet(String per_facet) {
this.per_facet = per_facet;
}
public String getGeo_facet() {
return geo_facet;
}
public void setGeo_facet(String geo_facet) {
this.geo_facet = geo_facet;
}
Here is what the JSON looks like:
JSON
First when I tried this one with Github user API, it works fine. But I can't figure out where I'm wrong there...
Is anybody can help me please ?
Thanks a lot !
Expected BEGIN_ARRAY but was BEGIN_OBJECT
this means you are trying to a get a JSON Array as a List in JAVA but the api sent you a JSON OBJECT. So I cannot gather enough information but if I have to guess you should change this
#GET("svc/topstories/v2/home.json?api-key=HiddenApiKeyJustForThisMessage")
Observable<List<NewsItem>> getResults();
to
#GET("svc/topstories/v2/home.json?api-key=HiddenApiKeyJustForThisMessage")
Observable<NewsItemObject> getResults();
NewsItemObject is the Class that wraps NewsItem
In your ApiServices interface you expect that getResults() returns Observable<List<NewsItem>>. Based on JSON you getting back this is not gonna work, because your root JSON element is Object, not an Array.
You have to create new wrapper Class (ResultsWrapper) with "results" field type of List<NewsItem>. Your method in ApiServices interface will then be:
#GET("svc/topstories/v2/home.json?api-key=HiddenApiKeyJustForThisMessage")
Observable<ResultsWrapper> getResults();
That is what "Expected BEGIN_ARRAY but was BEGIN_OBJECT" says to you.

Query Parameters are not getting mapped

I have a REST endpoint as shown below.
#Path("/consumers")
#Produces("application/x.com.abc.pqr.audit.v2+json")
#Consumes("application/x.com.abc.pqr.audit.v2+json")
public interface ConsumerEndpoint {
#GET
#Path("paged")
Page<Module> getConsumersOfDependencyByPage(#BeanParam ConsumerQueryParams params);
}
As you can see above, I am using #BeanParam to map the query parameters passed from the front end side.
The ConsumerQueryParams class is shown below.
public class ConsumerQueryParams implements Serializable{
private static final long serialVersionUID = 6440255704974023223L;
#QueryParam("pageNum") #DefaultValue("1") private int pageNum;
#QueryParam("pageSize") #DefaultValue("25") private int pageSize;
#QueryParam("groupId") private String groupId;
#QueryParam("artifactId") private String artifactId;
#QueryParam("version") private String version;
#QueryParam("groupIdFilter") private String groupIdFilter;
#QueryParam("artifactIdFilter") private String artifactIdFilter;
#QueryParam("versionFilter") private String versionFilter;
public ConsumerQueryParams() {
}
private ConsumerQueryParams(Builder builder) {
this.pageNum = builder.pageNum;
this.pageSize = builder.pageSize;
this.groupId = builder.groupId;
this.artifactId = builder.artifactId;
this.version = builder.version;
this.groupIdFilter = builder.groupIdFilter;
this.artifactIdFilter = builder.artifactIdFilter;
this.versionFilter = builder.versionFilter;
}
public int getPageNum() {
return pageNum;
}
public int getPageSize() {
return pageSize;
}
public String getGroupId() {
return groupId;
}
public String getArtifactId() {
return artifactId;
}
public String getVersion() {
return version;
}
public String getGroupIdFilter() {
return groupIdFilter;
}
public String getArtifactIdFilter() {
return artifactIdFilter;
}
public String getVersionFilter() {
return versionFilter;
}
#Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(!(obj instanceof ConsumerQueryParams))
return false;
ConsumerQueryParams other = (ConsumerQueryParams) obj;
return Objects.equals(pageNum, other.pageNum) &&
Objects.equals(pageSize, other.pageSize) &&
Objects.equals(groupId, other.groupId) &&
Objects.equals(artifactId, other.artifactId) &&
Objects.equals(version, other.version) &&
Objects.equals(groupIdFilter, other.groupIdFilter) &&
Objects.equals(artifactIdFilter, other.artifactIdFilter) &&
Objects.equals(versionFilter, other.versionFilter);
}
#Override
public int hashCode() {
return Objects.hash(pageNum, pageSize, groupId, artifactId, version, groupIdFilter, artifactIdFilter, versionFilter);
}
public static class Builder {
private int pageNum;
private int pageSize;
private String groupId;
private String artifactId;
private String version;
private String groupIdFilter;
private String artifactIdFilter;
private String versionFilter;
public Builder(int pageNum, int pageSize, String groupId, String artifactId) {
Preconditions.checkArgument(pageNum > 0, "pageNum must be greater than 0.");
Preconditions.checkArgument(pageSize > 0, "pageSize must be greater than 0.");
Preconditions.checkNotNull(groupId, "groupId is null");
Preconditions.checkNotNull(artifactId, "artifactId is null");
this.pageNum = pageNum;
this.pageSize = pageSize;
this.groupId = groupId;
this.artifactId = artifactId;
}
public Builder setVersion(String version) {
this.version = version;
return this;
}
public Builder setGroupIdFilter(String groupIdFilter) {
this.groupIdFilter = groupIdFilter;
return this;
}
public Builder setArtifactIdFilter(String artifactIdFilter) {
this.artifactIdFilter = artifactIdFilter;
return this;
}
public Builder setVersionFilter(String versionFilter) {
this.versionFilter = versionFilter;
return this;
}
public ConsumerQueryParams build() {
return new ConsumerQueryParams(this);
}
}
}
You can see that I am using the Builder pattern to set the variables.
I am using the below url to access the above specified endpoint.
http://localhost:8080/rest/api/consumers/paged?groupId=org.slf4j&artifactId=slf4j-api&groupIdFilter=sdlc
Everything works fine. I am able to get the data on Postman successfully.
Now I have a requirement where I need to rename the groupIdFilter, artifactIdFilter, versionFilter query params in ConsumerQueryParams class to consumerGroupIdFilter, consumerArtifactIdFilter and consumerVersionFilter respectively.
After changing the variable names in ConsumerQueryParams class, it looks like this:
public class ConsumerQueryParams implements Serializable{
private static final long serialVersionUID = 6440255704974023223L;
#QueryParam("pageNum") #DefaultValue("1") private int pageNum;
#QueryParam("pageSize") #DefaultValue("25") private int pageSize;
#QueryParam("groupId") private String groupId;
#QueryParam("artifactId") private String artifactId;
#QueryParam("version") private String version;
#QueryParam("groupIdFilter") private String consumerGroupIdFilter;
#QueryParam("artifactIdFilter") private String consumerArtifactIdFilter;
#QueryParam("versionFilter") private String consumerVersionFilter;
public ConsumerQueryParams() {
}
private ConsumerQueryParams(Builder builder) {
this.pageNum = builder.pageNum;
this.pageSize = builder.pageSize;
this.groupId = builder.groupId;
this.artifactId = builder.artifactId;
this.version = builder.version;
this.consumerGroupIdFilter = builder.consumerGroupIdFilter;
this.consumerArtifactIdFilter = builder.consumerArtifactIdFilter;
this.consumerVersionFilter = builder.consumerVersionFilter;
}
public int getPageNum() {
return pageNum;
}
public int getPageSize() {
return pageSize;
}
public String getGroupId() {
return groupId;
}
public String getArtifactId() {
return artifactId;
}
public String getVersion() {
return version;
}
public String getConsumerGroupIdFilter() {
return consumerGroupIdFilter;
}
public String getConsumerArtifactIdFilter() {
return consumerArtifactIdFilter;
}
public String getConsumerVersionFilter() {
return consumerVersionFilter;
}
#Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(!(obj instanceof ConsumerQueryParams))
return false;
ConsumerQueryParams other = (ConsumerQueryParams) obj;
return Objects.equals(pageNum, other.pageNum) &&
Objects.equals(pageSize, other.pageSize) &&
Objects.equals(groupId, other.groupId) &&
Objects.equals(artifactId, other.artifactId) &&
Objects.equals(version, other.version) &&
Objects.equals(consumerGroupIdFilter, other.consumerGroupIdFilter) &&
Objects.equals(consumerArtifactIdFilter, other.consumerArtifactIdFilter) &&
Objects.equals(consumerVersionFilter, other.consumerVersionFilter);
}
#Override
public int hashCode() {
return Objects.hash(pageNum, pageSize, groupId, artifactId, version, consumerGroupIdFilter, consumerArtifactIdFilter, consumerVersionFilter);
}
public static class Builder {
private int pageNum;
private int pageSize;
private String groupId;
private String artifactId;
private String version;
private String consumerGroupIdFilter;
private String consumerArtifactIdFilter;
private String consumerVersionFilter;
public Builder(int pageNum, int pageSize, String groupId, String artifactId) {
Preconditions.checkArgument(pageNum > 0, "pageNum must be greater than 0.");
Preconditions.checkArgument(pageSize > 0, "pageSize must be greater than 0.");
Preconditions.checkNotNull(groupId, "groupId is null");
Preconditions.checkNotNull(artifactId, "artifactId is null");
this.pageNum = pageNum;
this.pageSize = pageSize;
this.groupId = groupId;
this.artifactId = artifactId;
}
public Builder setVersion(String version) {
this.version = version;
return this;
}
public Builder setConsumerGroupIdFilter(String consumerGroupIdFilter) {
this.consumerGroupIdFilter = consumerGroupIdFilter;
return this;
}
public Builder setConsumerArtifactIdFilter(String consumerArtifactIdFilter) {
this.consumerArtifactIdFilter = consumerArtifactIdFilter;
return this;
}
public Builder setConsumerVersionFilter(String consumerVersionFilter) {
this.consumerVersionFilter = consumerVersionFilter;
return this;
}
public ConsumerQueryParams build() {
return new ConsumerQueryParams(this);
}
}
}
Now I am trying to access the same endpoint with the url:
http://localhost:8080/rest/api/consumers/paged?groupId=org.slf4j&artifactId=slf4j-api&consumerGroupIdFilter=sdlc
But this is not working. The consumerGroupIdFilter query param in the url is not being mapped to the consumerGroupIdFilter variable of the ConsumerQueryParams object, whereas groupId and artifactId gets mapped.
I am not sure why this is happening. As far as I know, the ConsumerQueryParams class has the correct code. All that I did was to change the variable names and updated the getters and setters in the Builder class.
Can anyone help me here.
The problem is that the url has the new name and the annotation has the old one
#QueryParam("groupIdFilter")
consumerGroupIdFilter

Hibernate one to many update with Spring HibernateTemplate

public class AfpProcessSummaryDetail implements Serializable {
private String srNo;
private String fileName;
private String status;
private String location;
private String comments;
private Character convertStatus;
private AfpProcessDetail afpProcessDetail;
public AfpProcessSummaryDetail() {
}
public AfpProcessSummaryDetail(String srNo, String fileName, String status, String location, String comments,
AfpProcessDetail afpProcessDetail) {
this.srNo = srNo;
this.fileName = fileName;
this.status = status;
this.location = location;
this.comments = comments;
this.afpProcessDetail = afpProcessDetail;
}
#ManyToOne
#JoinColumn(name = "PROCESSDETAIL")
public AfpProcessDetail getAfpProcessDetail() {
return afpProcessDetail;
}
AfpProcessDetail
public class AfpProcessDetail implements Serializable {
private String processID;
private String processDate;
private Integer fileCount;
private Integer successCount;
private Integer failureCount;
private Character active;
private Set<AfpProcessSummaryDetail> processSummaryDetails = new HashSet<AfpProcessSummaryDetail>(0);
public AfpProcessDetail() {
}
public AfpProcessDetail(String processID, String processDate, Integer fileCount, Integer successCount,
Integer failureCount) {
this.processID = processID;
this.processDate = processDate;
this.fileCount = fileCount;
this.successCount = successCount;
this.failureCount = failureCount;
}
public AfpProcessDetail(String processID, String processDate, Integer fileCount, Integer successCount,
Integer failureCount, Set<AfpProcessSummaryDetail> processSummaryDetails) {
this.processID = processID;
this.processDate = processDate;
this.fileCount = fileCount;
this.successCount = successCount;
this.failureCount = failureCount;
this.processSummaryDetails = processSummaryDetails;
}
#Column(name = "FAILURECOUNT")
public Integer getFailureCount() {
return failureCount;
}
public void setFailureCount(Integer failureCount) {
this.failureCount = failureCount;
}
#Column(name = "FILECOUNT")
public Integer getFileCount() {
return fileCount;
}
public void setFileCount(Integer fileCount) {
this.fileCount = fileCount;
}
#Column(name = "PROCESSDATE")
public String getProcessDate() {
return processDate;
}
public void setProcessDate(String processDate) {
this.processDate = processDate;
}
#Id
#Column(name = "PROCESSID", unique = true, nullable = false)
public String getProcessID() {
return processID;
}
public void setProcessID(String processID) {
this.processID = processID;
}
#Column(name = "SUCESSCOUNT")
public Integer getSuccessCount() {
return successCount;
}
public void setSuccessCount(Integer successCount) {
this.successCount = successCount;
}
#JoinColumn(name="PROCESSDETAIL")
#OneToMany(cascade=CascadeType.ALL,fetch = FetchType.EAGER)
public Set<AfpProcessSummaryDetail> getProcessSummaryDetails() {
return processSummaryDetails;
}
public void setProcessSummaryDetails(Set<AfpProcessSummaryDetail> processSummaryDetails) {
this.processSummaryDetails = processSummaryDetails;
}
Code for updating
public String updateSummaryDetails(ViewFile viewFile, String codeID) {
if (viewFile != null && codeID != null) {
HibernateTemplate transactionTemplate = new HibernateTemplate(sessionFactory, true);
Object result = transactionTemplate.execute(new HibernateCallback<Object>() {
#Override
public Object doInHibernate(org.hibernate.Session session) throws HibernateException, SQLException {
AfpProcessSummaryDetail processSummary =null,newProcessSummary =null;
AfpProcessDetail processDetail = (AfpProcessDetail)session.get(AfpProcessDetail.class,codeID);
List<FileProperty> fileList = viewFile.getFileList();
Set<AfpProcessSummaryDetail> setProcessSummary=new HashSet<AfpProcessSummaryDetail>();
Set<AfpProcessSummaryDetail> modSetProcessSummary=new HashSet<AfpProcessSummaryDetail>();
setProcessSummary =processDetail.getProcessSummaryDetails();
Iterator<AfpProcessSummaryDetail> itrProcessSumm=setProcessSummary.iterator();
int srNo = 0;
while (itrProcessSumm.hasNext()){
processSummary =(AfpProcessSummaryDetail)itrProcessSumm.next();
for (FileProperty fileProperty : fileList) {
newProcessSummary =new AfpProcessSummaryDetail();
newProcessSummary.setSrNo(codeID + "" + srNo);
newProcessSummary.setFileName(fileProperty.getName());
newProcessSummary.setLocation(fileProperty.getPath());
newProcessSummary.setComments(fileProperty.getComment());
newProcessSummary.setStatus(fileProperty.getStatus());
newProcessSummary.setConvertStatus(fileProperty.getConvertStatus());
newProcessSummary.setAfpProcessDetail(processDetail);
modSetProcessSummary.add(newProcessSummary);
/*if (processSummary.getFileName().trim().equals(fileProperty.getName().trim())){
System.out.println("Element removed");
itrProcessSumm.remove();
modSetProcessSummary.add(newProcessSummary);
break;
}*/
srNo++;
}
}
// setProcessSummary.addAll(modSetProcessSummary);
processDetail.setProcessSummaryDetails(modSetProcessSummary);
processDetail.setFailureCount(viewFile.getExceptionNo());
processDetail.setSuccessCount(viewFile.getSuccessNo());
processDetail.setActive(viewFile.getActive());
transactionTemplate.flush();
session.merge(processDetail);
System.out.println("updated successfully");
return codeID;
}
});
Desired result
I want to perform a one to many update -AfpProcessSummaryDetail which is related to AfpProcessDetail via Set. When I try to replace the set values for update it tries to update the primary key to null. If I don't replace the updates don't take place. If I set cascade it gives error -a different object with the same identifier value was already associated with the session:
[com.aurionpro.convertor.dto.AfpProcessSummaryDetail#15a236f‌​fc961];
nested exception is org.hibernate.NonUniqueObjectException: a
different object with the same identifier value was already associated
with the session.
Please suggest

Categories