I have a class wich contains:
#Column(name = "end_date")
private Date endDate;
and it's setter
public void setEndDate() {
endDate = new java.sql.Date(Calendar.getInstance().getTime().getTime());
System.out.println(endDate);
}
When I'm calling the setter, and check again if the value is correct, everything's fine.(even getEndDate().getClass() ).
However, when I'm saving my object into PostgreSQL (myObject.persist()), there's no value on END_TIME column. Other values are correct.
Does anyone know what's the problem?
Also, I have to mention that hibernate is set to create SQL tables
Setter and getter:
public void setEndDate(Date endDate) {
setEndDate();
}
public Date getEndDate() {
return endDate;
}
import java.util.Date instead of import java.sql.date
assign current date as per following code
default date assign while creating object of this entity if user need to change then using setter on run time
try this it will work
#Column(name = "END_TIME")
private Date endDate = new Date();
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public Date getEndDate() {
return endDate;
}
I use java.util.Date for this case, and change the mapping of your #Column as
#Column(name = "end_time")
private Date endDate = new Date();
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public Date getEndDate() {
return endDate;
}
Related
Im having an issue when I fetch data from the DB with HIBERNATE and SpringMVC, everything works fine except for the dates. When I fetch a field of Date type, I receive the date but with a previous day.
For example, Im fetching the date as "2022-08-28", but im receiving "2022-08-27"
Also have an issue when I update the data, Hibernate saves on the next day that the date that is stored on the DB.
On the same example Im fetching the date as "2022-08-28", but when saving the record appears as "2022-08-29"
This is my architechture
Entity
#Entity
#Table(name = "cliente_tickets")
public class ClienteTicket {
... other fields...
#DateTimeFormat(pattern = "yyyy-MM-dd")
#Temporal(TemporalType.DATE)
#Column(name = "created_on")
private Date createdOn;
#DateTimeFormat(pattern = "yyyy-MM-dd")
#Temporal(TemporalType.DATE)
#Column(name = "updated_on")
private Date updatedOn;
... other GettersAndSetters...
public Date getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Date createdOn) {
this.createdOn = createdOn;
}
public Date getUpdatedOn() {
return updatedOn;
}
public void setUpdatedOn(Date updatedOn) {
this.updatedOn = updatedOn;
}
}
This is the method in my DAO
#Override
public ClienteTicket buscarId(long id) {
try {
return sessionFactory.getCurrentSession().createQuery("from ClienteTicket ct where ct.idTicket = :id", ClienteTicket.class)
.setParameter("id", id).getSingleResult();
} catch (NoResultException e) {
return null;
}
}
This is the Service
#Override
#Transactional
public void guardar(ClienteTicket clienteTicket) {
if (clienteTicket.getCreatedBy() == null || clienteTicket.getCreatedBy().length() == 0) {
clienteTicket.setCreatedOn(new Date());
clienteTicket.setCreatedBy(Utilidades.currentUser());
} else {
clienteTicket.setUpdatedOn(new Date());
clienteTicket.setUpdatedBy(Utilidades.currentUser());
}
this.clienteTicketDao.guardar(clienteTicket);
}
This is my controller for fetching the Object
#GetMapping("/editar")
ModelAndView editar(#RequestParam("id") String id) throws ParseException {
ClienteTicket ticket = this.ticketsService.buscarId(Long.parseLong(id));
super.mv = new ModelAndView("/cliente/ticket_formulario");
super.mv.addObject("clienteEncontrado", true);
super.mv.addObject("editar", true);
super.mv.addObject("clienteTicket", ticket);
super.mv.addObject("idClienteActual", ticket.getCliente().getIdCliente());
super.mv.addObject("estadosIncidencia", this.ticketEstadosService.listar());
super.mv.addObject("tiposIncidencia", this.ticketTiposService.listar());
super.mv.addObject("titulo", "Tickets");
//this.ticketsService.guardar(ticket);
return super.mv;
}
When I Debug I get this JAVA_DEBUG
These are the properties of the DB TABLE_PROPERTIES
Current data on DB DATA_TABLE
Date in JSP is hidden DATA_JSP
HTML EDGE_DEVTOOLS
Other data is fetched correctly OTHER_DATA
I've solved!, It was related with the Timezone.The timezone on my pc was right, the issue was the configuration on the jdbc.url. I was using serverTimezone=UTC, Im from Mexico so i needed to use CST. adding serverTimezone=CST to jdbc.url solved my issue. I hope this helps someone in the future. TY
Change
jdbc.url=jdbc:mysql://localhost:3306/sge?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull
To
jdbc.url=jdbc:mysql://localhost:3306/sge?useSSL=false&serverTimezone=CST&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull
I have a problem with the serialization of an object to JSON using the org.json library.
In my code I have:
String resultStr = new JSONObject(result).toString();
and in result object two fields of type LocalDateTime:
private LocalDateTime startDate;
private LocalDateTime stopDate;
In variable resultStr I got date in following format:
2020-01-23T14:13:30.121205
I want this ISO format:
2016-07-14T07:58:08.158Z
I know that in Jackson there is an annotation #JsonFormat, but I didn't find anything like that in org.json. How to define a format of LocalDateTime in JSON string with org.json?
In JSON in Java, it seems that there are not much support for Date/Time formatting.
To customize the formatting of LocalDateTime field, we can make use of
1. #JSONPropertyIgnore to ignore the original getter to be serialized
2. #JSONPropertyName to annotate a new getter with ignored field name, which return the desired formatted date string, as following:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.json.JSONObject;
import org.json.JSONPropertyIgnore;
import org.json.JSONPropertyName;
public class CustomizeLocalDateTimeFormatInOrgJson {
public static void main(String[] args) {
Result result = new Result(LocalDateTime.now(), LocalDateTime.now());
String resultStr = new JSONObject(result).toString();
System.out.println(resultStr);
}
public static class Result {
DateTimeFormatter customDateTimeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssS'Z'");
private LocalDateTime startDate;
#JSONPropertyIgnore
public LocalDateTime getStartDate() {
return startDate;
}
#JSONPropertyName("startDate")
public String getStartDateString() {
return customDateTimeFormat.format(startDate);
}
private LocalDateTime stopDate;
#JSONPropertyIgnore
public LocalDateTime getStopDate() {
return stopDate;
}
#JSONPropertyName("stopDate")
public String getStopDateString() {
return customDateTimeFormat.format(stopDate);
}
public void setStopDate(LocalDateTime stopDate) {
this.stopDate = stopDate;
}
public void setStartDate(LocalDateTime startDate) {
this.startDate = startDate;
}
public Result(LocalDateTime startDate, LocalDateTime stopDate) {
super();
this.startDate = startDate;
this.stopDate = stopDate;
}
}
}
Currently, the format of the Date requestDate variable stored looks like: 2017-02-17 00:00:00.0. I want to convert this into, for example: Friday, February 17, 2017. I would like to do the conversion here in my entity and return it so that when it's displayed it is more human readable. This will likely happen in the constructor, at this line: this.setRequestDate(doDateConversion(requestDate));. How can I make this conversion?
My Request entity:
#Entity
#Table(name = "Request")
public class RequestDO implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="request_id")
private Long id;
private Date requestDate;
private String description;
private RequestStatus status;
/*private Boolean read;*/
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="user_id", nullable = false)
private Users users;
public RequestDO() {}
public RequestDO(Users user, Date requestDate) {
this.setUsers(user);
this.setRequestDate(requestDate);
}
#Override
public String toString() {
return String.format(
"RequestDO[id=%d, inital='%s', requestDate='%s']",
getId()
, getUsers().getInitialName()
, getRequestDate());
}
public Date getRequestDate() {
return requestDate;
}
public void setRequestDate(Date requestDate) {
this.requestDate = requestDate;
}
}
You can use SimpleDateFormat to convert your Date to a readable String of your choice.
The time format String for your example is EEEE, MMMM, dd, yyyy. You have to create a new SimpleDateFormat object and format your date to a String. Examples...
But Spring provides some specials out of the box. For example you can use Jackson for date format: #JsonFormat(pattern="yyyy-MM-dd") more. It is also possible to add a data format in application.properties file : spring.jackson.date-format
Using SimpleDateFormat:
java.sql.Date date = new Date(System.currentTimeMillis());
System.out.println(new SimpleDateFormat("EEEE, MMMM dd, YYYY").format(date));
See this for more details.
I solved the problem by changing the dates as they are read in my controller, using SimpleDateFormat:
#RequestMapping(value = "/requests", method = RequestMethod.GET)
public String getAllRequests(Model model, RequestModel requestModel) throws ParseException {
List<RequestDO> requestDOArrayList = new ArrayList<RequestDO>();
for (RequestDO requestDO : requestRepository.findAll()) {
log.info(requestDO.toString());
// Display all dates in Requests list in human-readable form
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse(requestDO.getRequestDate().toString());
log.info(String.valueOf(date));
requestDO.setRequestDate(date);
requestDOArrayList.add(requestDO);
}
model.addAttribute("requests", requestDOArrayList);
log.info(requestDOArrayList.toString());
return "requests";
}
I am using JPA with my Java project, and the timestamp is not working very well : it only shows 2015-08-12 00:00:00.0 (the day is correct but the hour is not)
#Entity
public class Session implements Serializable {
..
#Temporal(TemporalType.DATE)
private Date timestamp;
..
public Session(String sessionId) {
super();
this.sessionId = sessionId;
this.timestamp = new Date();
}
public Session() {
super();
this.timestamp = new Date();
}
}
Do you know how to fix this?
You should use TemporalType.TIMESTAMP that will map the field to a java.sql.Timestamp, hence it will contain also time related info, not only regarding date. In comparison, the type you used, TemporalType.DATE are mapped to java.sql.Date, class containing information like day, month year.
So, your code will transform in:
#Entity
public class Session implements Serializable {
..
#Temporal(TemporalType.TIMESTAMP)
private Date timestamp;
..
public Session(String sessionId) {
this.sessionId = sessionId;
this.timestamp = new Date();
}
public Session() {
this.timestamp = new Date();
}
}
Situation: NotificationProfile entity has collection of NotificationProfileIntegration entities which has embedded IntegrationNotificationCutOff. It is legacy database and i cannot modify it. Someone thought it is a good idea to store time as "HH:mm" strings, but i need to work with date objects. That is the reason why i have these convert callbacks and transient date fields.
When i do (for existing profile entity)
entityManager.merge(profile);
I expect that #PreUpdate is called on NotificationProfileIntegration and dates are converted to their string representation and persisted to DB. Instead #PostLoad method is called first and #PreUpdate is called after.
So if i set something in cutOff instance it is never persisted, because in #PostLoad method new instance of cutOffs is created because it is null due to this feature of hibernate
When all of the values in an #Embedded object are null, Hibernate will
set the field in the parent object to null.
How can i handle this situation? Thank you.
#Entity
#Table(name = "NOTIFICATION_PROFILES")
public class NotificationProfile extends AbstractEntity<Long> {
#OneToMany(mappedBy = "notificationProfile", cascade = CascadeType.ALL, orphanRemoval = true)
private Collection<NotificationProfileIntegration> profileIntegrations;
....
}
#Entity
#Table(name = "NOTIFICATION_PROFILE_INTEG")
public class NotificationProfileIntegration extends AbstractEntity<Long> {
#Embedded
private IntegrationNotificationCutOff cutOffs;
#Embedded
private IntegrationNotificationAverageCount averageShipments;
#PostLoad
public void initEmbeded() {
if (cutOffs == null) {
cutOffs = new IntegrationNotificationCutOff();
}
if (averageShipments == null) {
averageShipments = new IntegrationNotificationAverageCount();
}
cutOffs.convertToDates();
}
#PreUpdate
#PrePersist
private void formatCutOffs() {
if (cutOffs != null) {
cutOffs.convertToValues();
}
}
}
#Embeddable
public class IntegrationNotificationCutOff {
#Column(name = "NPI_CUT_OFF_TIME_MON")
private String monday;
#Column(name = "NPI_CUT_OFF_TIME_TUE")
private String tuesday;
#Column(name = "NPI_CUT_OFF_TIME_WED")
private String wednesday;
#Column(name = "NPI_CUT_OFF_TIME_THU")
private String thursday;
#Column(name = "NPI_CUT_OFF_TIME_FRI")
private String friday;
#Column(name = "NPI_CUT_OFF_TIME_SAT")
private String saturday;
#Column(name = "NPI_CUT_OFF_TIME_SUN")
private String sunday;
#Transient
private Date mondayDate;
#Transient
private Date tuesdayDate;
#Transient
private Date wednesdayDate;
#Transient
private Date thursdayDate;
#Transient
private Date fridayDate;
#Transient
private Date saturdayDate;
#Transient
private Date sundayDate;
public void convertToDates() {
SimpleDateFormat dateFormat = getDateFormat();
mondayDate = nullSafeConvert(monday, dateFormat);
tuesdayDate = nullSafeConvert(tuesday, dateFormat);
wednesdayDate = nullSafeConvert(wednesday, dateFormat);
thursdayDate = nullSafeConvert(thursday, dateFormat);
fridayDate = nullSafeConvert(friday, dateFormat);
saturdayDate = nullSafeConvert(saturday, dateFormat);
sundayDate = nullSafeConvert(sunday, dateFormat);
}
public void convertToValues() {
SimpleDateFormat dateFormat = getDateFormat();
monday = nullSafeFormat(mondayDate, dateFormat);
tuesday = nullSafeFormat(tuesdayDate, dateFormat);
wednesday = nullSafeFormat(wednesdayDate, dateFormat);
thursday = nullSafeFormat(thursdayDate, dateFormat);
friday = nullSafeFormat(fridayDate, dateFormat);
saturday = nullSafeFormat(saturdayDate, dateFormat);
sunday = nullSafeFormat(sundayDate, dateFormat);
}
private String nullSafeFormat(Date date, SimpleDateFormat dateFormat) {
if (date == null) {
return null;
}
return dateFormat.format(date);
}
private SimpleDateFormat getDateFormat() {
return new SimpleDateFormat("HH:mm");
}
private Date nullSafeConvert(String day, SimpleDateFormat dateFormat) {
if (day == null) {
return null;
}
try {
return dateFormat.parse(day);
} catch (ParseException e) {
return null;
}
}
}
EDIT
It seems that embedding does not have any efect on this behavior. When i refactor it to single entity problem is still here: after calling createOrUpdate - select is triggered before an update and my change to entity is somewhere "lost"