Lucene Index on Document is not working by ClassBridge hook - java

Problem : When I am uploading a word document, I am able to search on title(Entered while uploading the document) and summary, but when I search using the some text in document I am getting the result.
I am using "hibernate-search-engine : 4.3.0.Final, lucene-core : 3.6.2"
POM.XML
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId>
<version>${hibernate.search.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-engine</artifactId>
<version>${hibernate.search.version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>3.6.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queries</artifactId>
<version>3.6.2</version>
<scope>runtime</scope>
</dependency>
Classes
#Entity
#SequenceGenerator(name = "sitepagecontent_seq", sequenceName = "SITEPAGECONTENT_SEQ")
#Indexed(index = "SitePageContent")
#FullTextFilterDef(name = "condition1", impl = StatusFilterFactory.class) //Filter factory with parameters
#Analyzer (impl = StandardAnalyzer.class)
#ClassBridge(name = "splitcontentfileupload",
index = Index.YES,
store = Store.YES,
impl = WordDocHandlerBridge.class,
params = #org.hibernate.search.annotations.Parameter(name = "padding", value = " ")
)
#Table(name = "SITE_PAGE_CONTENT")
public class SitePageContent extends BaseObject implements Comparable<SitePageContent> {
// Fields
private static final long serialVersionUID = -7424477214552600300L;
private Long id;
#IndexedEmbedded
private Content content;
#IndexedEmbedded
private SitePage sitePage;
private Long sequence;
Content.java
#Entity
#SequenceGenerator(name = "content_seq", sequenceName = "CONTENT_SEQ")
#Table(name = "CONTENT")
#VersionSupportModel
public class Content extends BaseObject implements Comparable<Content> {
// ------------------------------ FIELDS ------------------------------
// Fields
private static final long serialVersionUID = 1441591301055742001L;
private Long id;
#IndexedEmbedded
private UploadedFile uploadedFile;
#IndexedEmbedded
private ContentType contentType;
#Field(index = Index.YES, store = Store.YES, analyzer = #Analyzer(impl = StandardAnalyzer.class))
private String title;
private String prevTitle;
#Field(index = Index.YES, store = Store.YES, analyzer = #Analyzer(impl = StandardAnalyzer.class))
private String teaser;
private String prevTeaser;
private String linkedContentType;
private String linkedUrl;
private Boolean linkedContentPopup;
#Field(index = Index.YES, store = Store.YES)
private String status;
private EcommUser createdBy;
private EcommUser modifiedBy;
#Temporal(TemporalType.DATE)
private Date createdDate;
#Temporal(TemporalType.DATE)
private Date modifiedDate;
private String shared;
private String statusTemp;
private Set<Request> requests = new HashSet<Request>(0);
#ContainedIn
private Set<SitePageContent> sitePageContents = new HashSet<SitePageContent>(0);
private Integer version;
private Integer articleId;
private String summary;
#Field(index = Index.YES, store = Store.YES, analyzer = #Analyzer(impl = StandardAnalyzer.class))
private String description;
#Field(index = Index.YES, store = Store.YES, analyzer = #Analyzer(impl = StandardAnalyzer.class))
private String contactName;
#Field(index = Index.YES, store = Store.YES, analyzer = #Analyzer(impl = StandardAnalyzer.class))
private String contactPhone;
#Field(index = Index.YES, store = Store.YES, analyzer = #Analyzer(impl = StandardAnalyzer.class))
private String contactEmail;
#Field(index = Index.YES, store = Store.YES, analyzer = #Analyzer(impl = StandardAnalyzer.class))
private String contactPostalAddress;
WordDocHandlerBridge.java
public class WordDocHandlerBridge implements FieldBridge, ParameterizedBridge {
protected final Log log = LogFactory.getLog(getClass());
public static String paddingProperty = "padding";
private String padding = "";
public void setParameterValues(Map arg0) {
Object padding = arg0.get( paddingProperty );
if (padding != null) {
this.padding = (String) padding;
}
}
public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
String fieldValue = "";
SitePageContent sitCont = (SitePageContent) value;
Content cont = sitCont.getContent();
UploadedFile upF = cont.getUploadedFile();
if (upF != null) {
String fieldValue1 = upF.getFileContentType();
if ( fieldValue1 == null ) {
fieldValue1 = "";
}
byte[] fieldValue2 = upF.getFileContent();
if ( fieldValue2 == null ) {
fieldValue2 = new byte[0];
}
fieldValue = convertFile2String(fieldValue1, fieldValue2);
} else {
fieldValue = "";
}
Field field = new Field( name, fieldValue, luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector() );
field.setBoost( luceneOptions.getBoost() );
document.add( field );
}
private String convertFile2String(String type, byte[] content) {
}
When I debugged "WordDocHandlerBridge.java", I am able to see my content is set in Field and added to document, but when I search I am not getting it.
Note : There is a standolne program which recreates the Index for me, If I recreated , I can see the result.
Can any one please help me resolve this.

I solved this, Method in WordDocHandlerBridge this class "convertFile2String", actually opens the file and reads the file and create a String to set the value in the Field, problem is Code is not closing the "File" and some how Luecene is not updating , but when I added close to the PDF and POI files it all started working.
Point here is it used to work with Luecene 2.4, this might be new feature in Lucene 3.6, which is good one.

Related

java.util.NoSuchElementException: No value present

So my problem is in a Test, when I call the method to test it gives this error:
java.util.NoSuchElementException: No value present
at java.base/java.util.Optional.get(Optional.java:143)
at com.MD.Medicine.Services.SaveService.savePlans(SaveService.java:57)
at com.MD.Medicine.Services.SaveServiceTest.testSavePlans_failPills(SaveServiceTest.java:99)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
My test:
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SaveServiceTest {
#MockBean
private MedsRepo medsRepo;
#MockBean
private PlansRepo plansRepo;
#MockBean
private PlanDayRepo planDayRepo;
#Autowired
private SaveService saveService;
#Test
void testSavePlans_failPills() {
LocalDate date = LocalDate.now();
Date date3 = new Date(1673740800000L);
Set<PlanDay> setPlans = new HashSet<>();
Plans plans = new Plans(1, setPlans);
BigDecimal price = new BigDecimal(8.00);
Meds meds = new Meds(1, "Brufen", price, "Pain", 200, date, setPlans);
when(medsRepo.getReferenceById(meds.getMedsId())).thenReturn(meds);
int pillNumber = meds.getPillNumber();
List<PlanDay> planList3 = new ArrayList<PlanDay>();
PlanDay planDay3 = new PlanDay(1, date3, "Tuesday", plans, meds, 50000);
planList3.add(planDay3);
String expected3 = saveService.savePlans(planList3);
assertThat(expected3).isEqualTo("Error: No piils available (Existing Pills: " + pillNumber + ")");
}
When it gets in * String expected3 = saveService.savePlans(planList3);* it stops and prints the error.
The method:
public String savePlans(List<PlanDay> plans) throws Error {
//long planIdVerify = plans.get(0).getPlanDaysId();
Date firstDate = plans.get(0).getPlanDate();
long todayMili = System.currentTimeMillis();
long dateLimitMili = firstDate.getTime() + 604800000;
long planId = plans.get(0).getPlans().getPlanId();
Plans plansWithId = new Plans();
plansWithId.setPlanId(planId);
plansRepo.save(plansWithId);
for (int i = 0; i < plans.size(); i++) {
long planDateInMili = plans.get(i).getPlanDate().getTime();
//long planIdMultiVerify = plans.get(i).getPlanDaysId();
if (planDateInMili <= dateLimitMili && todayMili<planDateInMili ) {
PlanDay planDay = plans.get(i);
long medsId = planDay.getMeds().getMedsId();
int medsToTake = planDay.getMedsToTake();
int pillNumber = medsRepo.getReferenceById(medsId).getPillNumber();
int pillUpdate = pillNumber - medsToTake;
Meds updatePlanDay = medsRepo.findById(medsId).get();
if (pillUpdate > 0) {
updatePlanDay.setPillNumber(pillUpdate);
} else {
return "Error: No piils available (Existing Pills: " + pillNumber + ")";
}
planDayRepo.save(planDay);
} else {
return "Week time interval not correct/Invalid planId (only one plan can be saved)";
}
}
return "Saved Successfully";
}
and my entities:
#Data
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name = "meds")
#JsonIgnoreProperties(value = { "days" })
public class Meds {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long medsId;
#Column
private String medsName;
#Column
private BigDecimal price;
#Column
private String category;
#Column
private int pillNumber;
#Column
#CreationTimestamp
private LocalDate medsDate;
#OneToMany(mappedBy = "meds", cascade = {CascadeType.REMOVE}, fetch = FetchType.LAZY)
#OnDelete(action = OnDeleteAction.CASCADE)
private Set<PlanDay> days = new HashSet<PlanDay>();
}
#Data
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name = "planDay")
#JsonIgnoreProperties(value = { "planDaysId" })
public class PlanDay {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long planDaysId;
#Column
private Date planDate;
#Column
private String weekday;
#ManyToOne
#JoinColumn(name = "planId", nullable = false)
private Plans plans;
#ManyToOne
#JoinColumn(name = "medsId", nullable = false)
private Meds meds;
#Column
private int medsToTake;
}
I have been looking for a solution and the orElse() method was one of the options but I can't make it work.. What would be a solution for this problem?
Kind Regards.
MedsRepo is a MockBean when you call medsRepo.findById(medsId) it will return an empty optional because you have no when for that method.
int pillNumber = medsRepo.getReferenceById(medsId).getPillNumber(); //extract the Meds as a variable and keep using this
int pillUpdate = pillNumber - medsToTake;
Meds updatePlanDay = medsRepo.findById(medsId).get(); //trying to get the same as you did above
Should be
Meds updatePlanDay = medsRepo.getReferenceById(medsId);
int pillNumber = updatePlanDay.getPillNumber();
int pillUpdate = pillNumber - medsToTake;
//Meds updatePlanDay = medsRepo.findById(medsId).get(); no longer needed
Also on a different note you should look into the difference between findById and getReferenceById and what happens when there is no Meds with that medsId

OpenCSV : throws error capturing csv header on parse method

My OpenCSV Version is : 5.5.2
I upload a CSV file and call the parseCSVFile method like this
List<CSVCouponData> csvData = CSVFileHelper.parseCSVFile(multipartFile.getInputStream());
Following is my code
public static List<CSVCouponData> parseCSVFile(InputStream inputStream) throws IOException {
CSVReader reader = null;
List<CSVCouponData> rec = null;
try {
reader = new CSVReader(new InputStreamReader(inputStream));
HeaderColumnNameMappingStrategy<CSVCouponData> beanStrategy = new HeaderColumnNameMappingStrategy<>();
beanStrategy.setType(CSVCouponData.class);
CsvToBean<CSVCouponData> csvToBean = new CsvToBean<>();
csvToBean.setCsvReader(reader);
csvToBean.setMappingStrategy(beanStrategy);
csvToBean.setIgnoreEmptyLines(true);
rec = csvToBean.parse();
} finally {
if(reader != null)
reader.close();
}
return rec;
}
The following is my CSVCouponData
public class CSVCouponData {
#CsvBindByName(column = "name", required = true)
private String name;
#CsvBindByName(column = "coupon-type", required = true)
private String couponType;
#CsvBindByName(column = "incentive-program-id", required = true)
private String programId;
#CsvBindByName(column = "coupons-amount")
private Long couponsAmount;
#CsvBindByName(column = "coupon-benefits.unit-of-measure")
private String unitOfMeasure;
#CsvBindByName(column = "coupon-benefits.benefit-target-party")
private String benefitTargetParty;
#CsvBindByName(column = "coupon-benefits.characteristics")
private String characteristics;
#CsvBindByName(column = "coupon-benefits.benefit-type")
private String benefitType;
#CsvBindByName(column = "coupon-benefits.benefit-confirmation-source")
private String benefitConfirmationSource;
#CsvBindByName(column = "coupon-benefits.benefit-currency")
private String benefitCurrency;
#CsvBindByName(column = "coupon-benefits.benefit-amount")
private String benefitAmount;
#CsvBindByName(column = "coupon-benefits.benefit-description", required = true)
private String benefitDescription;
#CsvBindByName(column = "benefit-catalog-info.product-offering-ids")
private String productOfferingIds;
#CsvBindByName(column = "benefit-catalog-info.discount-id")
private String discountId;
#CsvBindByName(column = "benefit-catalog-info.cardinality.min")
private Integer cardinalityMin;
#CsvBindByName(column = "benefit-catalog-info.cardinality.max")
private Integer cardinalityMax;
#CsvBindByName(column = "external-id", required = true)
private String externalId;
#CsvBindByName(column = "valid_from", required = true)
private String validFrom;
#CsvBindByName(column = "valid_to", required = true)
private String validTo;
#CsvBindByName(column = "sales_context.batch-id")
private String batchId;
#CsvBindByName(column = "sales_context.campaign-id")
private String campaignId;
#CsvBindByName(column = "sales_context.chain-id")
private String chainId;
#CsvBindByName(column = "sales_context.channel")
private String channel;
#CsvBindByName(column = "sales_context.dealer-id")
private String dealerId;
#CsvBindByName(column = "sales_context.sales-type")
private String salesType;
#CsvBindByName(column = "sales_context.salesperson-id")
private String salesPersonId;
#CsvBindByName(column = "incentive-coupon-batches.partner-name", required = true)
private String partnerName;
#CsvBindByName(column = "incentive-coupon-batches.redemption-specification-owner", required = true)
private String redemptionSpecificationOwner;
#CsvBindByName(column = "incentive-coupon-batches.distribution-specification.owner", required = true)
private String distributionSpecificationOwner;
#CsvBindByName(column = "incentive-coupon-batches.distribution-specification.method", required = true)
private String distributionSpecificationMethod;
#CsvBindByName(column = "incentive-coupons.code", required = true)
private String code;
#CsvBindByName(column = "brand")
private String brand;
When i debug my code it throws and error at this line rec = csvToBean.parse(); with this error
java.lang.RuntimeException: Error capturing CSV header!
Even though i have provided all the fields which are marked required =true in my CsvCouponData, i see this error
com.opencsv.exceptions.CsvRequiredFieldEmptyException: Header is missing required fields [INCENTIVE-PROGRAM-ID]. The list of headers encountered is [ incentive-program-id,coupon-type,name,coupon-benefits.benefit-description,external-id,valid_from,valid_to,incentive-coupon-batches.partner-name,incentive-coupon-batches.redemption-specification-owner,incentive-coupon-batches.distribution-specification.owner,incentive-coupon-batches.distribution-specification.method,incentive-coupons.code].
Initially i had opencsv version 4.4 and did not have this error.
But when i upgraded the version to 5.5.2 i started seeing this error. I have also upgraded to the latest version which is 5.6, but still no luck.
I have gone through this link which is almost similar to the error i get, but no solutions have helped
OpenCSV throws Error capturing CSV header on parse
Any suggestions please
I have figured out the issue. The problem is not with the code, but the problem was the file format. The csv file which we were uploading was saved with the following format .csv(utf-8). Then changing the format of the file to .csv solved the issue.

Error while mapping xml to java using jackson: com.fasterxml.jackson.databind.exc.MismatchedInputException

I have an xml file that I have to parse and map to a Java class:
<udm.DeployedApplication id="ID" token="TOKEN" created-by="AUTHOR" created-at="2018-12-10T10:02:36.264+0000" last-modified-by="AUTHOR" last-modified-at="2019-05-21T18:16:07.492+0000">
<version ref="REF"/>
<environment ref="REF2"/>
<deployeds>
<ci ref="ref3"/>
</deployeds>
<orchestrator>
<value>value1</value>
<value>value2</value>
<value>value3</value>
</orchestrator>
<optimizePlan>true</optimizePlan>
<boundConfigurationItems/>
<unresolvedPlaceholders/>
<undeployDependencies>false</undeployDependencies>
<bpcForceUndeployment>false</bpcForceUndeployment>
<enableAutomaticOrchestrators>true</enableAutomaticOrchestrators>
<hotDeploy>false</hotDeploy>
</udm.DeployedApplication>
XlDeployCi.java:
#JsonIgnoreProperties(ignoreUnknown = true)
public class XlDeployCi {
#JacksonXmlProperty(localName = "id")
private String id;
#JacksonXmlProperty(localName = "token")
private String token;
#JacksonXmlProperty(localName = "created-by")
private String createdBy;
#JacksonXmlProperty(localName = "created-at")
private Timestamp createdAt;
#JacksonXmlProperty(localName = "last-modified-by")
private String modifiedBy;
#JacksonXmlProperty(localName = "last-modified-at")
private Timestamp modifiedAt;
#JacksonXmlProperty(localName = "version")
private XlDeployRef version;
#JacksonXmlProperty(localName = "environment")
private XlDeployRef environment;
#JacksonXmlProperty(localName = "deployeds")
private List<XlDeployRef> deployeds;
#JacksonXmlProperty(localName = "orchestrator")
private XlDeployOrchestrator orchestrator;
#JacksonXmlProperty(localName = "boundConfigurationItems")
private String boundConfigurationItems;
#JacksonXmlProperty(localName = "unresolvedPlaceholders")
private String unresolvedPlaceholders;
#JacksonXmlProperty(localName = "optimizePlan")
private Boolean optimizePlan;
#JacksonXmlProperty(localName = "undeployDependencies")
private Boolean undeployDependencies;
#JacksonXmlProperty(localName = "bpcForceUndeployment")
private Boolean bpcForceUndeployment;
#JacksonXmlProperty(localName = "enableAutomaticOrchestrators")
private Boolean enableAutomaticOrchestrators;
#JacksonXmlProperty(localName = "hotDeploy")
private Boolean hotDeploy;
}
XlDeployRef.java:
#JsonIgnoreProperties(ignoreUnknown = true)
public class XlDeployRef {
#JacksonXmlProperty(localName = "ref")
private String ref;
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
}
XlDeployOrchestrator.java:
#JsonIgnoreProperties(ignoreUnknown = true)
public class XlDeployOrchestrator {
#JacksonXmlProperty(localName = "value")
private ArrayList <String> value;
}
TestXml.java:
public class TestXml {
private static final String FILE_PATH = "src/main/resources/xmlRest.txt";
#Test
public void testXml() throws JsonParseException, JsonMappingException, IOException {
String xmlFile = readFile(FILE_PATH, Charset.defaultCharset());
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.setDefaultUseWrapper(false);
xmlMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
List<XlDeployCi> list = xmlMapper.readValue(xmlFile, new TypeReference<List<XlDeployCi>>() {});
list.forEach(System.out::println);
}
private static String readFile(String path, Charset encoding) throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
}
The error I get :
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of package.XlDeployCi
(although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('true')
EDIT
I tried few things, and found something strange, I changed my xml file to :
<udm.DeployedApplication id="Environments/UAT/Env/UAT-DCS_APL/dcs-application" token="b3dd242b-66ff-4548-81b1-062c8a1152be" created-by="ext.pcuciniello" created-at="2018-12-10T10:02:36.264+0000" last-modified-by="ext.pcuciniello" last-modified-at="2019-05-21T18:16:07.492+0000">
<version ref="Applications/Shipping/Java/DCS/dcs-application/dcs1.8.5-20190521"/>
<environment ref="Environments/UAT/Env/UAT-DCS_APL"/>
<deployeds>
<ci ref="Infrastructure/UAT/WEBLO/UAT_DCS_APL_DOMAIN/DCS_UAT_CLUSTER/dcs-application"/>
</deployeds>
<hotDeploy>true</hotDeploy>
</udm.DeployedApplication>
Then, I changed the XlDeployCi.java file:
#JsonIgnoreProperties(ignoreUnknown = true)
public class XlDeployCi {
#JacksonXmlProperty(localName = "id")
private String id;
#JacksonXmlProperty(localName = "token")
private String token;
#JacksonXmlProperty(localName = "created-by")
private String createdBy;
#JacksonXmlProperty(localName = "created-at")
private Timestamp createdAt;
#JacksonXmlProperty(localName = "last-modified-by")
private String modifiedBy;
#JacksonXmlProperty(localName = "last-modified-at")
private Timestamp modifiedAt;
#JacksonXmlProperty(localName = "version")
private XlDeployRef version;
#JacksonXmlProperty(localName = "environment")
private XlDeployRef environment;
#JacksonXmlProperty(localName = "deployeds")
private List<XlDeployRef> deployeds;
#JacksonXmlProperty(localName = "hotDeploy")
public String hotDeploy;
#Override
public String toString() {
return "XlDeployCi [id=" + id + ", token=" + token + ", createdBy=" + createdBy + ", createdAt=" + createdAt
+ ", modifiedBy=" + modifiedBy + ", modifiedAt=" + modifiedAt + ", version=" + version
+ ", environment=" + environment + ", deployeds=" + deployeds + ", hotDeploy=" + hotDeploy + "]";
}
}
The error I get :
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of package.XlDeployCi
(although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('false')
But, If I remove the line <hotDeploy>false</hotDeploy>, it works correctly.
It's seems, I can't do something like <X>Y</Y>, I can only do stuff like <X Y="Z"/>.
I found the solution:My mistake, (a terrible one), was, that I forgot to change the type of the mapping class for the method xmlMapper.readValue(String content, Class<T> valueType).
Indeed, I set the class of the mapping object as new TypeReference<List<XlDeployCi>>() {}. You should do that to get a list, but actually, I only needed 1 object.
I leave this answer, in case someone makes the same mistake as me.

DynamoDB fetch query

#DynamoDBTable(tableName = "OrderDashboardMetadata")
public class OrderDashBoardMetaData {
private int position;
private Date ETA = null;
private List<String> notes;
#DynamoDBHashKey(attributeName = "queueName")
private String queueName;
#DynamoDBRangeKey(attributeName = "orderId")
private String orderId;
#DynamoDBIndexHashKey(globalSecondaryIndexName = "city")
private String city;
#DynamoDBIndexRangeKey(globalSecondaryIndexName = "city")
private String fcId;
#DynamoDBIndexHashKey(globalSecondaryIndexName = "orderState")
private String orderState;
#DynamoDBAttribute(attributeName = "action")
private String action;
#DynamoDBAttribute(attributeName = "createdTime")
private Date createdTime = new Date();
#DynamoDBAttribute(attributeName = "updatedTime")
private Date updatedTime = new Date();
Hi
I have a table structure like the one above.
What would be query to fetch results only that have
1) queueName -- > PFS
2) ETA --> greater than 1st jan 2017
3)order state -- PO
Kindly suggest full query for the above scenario in JAVA.
Since you have not annotated so assuming ETA is also an DDBAttribute
Map<String, AttributeValue> expValues = new HashMap<>();
expValues.put(":hv", new AttributeValue("PFS"));
expValues.put(":osv", new AttributeValue("PO"));
expValues.put(":etav", new AttributeValue("2017-01-01"));
QueryRequest q = new QueryRequest("OrderDashboardMetadata");
q.setKeyConditionExpression("queueName = :hv");
q.setFilterExpression("orderState = :osv and ETA > :etav");
q.setExpressionAttributeValues(expValues);
QueryResult r = dbClient.query(q);
Note: Dates are stored as S (string type). The Date values are stored as ISO-8601 formatted strings.

XML parsing returns 40 counts of IllegalAnnotationExceptions

I am trying to parse the XML response to an object but it throws exception.
The link of response is this:
<response>
<meta>
<per_page>10</per_page>
<total>20</total>
<geolocation>None</geolocation>
<took>8</took>
<page>1</page>
</meta>
<events>
<event>
...
</event>
<event>
...
</event>
....
</events>
</response>
Code
queryString = queryString.replaceAll(" ", "%20");
try {
URL page = new URL(queryString);
HttpURLConnection conn = (HttpURLConnection) page.openConnection();
conn.connect();
InputStreamReader in = new InputStreamReader(conn.getInputStream(),Charset.forName("UTF-8"));
this.response = (Response) JAXB.unmarshal(in, Response.class);
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
Exception
javax.xml.bind.DataBindingException: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 40
counts of IllegalAnnotationExceptions
Class has two properties of the same name "events"
this problem is related to the following location:
....
Object classes
#XmlRootElement(name = "Response")
public class Response {
#XmlElement(name="per_page")
private int per_page;
#XmlElement(name="total")
private int total;
#XmlElement(name="geolocation")
private String geolocation;
#XmlElement(name="took")
private int took;
#XmlElement(name="page")
private int page;
#XmlElement(name="events")
private List<Event> events = null;
**getters and setters**
Objects
#XmlRootElement(name="event")
public class Event {
#XmlElement(name = "links")
private String link;
#XmlElement(name = "id")
private int id;
#XmlElement(name = "stats")
private Stats stats;
#XmlElement(name = "title")
private String title;
#XmlElement(name = "announce_date")
private String announce_date;
#XmlElement(name = "score")
private float score;
#XmlElement(name = "date_tbd")
private boolean date_tbd;
#XmlElement(name = "type")
private String type;
#XmlElement(name = "datetime_local")
private String datetime_local;
#XmlElement(name = "visible_until_utc")
private String visible_util_utc;
#XmlElement(name = "time_tbd")
private boolean time_tbd;
#XmlElement(name = "taxonomies")
private List<Taxonomie> taxonomies;
#XmlElement(name = "performers")
private List<Performer> performers;
#XmlElement(name = "url")
private String url;
#XmlElement(name = "created_at")
private String created_at;
#XmlElement(name = "venue")
private Venue venue;
#XmlElement(name = "short_title")
private String short_title;
#XmlElement(name = "datetime_utc")
private String datetime_utc;
#XmlElement(name = "datetime_tbd")
private boolean datetime_tbd;
**getters and setters**
By default JAXB implementations treat public fields and properties as mapped. When you annotate a non-public field it also becomes mapped. Then if you have a mapped field an property with the same name you will get this exception.
When you annotate fields you need to annotate your class with #XmlAccessorType(XmlAccessType.FIELD).
http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
Note:
You are currently adding more annotations on your model than you need to. Since JAXB is configuration by exception you only need to add annotations where you want the XML representation to differ from the default.
http://blog.bdoughan.com/2012/07/jaxb-no-annotations-required.html

Categories

Resources