spring bind date field of command object - spring

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.

Related

Spring Data JPA - cannot insert to the databse - annotation problem?

I can't resolve the problem with inserting values into my database.
I've two very basic and simple classes - Car and Model. I want to store the model ID value for each vehicle in the car class. You know, for the sake of simplicity I assume every car has no brand, only model (eg. Auris, Civic, F150, Challenger etc.).
#Data
#Entity
public class Car {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
#ManyToOne
private Model model;
}
#Entity
#Data
#NoArgsConstructor(access=AccessLevel.PRIVATE, force=true)
#RequiredArgsConstructor
public class Model {
#Id
private final Long id;
private final String name;
private final int price;
}
But the problem is I got that error
Field error in object 'car' on field 'model': rejected value [Model(id=2, name=Civic)]; codes [typeMismatch.samochod.model,typeMismatch.model,typeMismatch.com.CarDealer.Model,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [car.model,model]; arguments []; default message [model]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'com.CarDealer.Model' for property 'model'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value 'Model(id=2, name=Civic)'; nested exception is java.lang.NumberFormatException: For input string: "Model(id=2,name=Civic)"]]
I'd appreciate any help.

Bind ZonedDateTime to bean from application.properties

I want to bind the current date to a bean via application.properties. I tried using a spell expression but it didn't work.
application.yml
defaults:
date: #{T(java.time.ZonedDateTime).now()}
And I have a java bean with getters and setters.
#ConfigurationProperties(prefix = "defaults")
public class DefaultProperties {
private ZonedDateTime date;
// Getters & Setters
}
The trouble is that the expression is always parsing as a string . I am getting Reason: Failed to convert property value of type 'java.lang.String' to required type 'java.time.ZonedDateTime'
Is there any way of doing this?

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

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.

Spring Data JPA - How to find by param with underscore

Here is my model:
public class Log {
#Id
private String id;
private String project;
private String test_no;
// Constructor, getters and setters.
}
How can I add a findBy query which allows me to finding an element by its test_no value? I have tried those method headers but they don't work:
List<Log> findByTest_No(String test_no);
The error that my STS reports is: Invalid delivery query! No property test found in type Log!
List<Log> findByTest_no(String test_no);
The error that my STS reports is: Invalid delivery query! No property test found in type Log!
List<Log> findByTestno(String test_no);
The error that my STS reports is: Invalid derived query! No property testno found for type Log! Did you mean 'test_no'?
It seems that _ is a special character which separates properties names
... it is possible for the algorithm to select the wrong property ... To resolve this ambiguity you can use \_ inside your method name to manually define traversal points ...
Docs
So it can't find test field in Log class.
Try to use:
#Query("select log from Log log where log.test_no = ?1")
List<Log> findByTestNo(String testNo);
There is no need to use private String test_no; You may use private String testNo; Spring automatically understand that you are binding test_no column in the database. Also you can use
#Column(name = "test_no")
private String testNo;
After this changes you can execute queries, mentioned in your question without any custom sql.
List<Log> findByTestNo(String testNo);

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