vaadin8 DateField: Cannot cast java.time.LocalDate to java.util.Date - java-8

I have simple entity (for example)
import java.util.Date;
class People implements Serializable{
...
private Date birthdate; //(getters, setters)
...}
UI code:
final Binder<People> binder = new Binder<People>(People.class); ...
People bean=new People();
binder.setBean(bean);
DateField birthdate = new DateField("date of birth");
binder.bind(birthdate, "birthdate");
When I select date from calendar in UI I get:
Caused by: java.lang.ClassCastException: Cannot cast java.time.LocalDate to java.util.Date
at java.lang.Class.cast(Class.java:3369)
at com.vaadin.data.Binder$BindingBuilderImpl.lambda$createConverter$f6099586$1(Binder.java:800)
at com.vaadin.data.Converter.lambda$null$fdd4de71$1(Converter.java:105)
at com.vaadin.data.Result.of(Result.java:91)
I tried to use
DateField birthdate = new DateField("birthdate");
binder.bind(birthdate, "birthdate");
binder.forField(birthdate).withConverter(new LocalDateToDateConverter());
but have same result.
How to bind Date to DateField properly?

The problem is how you make use of the binder. Instead try
DateField birthdate = new DateField("birthdate");
binder.forField(birthdate).withConverter(new LocalDateToDateConverter()).bind("birthdate");
The forField method returns an object following the builder design pattern. That means you call some (chained) methods on that object and finish it by a call to bind.

Related

How do i create new table in database from same entity JPA Spring boot?

I want to create a new table every day with the full date as table name if the day is new create table for the that day
I have seen that when I change #Table(name="") name to a new string it make a new table but I can't automate this work
#Entity
#Table(name="orders_25_10_2021")
public class game2data {
#Id
private int cid;
private String name;
private Integer address;
private Integer gender;
private String date;
private String Done;
In simple words, I want to pass the name of #Table(name="") as a variable with dynamic according to date.
You can achieve this custom naming strategy by extending SpringPhysicalNamingStrategy and overriding its toPhysicalTableName method :
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
import org.springframework.context.annotation.Configuration;
#Configuration
public class TableNamingStrategy extends SpringPhysicalNamingStrategy {
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd_MM_YYYY");
public static final PhysicalNamingStrategyStandardImpl INSTANCE =
new PhysicalNamingStrategyStandardImpl();
#Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
if (!name.getText().equals("game2data"))
return name;
StringBuilder customName =
new StringBuilder("orders").append('_').append(DATE_FORMATTER.format(LocalDate.now()));
return new Identifier(customName.toString(), name.isQuoted());
}
}
and registering it in your application.properties:
spring.jpa.hibernate.naming.physical-strategy=com.stackoverflow.questions.TableNamingStrategy
and removing the #Table annotation from the game2data entity.
This method is limited by the fact table names are determined at application start-up.
As a proof of concept, here's a way to update the table name every day by extending StatementInspector. By using this, you won't be able to read old data. You'll also have to use custom implementations of the JpaRepository's methods to create the new table every day before you insert data in it.

How to resolve No converter found capable of converting from type TupleBackedMap to type [com.example.dto.ExampleDto]

org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.example.dto.ExampleDto]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321) ~[spring-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:194) ~[spring-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174) ~[spring-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.convert(ResultProcessor.java:293) ~[spring-data-commons-2.1.5.RELEASE.jar:2.1.5.RELEASE]
The above error is being thrown when I have a query that returns 2 values in a native JPA query is being used. I'm capturing the query response in the DTO below:
#Data
#Entity
#NoArgsConstructor
#AllArgsConstructor
#Builder
public class ExampleDto {
#Id
private String name1;
private int nameFlag;
}
And in a DAO class, I'm calling the native query as below. The query works in SQL Developer and returns 2 records. But when called as below , it throws the above error.
List<ExampleDto> getExampleDto = myJPARepository.
.findNameObject(uuid);
There is something wrong in the DTO class, which i need to change. Annotations? I'm not sure what is missing here, and try as I might , putting in #Entity annotation, #Data annotation , I'm not able to resolve this error when the query is called.
UPDATE: The native query associated with this is
#Query(value = "select name1, nameFlag from NameTable",
nativeQuery = true, name = "findNameObject where namekey = ?")
List<ExampleDto> findNameObject(
#Param("nameKey") UUID nameKey);
This is a bug: https://jira.spring.io/browse/DATAJPA-1714
You can either use JPQL with a constructor expression, an interface projection or a custom method implementation as a workaround.
Make sure, your Repository class is using same class, as you are using for extracting the records from native query. Example shown below for XYZDTO
#Repository
public interface XYZRepository extends JpaRepository <XYZDTO, Long> {
}

spring bind date field of command object

I have a form that inserts/updates data. The command object (Bean) class has a Date field that is placed in the form as follows:
<form:hidden path="createdDate">
when I submit the form, the BindResult.hasErrors() is validated as true.
I think I need to bind the date object, but how is it done for Command object field?
The form bean code is as follows
#Entity
#Table(name = "Employee")
public class Employee {
#Id
#GeneratedValue
#Column(name="id")
private int id;
#Column(name="EmployeeName")
private String employeeName;
#Column(name="CreatedDate")
private Date createdDate;
//Setter and getter methods
}
Error:
[Field error in object 'employee' on field 'CreatedDate': rejected value [Mon Sep 17 20:35:26 IST 2012]; codes [typeMismatch.employee.CreatedDate,typeMismatch.CreatedDate,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [subject.CreatedDate,CreatedDate]; arguments []; default message [CreatedDate]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'CreatedDate'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property 'CreatedDate': no matching editors or conversion strategy found]]
Add this annotation to your date fields:
#Column(name="CreatedDate")
#DateTimeFormat(pattern="yyyy/MM/dd hh:mm:ss") //whatever format is appropriate to you..
private Date createdDate;
Ensure that you have joda time as a dependency and the library is present in classpath. It will automatically register a converter to take care of the transformation.
I found your problem. In your Employee model class the createdDate field is not defined correctly.
You need to use the #Temporal annotation to define that the field is of type date.
Please put the following annotation also on top of the field declaration of createdDate
#Temporal(TemporalType.TIMESTAMP)
I think this should solve your problem. Cheers.

Time string to Calendar

I am using the jquery timepicker plugin and it works fine. I can select a time and submit my form. I am using spring MVC 3.0 and the problem comes in when I attempt to parse a string ,which represents time, as a java carlendar.
I have been reading up on this date/time conversion, http://www.odi.ch/prog/design/datetime.php, and it seems quite complicated. Can someone please offer some form of advice. Here is my code, which is spring specific.
#RequestMapping(value = "scheduleadd", method = RequestMethod.POST)
public String scheduleadd( #Valid Schedule schedule, BindingResult bindingResult,
#RequestParam("startdate") #org.springframework.format.annotation.DateTimeFormat(iso=ISO.DATE) java.util.Calendar startdate,
#RequestParam("enddate") #org.springframework.format.annotation.DateTimeFormat(iso=ISO.DATE) java.util.Calendar enddate,
#RequestParam("starttime") #org.springframework.format.annotation.DateTimeFormat(iso=ISO.NONE) java.util.Calendar starttime,
#RequestParam("endtime") #org.springframework.format.annotation.DateTimeFormat(iso=ISO.NONE) java.util.Calendar endtime,
#RequestParam("moduleInstanceId") Long mId, Model uiModel, HttpServletRequest httpServletRequest) { //my stuff goes here}
As you can see, I am trying to parse a string like "09:30" as java Carlendar. Do I need the date part? How do I specify the date part ?
Use the pattern attribute of #DateTimeFormat to specify that the "time" fields are not fully-formed ISO datetimes, but rather just times; e.g.:
...
#RequestParam("starttime") #DateTimeFormat(pattern="hh:mm") Calendar starttime,
#RequestParam("endtime") #DateTimeFormat(pattern="hh:mm") Calendar endtime,
...
And in your scheduleadd() method, combine the Calendar fields to get a fully-formed datetime:
startdate.set(Calendar.HOUR_OF_DAY, starttime.get(Calendar.HOUR_OF_DAY));
startdate.set(Calendar.MINUTE, starttime.get(Calendar.MINUTE));
...

How can I validate a complex model object in Spring 3 using #Valid annotations?

I have a model object modelling a purchase order. The purchase order has a few fields (such as ID and date) and a list of line-items as ArrayList. I can validate the parent purchase order ok, but it chokes when validating the line-items.
Can anyone help me with validation of complex objects? If I cannot validate complex objects auto-magically, how can I write a custom validator that relies upon the constraint annotations in the parent and then iterates over the child line-items? This Validator instance needs to be able to call something.validate(purchaseOrder) and (for each line-item) something.validate(lineItem). Where do I get "something" from?
I have specified <mvc:annotation-driven /> in dispatcher-servlet. I am not using #InitBinder. And I am using #Valid annotation for validation in controller's method like
#RequestMapping(params="confirmPurchaseOrder")
public String confirm(
#ModelAttribute("purchaseOrder") #Valid PurchaseOrder purchaseOrder,
BindingResult result,
#RequestParam("account") String accountString,
#RequestParam("division") String divisionString,
Model model)
{
if (result.hasErrors()) {
return PURCHASE_ORDER_CREATE_VIEW;
}
The domain classes look like this: -
public class PurchaseOrder implements Comparable<PurchaseOrder> {
/** Based on GUID */
private String id;
/** SOP */
#NotNull
private Integer SOP;
/** Reference from client */
#NotBlank
private String purchaseOrderReference;
/** PO date */
#DateTimeFormat(style="S-")
#NotNull
private Date date;
#Valid
private final Collection<LineItem> lineItems = new ArrayList<LineItem>();
And
public class LineItem {
...Elided
/** Generated from GUID */
private String id;
#NotNull
#DateTimeFormat(style="S-")
#Future
private Date expiry;
private String softwareVersion;
#NotNull
#NumberFormat(style = Style.NUMBER)
#Min(1)
private Integer licenceCount;
When committing a Purchase Order with an empty expiry date, I get the following exception:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'lineItems[]' of bean class [com.nit.ols.domain.PurchaseOrder]: Invalid index in property path 'lineItems[]'; nested exception is java.lang.NumberFormatException: For input string: ""
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:730)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:634)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
In your PurchaseOrder class, try changing your lineItems collection to a List. It looks like you are having the same problem addressed in this question.
It's like David said, declaring lineItems of type List should do the trick. In Hibernate Validator 4.2.0 CR1 (not yet released atm, you could use the latest snapshot build if you are interested) also Collection should work, see HV-468 for more details.

Resources