UnrecognizedPropertyException for a ghost attribute in XML - java

I'm currently writing a program to display weather data from the MSC. I'm using Jackson 2.9.6 (as a different library didn't work on other versions) and the XML extension (also in Jackson 2.9.6) to access and display the data provided online, which is in XML format.
I'm running into problems with representing the times given from the API. My code works until it hits the month, it seems.
This is what the test date data looks like.
<dateTime name="xmlCreation" zone="UTC" UTCOffset="0">
<year>2022</year>
<month name="April">04</month>
<day name="Saturday">02</day>
<hour>20</hour>
<minute>50</minute>
<timeStamp>20220402205000</timeStamp>
<textSummary>Saturday April 02, 2022 at 20:50 UTC</textSummary>
</dateTime>
And this is what my POJO class for the data looks like.
package city_weather;
import com.fasterxml.jackson.dataformat.xml.annotation.*;
public class DateTime {
#JacksonXmlProperty(isAttribute = true)
private String name;
#JacksonXmlProperty(isAttribute = true)
private String zone;
#JacksonXmlProperty(isAttribute = true)
private String UTCOffset;
#JacksonXmlProperty(localName = "year")
private int year;
#JacksonXmlProperty(localName = "month")
private Month month;
#JacksonXmlProperty(localName = "day")
private Day day;
private int hour;
private int minute;
private String timeStamp;
private String textSummary;
}
class Month {
#JacksonXmlProperty(localName = "month")
public int month;
public String name;
}
class Day {
#JacksonXmlProperty(localName = "day")
public int day;
public String name;
}
I tried to add the tags and annotations across the code, but it didn't seem to work. Also, my first few attempts featured the month/day not as separate classes but as variables Month, Day, MonthName, and DayName. I'm not sure how I'm supposed to ignore these attributes and just carry on.
When I run my code (which is just using the XMLMapper to map the XML file to an instance of that DateTime class), it doesn't work.
Here's the error it produced :
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "" (class city.weather.Month), not marked as ignorable (2 known properties: "month", "name"])
at [Source: (File); line: 3, column: 35] (through reference chain: city.weather.DateTime["month"]->city.weather.Month[""])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:60)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:822)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1152)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1589)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1567)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:294)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:136)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2902)
at Tester.main(Tester.java:8)
This stumped me because clearly you can see that there isn't any attributes listed (just a "" field, which tells me nothing). I tried to find documentation but there wasn't much I could find.

Fixed! For this I simply added #JsonIgnoreProperties({""}) in the start of the classes Month and Day.

Using #JsonIgnoreProperties({""})
on the Month and Day classes
(as written in your own answer) surely works.
Another (and in my opinion better) way would be to annotate
the month property of class Month and the day property of class Day
with #JacksonXmlText instead of #JacksonXmlProperty(...).
By doing so these properties would actually
receive the day and month number from XML.

Related

spring boot repository: check if Date exists

In my reservation-entity i have a column "bookingDate" --> example: "2021-05-10 12:00:00".
So in this object the date and starttime of an user-booking gets displayed.
If a user wants to book a timeslot, i want to check first if the selected timeslot is empty. So i want to query the database by date&startTime.
I tried it with https://www.baeldung.com/spring-data-jpa-query-by-date , but it didnt work. I got the errors: "The annotation #Temporal is disallowed for this location" & "#Temporal cant be used for variables"
these are the relevant classes:
Reservation.java
#Entity
public class Reservation {
#Id #GeneratedValue
private int reservationId;
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime bookingDate;
private int court = 1;
private String playerNames;
private int userIdReservation;
//getter and setters
With the method "findByBookingDate()" i want to query the database, if the selected timeslot is empty...
VerificationClass.java
public boolean validateReservation(Reservation r) {
LocalDateTime tempDate = r.getBookingDate();
if(reservationRepository.findByBookingDate(tempDate)){ // todo: + and Court
logger.getLogger().info(this.getClass().getName() + "||Booking Slot is empty -- Reservation created||");
return true;
}
logger.getLogger().info(this.getClass().getName() + "||Booking Slot is full -- Reservation failed||");
return false;
}
ReservationRepository.java
#Repository
#Repository
public interface ReservationRepository extends JpaRepository<Reservation, Integer>{
#Query("Select r from reservation r where r.booking_date = :tempDate")
boolean findByBookingDate(#Param("tempDate") LocalDateTime tempDate);
}
If I run it like this i always get an "org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'backyardcodersSpringReactApplication'" --> so the application does not successfully start up.
Im very thankful for every tip and critique!
cheers!
Not understood completely. this is just a lead maybe not a perfect solution.
You can use java.time.LocalDateTime . and annotation be like #DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME).
And the query should be like. [the query will check all the reservation for that day]
Select
from reservation_table
Where
timeSlot between ‘2021-05-10 00:00:00’ and ‘2021-05-10 23:59:59’
I copied your code in my local file. Instead of
import org.springframework.data.jpa.repository.Temporal;
I used
import javax.persistence.Temporal;
in your Reservation.java file.
Also this is my very first answer on Stackoverflow.
First of all #Temporal have three different arguments and it can be applied to the variable of type date , time and time stamp.
Usage
#Temporal(Temporal type.DATE)
private Date date;
#Temporal(Temporal type.TIMESTAMP) // INSERT BOTH DATE WITH TIME TILL MILLISECONDS
private Calendar date;
Why not just just extract the localdate from your LocalDateTime and pass it on? and extract the hour and pass it on and query 2 different columns with it.
LocalDateTime.toLocalDate()
LocalDateTime.getHour()

Get all the dates from database

I am storing objects with timestamp in the database(Realm).
public class Met extends RealmObject{
private String name;
private int met;
private long timestamp;
}
I want to show them date wise, like grouping them by date.
Since it is a timestamp and will be different for rows of the same day, I am not able to get it to work.
This comes from the backend and I cannot change it to date.
The only idea I have is to add an extra date field, so that it would be easy to query.
Is there a way to achieve this at the query level without any extra fields?
To query by the same day, you could easily set up a query that queries between the start of the day and the start of the next day.
public class Met extends RealmObject {
private String name;
private int met;
#Index
private long timestamp;
}
And
Date startOfDay = //...get start of day
Date startOfNextDay = //... get start of next day;
RealmResults<Met> mets = realm.where(Met.class)
.greaterThanOrEqualTo(MetFields.TIMESTAMP, startOfDay.getTime())
.lessThan(MetFields.TIMESTAMP, startOfNextDay.getTime())
.findAllSorted(MetFields.TIMESTAMP, Sort.ASCENDING);

Date calculation in Entity

I have my entity class like this
#Entity
public class CheckInstrument extends BaseEntity {
public CheckInstrument() {
}
#Column(nullable = false)
private Date currentCheck;
#Column(nullable = false)
private Long periodicity;
#Column
private Date nextCheck;
#Column
private boolean isExpired;`
(getters and setters)
My issues is
Сalculate nextCheck such as adding periodicity(month) to
currentCheck
Calculate isChecked property as comparing nextCheck with current
System Date.
I think your question is a pure date calculation problem, has nothing to do with Hibernate or jpa entity.
all codes are not written in IDE, not tested either:
Calculate nextCheck such as adding periodicity(month) to currentCheck
You may want to check the Calendar class
Calendar cal = Calendar.getInstance();
cal.setTime(currentCheck);
cal.add(Calendar.MONTH,1);
currentCheck = cal.getTime();
Calculate isChecked property as comparing nextCheck with current System Date.
java.util.Date implements Comparable, so you can compare two dates like:
int result = date1.compareTo(date2);
To your question: nextCheck.compareTo(new Date())
IMO, isExpired / overdued shouldn't be added as database field. because it is related current date. It would be better to get that flag by calculation, to make it real time. Well it is anyway up to your requirement.

How to override table data using Hibernate for specific criteria using hibernate annotations?

We are generating Sales Report using Hibernate.
Scenario
When user clicks on generate report button after entering some criteria, I am fetching data from database using hibernate, then we are doing some data manipulation to generate actual report data. Report data is stored in ArrayList, which then persisted into database in CommissionSummary table, which is mapped with hibernate entity as below
CommussionSummary.java
#Column(length=100)
private String advisorName;
private String advisorCodeParent;
#Column(length=100)
private String advisorNameParent;
#Column(length=100)
private String advisorPost;
#Column
private Double percentage;
#Column
private Double diffPercentage;
#Column
private Double saleAmount;
#Column
private Long saleCount;
#Column
private Double commissionAmount;
#Column
private Integer month;
#Column
private Integer year;
Report is generated for every month.
My Question is: For 05 July 2012 user has generated data so i am storing this information in CommissionSummary table. Now user has generating the same report on 15 July 2012, then it should override earlier month data.
Override criteria should be month and year.
I believe what you need is a simple data checking.
Solution One:
1. Load data from DB and check those data for possible duplication.
2. If you find them equal, delete the older version.
Solution Two:
One other possible solution is to define your columns unique, so if a user wants to put the same data, he will be receiving some exceptions. Something like this:
#Table(name="TABLE_NAME", uniqueConstraints = {
#UniqueConstraint(columnNames={"advisorName", "advisorNameParent", "advisorPost", "percentage", "diffPercentage" , "saleAmount", "saleCount", "commissionAmount" })
#Column(name = "ADVISOR_NAME", length=100)
private String advisorName;
private String advisorCodeParent;
#Column(name = "ADVISOR_PARENT_NAME", length=100)
private String advisorNameParent;
#Column(name = "ADVISOR_POST" , length=100)
private String advisorPost;
#Column(name = "PERCENTAGE")
private Double percentage;
#Column (name = "DIFF_PERCENTAGE")
private Double diffPercentage;
#Column (name = "SALE_AMOUNT")
private Double saleAmount;
#Column (name = "SALE_COUNT")
private Long saleCount;
#Column (name = "COMMISSION_AMOUNT")
private Double commissionAmount;
Using this, you can check if there were some errors you can do your desired action.
Get the CommissionSummary for the given month an year using a HQL query:
select c from CommissionSummary where c.year = :year and c.month = :month
If not null, delete it:
session.delete(existingCommissionSummary);
Then save the new one.

JPA/Hibernate mapping to store months and days-of-months

I have following POJOs:
class Month {
long id;
String description;
List<Day> days; // always contains 29, 30 or 31 elements
}
class Day {
byte nr; // possible values are 1-31
String info;
}
Is there a way to store these objects into following DB structure using JPA+Hibernate:
Table MONTHS:
id;description;
Table DAYS:
id-of-month;nr-of-day;info;
Any better solution for this situation?
If you can't change your pojo's or table structure you are a bit screwed. If you can then a simple annotated pojo will work.
class Month {
#Id
private long id;
private String description;
#OneToMany(mappedBy="month",fetchType=Lazy)
private List<Day> days;
}
---- Surrogate key required DB change for Days table
class Day {
#Id
private int id;
private Month month;
private byte nr; // possible values are 1-31
private String info;
}
Here is one solution I found:
class Month {
long id;
String description;
#CollectionOfElements(fetch = FetchType.EAGER)
#IndexColumn(name = "nr-of-day")
List<Day> days; // always contains 29, 30 or 31 elements
}
#Embeddable
class Day {
byte nr; // possible values are 1-31
String info;
}
#CollectionOfelements and #IndexColumn are Hibernate annotations. If I use #OneToMany annotation available in JPA, hibernate creates 3 tables instead of 2.
My only problem now is that Day.nr is saved twice: first as IndexColumn of the List (0-based counter) and second time as field of class Day (1-based counter).
Can you map a Month #Entity class UNIDIRECTIONAL relationship with Day #Entity class without #Embeddable with CascadeType.PERSIST instead, where the identifier of #Entity Day class is composed by Month identifier and the list index as follow ?
#Entity public class Month {
#Id
#GeneratedValue
private Integer id;
// one way relationship
#OneToMany(cascade=CascadeType.PERSIST)
#JoinColumn(name="MONTH_ID")
#IndexColumn(name="childIndex")
private List<Day> dayList = new ArrayList<Day>();
}
#Entity public class Day {
#EmbeddedId // composed by month foreign key and index column
private DayId id;
}
I hope you solve this problem
Regards
Arthur Ronald F D Garcia (Java programmer)
Natal/Rn - Brazil

Categories

Resources