I have been configuring Spring auditing for my entity classes. Using annotations, I have something like this:
#CreatedDate
#NotNull
private Date createdDate
#CreatedBy
#NotNull
private User createdBy
The createdBy field is being set correctly, however persisting the object fails with a null createdDate. I am guessing that this may be related to type conversion for Eclipselink?
#Temporal annotation is available since the release of JPA 1.0. #Temporal solves the one of the major issue of converting the date and time values from Java object to compatible database type and retrieving back to the application.
#Column(name = "XDATE")
#Temporal(TemporalType.DATETIME)
private Date xDate; //java.util.Date
I hope this will resolve your problem. For more info please refer this link
Related
I have an Entity CustomEntity with a data member updateDate of type OffsetDateTime.
I have defined a Repository for this Entity which has a simple method to retrieve list of records matching updateDate as
List<CustomEntity> findByUpdateDate(OffsetDateTime updateDate);
Now, when this method is called from Controller/Service bean, I can see no matching record is retrieved; however, when I execute the generated SQL in the DB, I can see matching rows available.
I can retrieve the records based on other data members of the entity; its just an issue with OffsetDateTime and LocalDateTime
I got to understand that java.time package support was not in JPA 2.1; however I am using JPA 2.3.1. Do I need to use Converters (as suggested for JPA 2.1?
Any help is much appreciable.
EDIT :-
Below is the code for Entity
#Entity
#Table(name = "SAMPLE_TABLE")
public class CustomEntity {
#Id
#GeneratedValue
private Long id;
#Column
private OffsetDateTime updateDate;
//Getters & Setters
}
I am using Microsoft SQL Server and the generated SQL query (hibernate generated) looks something like below
select sample0_.id as id1_10, sample0_.updateDate as update2_10 from sample_table sample0_ where sample0_.updateDate=?
binding parameter [1] as [TIMESTAMP] - [2021-07-27T17:22:34.597Z]
I'm using Spring Boot with Spring Data JPA to map an Entity to a table in a SQL Server database for which I've created an #Embeddable composite key. There's a column I'd like to use as part of the key and according to SQuirreL its type name is datetime and the class name is java.sql.Timestamp. The key class looks like this:
#Embeddable
public class MyEntityIdentifier implements Serializable {
#Column(name = "LastUpdateDateTime")
private Timestamp lastUpdateDateTime;
...but the lastUpdateDateTime property always resolves to null without error. I've checked and there are no null fields for this column. I've also tried resolving to java.util.Date without success. Is there another type I should be using or something I'm doing wrong?
Hibernate will internally convert to a native Java type (i.e. java.util.Date as opposed to java.sql.Timestamp) by adding the #Temporal annotation.
#Column(name = "LastUpdateDateTime")
#Temporal(TemporalType.DATE)
private Date lastUpdateDateTime;
I upgraded from Hibernate Search 4.4 to 5.3 and sucessfully migrated all issues in Hibernate Search Migration Guides, but I'm encountering the following error regarding a date property when using MultiFieldQueryParser.
org.hibernate.search.exception.SearchException: HSEARCH000233: The specified query '+(dateField:value)' contains a string based sub query which targets the numeric encoded field(s) 'myDate'. Check your query or try limiting the targeted entities.
My date property is pretty standard
#Column(name = "my_date")
#Temporal(TemporalType.TIMESTAMP)
#Field
#DateBridge(resolution = org.hibernate.search.annotations.Resolution.DAY)
private Date myDate;
Versions
Hibernate 4.3
Hibernate Search 5.3
had to explicitly import (maven) org.apache.lucene.lucene-queryparser (4.10.4) for org.apache.lucene.queryparser.classic.MultiFieldQueryParser, otherwise it wouldn't find it
Also found this issue (HSEARCH-1870) regarding date values, not sure if related.
Am I missing something on myDate declaration?
EDIT: missed one migration requirement - see my answer bellow.
As it turns out I missed one migration requirement: enconding is set to numeric in HS 5 by default.
Numeric Field(s) being used by default
Numbers and Dates now indexed as Numeric Field by default
Setting the encoding to mimic the behavior in previous versions fixed it.
#Column(name = "my_date")
#Temporal(TemporalType.TIMESTAMP)
#Field
#DateBridge(resolution = org.hibernate.search.annotations.Resolution.DAY, encoding = EncodingType.STRING)
private Date myDate;
I am using this code:
#Column(name = "FECHA_CREACION_TIMESTAMP",columnDefinition="DATE DEFAULT SYSDATE", insertable=false)
#Temporal(TemporalType.TIMESTAMP)
private Date fechaCreacionTimestamp;
But when I insert some data to the table, it doesn't have the date just have the date like null.
Updated Answer: (Now that I know that you are using Oracle)
What you need is to make sure that the column doesn't get included in the insert statements. For that, you need to update your #Column annoation like:
#Column(..other properties.., insertable = false)
See here for more details.
Now, you also need to make sure that the generated value is available in your domain object after you perform the insert. If you are using Hibernate, and do not mind using Hibernate annotations, you can put the following annotation on your field.
#org.hibernate.annotations.Generated(org.hibernate.annotations.GenerationTime.INSERT)
Hibernate will automatically perform the required select query for you.
If you are not using Hibernate, you will need to do a select yourself to fetch the generated value after performing the insert. JPA doesn't have anything to specify that this should be done automatically.
you can use something like :
#Column(name = "FECHA_CREACION_TIMESTAMP",columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP", insertable=false)
#Temporal(TemporalType.TIMESTAMP)
private Date fechaCreacionTimestamp;
Which is best practice?
#Column(name = "FOO", columnDefinition = "TIMESTAMP")
private Date foo;
Or
#Column(name = "FOO")
#Temporal(TemporalType.TIMESTAMP)
private Date foo;
The documentation suggests that using columnDefinition is non-portable ...
The documentation suggests that using columnDefinition is non-portable
...
That's true. columnDefinition specified the SQL data type that will be used. This data type may however not be available in all RDBMS. In JPA, it's the JPA provider's duty to figure out what SQL works on what DB. You can specifiy part of that configuration, but you will always risk breaking support for some databases.
#Temporal on the other hand is an abstraction that is part of the JPA standard. Every JPA provider must be able to map the different types of #Temporal to different SQL types for all supported databases.