java.time.format.DateTimeParseException, Date could not be parsed - java

I am trying to create an application using springboot-java,
front end as html/css/javascript. I get the below error while doing a post to create an employee record. I am passing a join date which is causing the error.
failed - {"readyState":4,
"responseText":"{\"timestamp\":1515066928232,
\"status\":500,
\"error\":\"Internal Server Error\",
\"exception\":\"java.time.format.DateTimeParseException\",
\"message\":\"Text '01-17-2018' could not be parsed at index 0\",
\"path\":\"/employee/\"}",
"responseJSON":{"timestamp":1515066928232,
"status":500,
"error":"Internal Server Error",
"exception":"java.time.format.DateTimeParseException",
"message":"Text '01-17-2018' could not be parsed at index 0",
"path":"/employee/"},
"status":500,
"statusText":"error"}
Below is the code I use in java:
private static final long serialVersionUID = -7314008048174880868L;
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("MM-dd-yyyy");
private Integer organisation;
private String empName;
private String joinDate;
private String gender;
private String designation;
private String email;
public EmployeeDto(){
}
public EmployeeDto(Integer organisation, String empName, String joinDate, String gender,
String designation, String email) {
super();
this.organisation = organisation;
this.empName = empName;
this.joinDate = joinDate;
this.gender = gender;
this.designation = designation;
this.email = email;
}
public Employee buildEmployee(){
return new Employee(this.empName,LocalDate.parse(this.joinDate),this.gender,this.designation,this.email);
}
I use the below date converter:
#Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
#Override
public Date convertToDatabaseColumn(LocalDate locDate) {
return (locDate == null ? null : Date.valueOf(locDate));
}
#Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
return (sqlDate == null ? null : sqlDate.toLocalDate());
}
}
I am unable to find the root cause....

In buildEmployee() I think you want LocalDate.parse(this.joinDate, DATE_FORMAT) instead of LocalDate.parse(this.joinDate).
One often posted link here on Stack Overflow is How to debug small programs. In that blog post the first tip is to turn on compiler warnings and read them carefully. Putting your code into my Eclipse produces the following warning:
The value of the field EmployeeDto.DATE_FORMAT is not used
This may cause you to wonder why DATE_FORMAT is not used and why you wanted to have it there in the first place. Which in turn could inspire you to use it as intended, which fixes your error.

Related

Update User Detail api returns DataIntegrityViolationException

I'm creating an update API that updates the profile of the super admin, I mapped the member table to a DTO, on the member table password is set to not null and I did not include the password field on the dto because there's a provision for that be, when I tested the API on postman it returned on the console
DataIntegrityViolationException
SQL Error: 1048, SQLState: 23000
Column 'password' cannot be null
Here is my code
Dto
#Getter
#Setter
public class UpdateProfileDto {
#NotNull(message = "{member.firstName.notNull}")
#JsonProperty("first_name")
private String firstName;
#NotNull(message = "{member.lastName.notNull}")
#JsonProperty("last_name")
private String lastName;
#JsonProperty("nationality")
private Long nationality;
#JsonProperty("country_of_residence")
private Long countryOfResidence;
#JsonProperty("date_of_birth")
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
#JsonFormat(pattern = "dd-MM-yyyy")
#Past(message = "{customer.dateOfBirth.past}")
private Date dateOfBirth;
#JsonProperty("current_job_title")
private String currentJobTitle;
#NotNull(message = "{member.emailAddress.notNull}")
#JsonProperty("email_address")
private String emailAddress;
#JsonProperty("username")
private String username;
#NotNull(message = "{member.phoneNumber.notNull}")
#PhoneNumber
#JsonProperty("phone_number")
private String phoneNumber;
#Size(max = 300, message = "{member.city.size}")
#JsonProperty("city")
private String city;
#Size(max = 300, message = "{member.state.size}")
#JsonProperty("state")
private String state;
}
ServiceImpl
#Override
#Transactional
public Member updateProfile(UpdateProfileDto body) {
Member superAdmin = repository.getOne(id);
if (superAdmin == null) {
throw new MemberNotFoundException(id);
}
Optional<Role> existingRole = roleJpaRepository.findByCode(RoleType.SUPER_ADMINISTRATOR.getValue());
if (existingRole.isEmpty()) {
throw new RoleNotFoundException(RoleType.SUPER_ADMINISTRATOR.getValue());
}
Member existing;
existing = mapper.map(body, Member.class);
existing.setPassword(superAdmin.getPassword());
existing.getRoles().add(existingRole.get());
existing.setNationality(countryRepository.getOne(body.getNationality()));
existing.setCountryOfResidence(countryRepository.getOne(body.getCountryOfResidence()));
return adminJpaRepository.save(existing);
}
Controller
#RestController
#RequestMapping(
value = "super-admin",
produces = { MediaType.APPLICATION_JSON_VALUE }
)
public class SuperAdminController {
private final SuperAdminService service;
public SuperAdminController(SuperAdminService service) {
this.service = service;
}
#PutMapping("/update")
public Member updateProfile(#Valid #RequestBody UpdateProfileDto body){
Member superAdmin = service.updateProfile(body);
return superAdmin;
}
}
The password bug has been fixed(changes reflected in serviceImpl), but when I run the code it returned Duplicate entry 'ijava#gmail.com-111803918380' for key 'member.email_address_phone_number_uq' email, and the phone number is set as a unique constraint in the member table, how can I bypass this?
You have few options, depending on your exact use case.
Extract existing password, using unique property in UpdateProfileDto, email looks like it can do the job.
Pseudocode:
Member existing = repository.findByEmail;
Member superAdmin = mapper.map(body, Member.class);
superAdmin.setPassword(existing.getPassword());
Set a dummy value for password, to be updated later on.
superAdmin.setPassword("dummy-password");
Make the column nullable in database.

Serializing Enum to JSON in Java

I have a Java enum where I store different statuses:
public enum BusinessCustomersStatus {
A("active", "Active"),
O("onboarding", "Onboarding"),
NV("not_verified", "Not Verified"),
V("verified", "Verified"),
S("suspended", "Suspended"),
I("inactive", "Inactive");
#Getter
private String shortName;
#JsonValue
#Getter
private String fullName;
BusinessCustomersStatus(String shortName, String fullName) {
this.shortName = shortName;
this.fullName = fullName;
}
// Use the fromStatus method as #JsonCreator
#JsonCreator
public static BusinessCustomersStatus fromStatus(String statusText) {
for (BusinessCustomersStatus status : values()) {
if (status.getShortName().equalsIgnoreCase(statusText)) {
return status;
}
}
throw new UnsupportedOperationException(String.format("Unknown status: '%s'", statusText));
}
}
Full code: https://github.com/rcbandit111/Search_specification_POC/blob/main/src/main/java/org/merchant/database/service/businesscustomers/BusinessCustomersStatus.java
The code works well when I want to get the list of items into pages for the value fullName because I use #JsonValue annotation.
I have a case where I need to get the shortValue for this code:
return businessCustomersService.findById(id).map( businessCustomers -> businessCustomersMapper.toFullDTO(businessCustomers));
Source: https://github.com/rcbandit111/Search_specification_POC/blob/316c97aa5dc34488771ee11fb0dcf6dc1e4303da/src/main/java/org/merchant/service/businesscustomers/BusinessCustomersRestServiceImpl.java#L77
But I get fullValue. Do you know for a single row how I can map the shortValue?
I'd recommend serializing it as an object. This can be done via the #JsonFormat annotation at the class level:
#JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum BusinessCustomersStatus {
A("active", "Active"),
O("onboarding", "Onboarding"),
//...
#Getter
private String shortName;
#Getter
private String fullName;
//...
This will lead to the following result when serializing this enum for BusinessCustomersStatus.A:
{"shortName":"active","fullName":"Active"}
Alternatively, you could define status field as String:
public class BusinessCustomersFullDTO {
private long id;
private String name;
private String businessType;
private String status;
}
and map its value like this:
businessCustomersFullDTO.status(businessCustomers.getStatus().getShortName());

Adding an object to a List of another type

I'm trying to return the record that I got from my database. But I'm having a problem on how I can do that because the data than I retrieved from the database is in a different class from the return parameter.
public List<Record> getRecord(List<Request> requests) {
List<Record> records = new ArrayList<>();
for (Request request : requests) {
Billing billing = billingRepository
.findByBillingCycleAndStartDateAndEndDate(
request.getBillingCycle()
, request.getStartDate()
, request.getEndDate());
if (billing != null) {
// Need to add "billing" to "records" list here
}
}
return records;
}
Record.class
public class Record {
private int billingCycle;
private LocalDate startDate;
private LocalDate endDate;
private String accountName;
private String firstName;
private String lastname;
private double amount;
public Record() {
}
//Getters and setters
Billing.class
public class Billing {
private int billingId;
private int billingCycle;
private String billingMonth;
private Double amount;
private LocalDate startDate;
private LocalDate endDate;
private String lastEdited;
private Account accountId;
public Billing() {
}
//Getters and setters
What can I do? and please explain the answer so I can understand it. I really want to learn
You can use DozerMapper. It will map the object to another object having same name properties or you have to write the mapping in the dozer-mapping xml.
Lets come to your question. Here you are trying to convert your entity to another object.
For that you have to write mapping code. It will be something like this and it is very common practice to convert entity objects to another object before using them.
Record toRecord(Billing billing) {
if(billing == null) {
return null;
}
Record record = new Record();
record.setBillingCycle = billing.getBillingCycle();
...
...
// other properties
...
return record;
}

How i can allow user to input "empty" for integer columns in Jtable and mysql table?

I want allow the user to pass some optional data in the input like:
salary, Graduation year are int type
Hiring Date, End Date, Birth Date are str type
How can I avoid this, and allow mysql Entry?
public class Employee implements mainData{
private int EmpNo;
private String EmpName;
private String HireDate;
private String EndDate;
private Double Salary;
private int GraduationYear;
private String BirthDate;
private String Nationality;
private int DespNo;
private String Note;
public int getEmpNo() {
return EmpNo;
}
public void setEmpNo(int EmpNo) {
this.EmpNo = EmpNo;
}
//and continue setters & getters
Employee emp = new Employee();
private void setValues(){
//Main Entry
emp.setEmpNo(Integer.parseInt(txtEmpNo.getText()));
emp.setEmpName(txtEmpName.getText());
// optional input (have problem as type is integer)
emp.setSalary(Double.parseDouble(txtSalary.getText()));
emp.setGraduationYear(Integer.parseInt(txtGradyear.getText()));
// optional input (no problem as type is string)
emp.setNationality(txtNationality.getText());
emp.setNote(txtNote.getText());
//optional input ((have problem type is string)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String HDate = String.valueOf(sdf.format(dteHire.getDate()));
String EDate = String.valueOf(sdf.format(dteEnd.getDate()));
String BDate = String.valueOf(sdf.format(dteBirth.getDate()));
emp.setHireDate(HDate);
emp.setHireDate(EDate);
emp.setBirthDate(BDate);
//Main Entry
String dspNam = cmbDespline.getSelectedItem().toString();
String dspNo = desp.getValueByName(dspNam);
emp.setDespNo(Integer.parseInt(dspNo));
}
private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {
setValues();
emp.add();
clearData();
emp.getAllRows(tblEmployee);
If there is an empty entry by the user for the optional input, the row entry is not added to the jtable or mysql table and get the following errors:
The following error occurs for Salary:
Exception in thread "AWT-EventQueue-0"
java.lang.NumberFormatException: empty String
The following error occurs for Dates:
Exception in thread "AWT-EventQueue-0"
java.lang.NullPointerException Thanks for any help

Direct self-reference leading to cycle

I'm trying to send a request to get back an array of an object - Coupon when I submit the request I get the answer-
Direct self-reference leading to cycle (through reference chain:
java.util.HashSet[0] => model.Coupon["emptyCoupon"] => model.Coupon["emptyCoupon"])
The model.Coupon probably does the problem.
empty coupon is intended to be returned if the requested coupon does not exist.
public static final int NO_ID = -1;
private static final Coupon EMPTY_COUPON = new Coupon(NO_ID, null, null, null, NO_ID, NO_ID, null, NO_ID, null);
private long id = NO_ID;
private String title;
private LocalDate startDate;
private LocalDate endDate;
private int amount;
private int category;
private String message;
private double price;
private String image;
public Coupon() {
}
private Coupon(long id, String title, LocalDate start_date, LocalDate end_date, int amount, int category,
String message, double price, String image) {
this.id = id;
this.title = title;
this.startDate = start_date;
this.endDate = end_date;
this.amount = amount;
this.category = category;
this.message = message;
this.price = price;
this.image = image;
}
public Coupon getEmptyCoupon() {
return EMPTY_COUPON;
}
Before I added the EMPTY_COUPON I had no problems with the requests.
I want the emptyCoupon in the code, and I'll be happy to help
Since you are serializing to JSON or XML with Jersey, you may not have cycles in your object graph.
Jersey doesn't have a #JsonBackReference like Jackson does, so you might consider to move the EMPTY_COUPON in a separate class (something like Constants.java) and obtain it from there.
Other options are to add #XmlIgnore to your field or to switch to another JSON serializer like Jackson.

Categories