I'm using spring boot JPA for CRUD operations. I'm querying the database table with the field name created_at which is of type date.There are some rows in the table with the given date but JPA is giving zero result set. I'm using Oracle 11g
Here is my entity
import java.sql.Date;
#Entity
#Table(name="veev_json")
public class VeevJson {
#Id
#Column(name="ID")
private int id;
#Column(name="CREATED_AT")
private Date createdDate;
}
My JPA Repository
import java.util.Date;
#Repository
public interface VeevJsonRepository extends JpaRepository<VeevJson, Integer> {
public List<VeevJson> findByCreatedDate(Date date);
}
Calling the function in the service layer
Date date = new Date(); //taking current date of type java.util.Date
List<VeevJson> documents = veevJsonRepository.findByCreatedDate(date);
My DB table structure
ID NUMBER(10,0)
CREATED_AT DATE
SQL query generated by the hibernate:
select veevjson0_.ID as ID1_1_, veevjson0_.CREATED_AT as CREATED_AT2_1_, veevjson0_.JSON as JSON3_1_, veevjson0_.STATUS as STATUS4_1_ from veev_json veevjson0_ where veevjson0_.CREATED_AT=?
When using a field with type Date, you should also use the #Temporal annotation. The default value of #Temporal is TemporalType.TIMESTAMP, and your JPA implementation may get confused about dealing with a field of type java.util.Date, passing as argument of query the timestamp instead of date.
Please annotate your field as
import java.util.Date;
#Entity
#Table(name = "veev_json")
public class VeevJson {
#Id
#Column(name = "ID")
private int id;
#Temporal(TemporalType.DATE)
#Column(name = "CREATED_AT")
public Date createdDate;
...
}
Doing so will allow JPA implementation to send as queried value only the date (probably in 'YYYY-MM-dd' format) instead of timestamp or any other value.
If you prefer and your JDBC supports 4.1 version, you may exchange the java.util.Date for java8 time API types, but I guess this is out of scope here.
Related
ETA: TL;DR:
orderRepo.save() converts the date (input):
Wed Jun 22 00:00:00 CDT 2022
into this (output):
2022-06-22 05:00:00.000
I am wondering how I can convert the input into the output, in Java, without putting it in the database first.
Original post:
I have a website that has been working with java.utils.Date for over a year now. I can use the angular date picker which makes an order object, sends it to java, repo.save() puts it in the database, pulls it back to angular and displays the date just fine.
I am now trying to query only a specific date from the DB.
#Query("SELECT o FROM Order o JOIN o.boats b WHERE b.date = ?1")
Set<Order> findByDate(Date date);
However this keeps turning up empty even though there are dates that match in the DB
How do I fix my query to grab those dates?
I know, "Don't use java.util.Date" but that is the system I am working with and I don't have time at the moment to convert everything to LocalDate. I will at some point but I am already quite behind on current tasks.
Thanks!!
This method is a jpql
I would have used another way.
Interface call method or Query methods
By calling a method request in the interface, we need our user interface to inherit the interface specified in the Spring Data Jpa:
public interface UserDao extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User>
The prerequisite for using these methods is that the entity class you define should be marked with appropriate annotations.
#Entity //Mark this as an entity class
#Table(name = "tbl_user") //Setting the mapping relationship between the entity class and the public class User table {
#Id //Declare this attribute as the primary key
#GeneratedValue(strategy = GenerationType.IDENTITY) //Primary key generation strategy, self-reinforcing
#Column(name = "user_id") //The specified attribute corresponds to the column name of the database table
private Integer userId;
#Column(name = "user_name")
private String userName;
#Column(name = "user_address")
private String userAddress;
#Column(name = "user_salary")
private Double userSalary;
//... setter method toString
}
I am using Hibernate core 5.4.22 and Hibernate common annotations 5.1.2. I have tried to save the update timestamp on the DB entry using the following annotation:
#UpdateTimestamp
private LocalDateTime closedDateTime;
Unfortunately, this works only when creating a new entry in the DB but not when updating the entry row.
According to the hibernate documentation:
The #UpdateTimestamp annotation instructs Hibernate to set the annotated entity attribute with the current timestamp value of the JVM when the entity is being persisted.
The supported property types are:
java.util.Date
java.util.Calendar
java.sql.Date
java.sql.Time
java.sql.Timestamp
You use direct update query, but the #UpdateTimestamp annotation does not work for this case.
Imagine you have the TestData entity:
#Entity
public class TestData
{
#Id
private Long id;
private String name;
#UpdateTimestamp
private LocalDateTime time;
}
So, you can create new entity in the following way:
TestData testData = new TestData();
testData.setId(1L);
testData.setName("Name 1");
entityManager.persist(testData);
or update existing entity in the following way:
TestData testData = entityManager.find(TestData.class, 1L);
testData.setName("Name 11");
testData = entityManager.merge(testData);
in the last case hibernate will update the time field automatically by the following query:
13:00:32,468 DEBUG SQL:144 - // update com.test.hibernate.entities.TestData
update TEST_SCHEMA.TST_TEST_DATA
set
name=?,
time=?
where
id=?
I'm having the below table in the keyspace myks
CREATE table IF NOT EXISTS myks.users (
user_name text,
email text,
created_at timestamp,
updated_at timestamp,
PRIMARY KEY (user_name)
);
Below is the model class
#Table(value = "users")
public #Data class Users{
#PrimaryKey
#Column("user_name")
#CassandraType(type = DataType.Name.TEXT)
private String user_name;
#Column("email")
#CassandraType(type = DataType.Name.TEXT)
private String email;
#Column("created_at")
#CassandraType(type = DataType.Name.TIMESTAMP)
private Timestamp created_at;
#Column("updated_at")
#CassandraType(type = DataType.Name.TIMESTAMP)
private Timestamp updated_at;
}
Repository interface
#Repository
public interface UsersRepository extends CrudRepository<Users, String> {
}
Inserted the below values into the table
Users users = new Users();
LocalDateTime ldt_created = LocalDateTime.now();
LocalDateTime ldt_updated = ldt_created.plus(1000, ChronoUnit.MILLIS);
Timestamp ts_created = Timestamp.valueOf(ldt_created);
Timestamp ts_updated = Timestamp.valueOf(ldt_updated);
users.setUser_name(krishna");
users.setEmail("krishna#gmail.com");
users.setCreated_at(ts_created);
users.setUpdated_at(ts_updated);
usersRepository.save(users);
It got saved in the table but while retrieving the data it is throwing the below exception
No converter found capable of converting from type [java.util.Date] to type [java.sql.Timestamp]
CQL's timestamp type is mapped into java.util.Date Java type, so you need to use it instead of Timestamp. See CQL to Java mapping table for this & other types.
You can also use so-called optional codecs (an additional dependency) to map timestamp into other Java types, such as, Instant. See documentation for more information.
java.util.Date is no longer used in driver 4.X java-driver-mapper-processor version. Java.time.Instant is used instead.
Mapping in java.util.Date doesn't work anymore, and throws exception:
Field: expiration_date, Entity Type: java.util.Date, CQL type: TIMESTAMP
So actual solution is to use Java.time.Instant for 4.X, and java.util.Date for 3.X.
I'm working on Web application which is using Spring Data JPA and Oracle Database. I was using #RepositoryRestResource annotation in interface where I was just declaring some query methods with named parameters using #Param and #Query annotations. Today I needed to add a new entity with the dates. In database one column is type of DATE and the other one is type of TIMESTAMP. And below the Java representation of this two columns only, of course with all setters and getters, but it has more fields so just adding this:
#Temporal(TemporalType.DATE)
#Column(name = "INIT_DATE")
private Calendar initDate;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "AGG_DATE")
private Calendar aggDate;
I also created new interface for case, the same way as always:
#RepositoryRestResource(collectionResourceRel = "customer", path = "customer")
public interface ICustomerRepository extends PagingAndSortingRepository<Customer, Long> {
#Query("SELECT c FROM Customer c where c.initDate <= TO_DATE(:currentDate, 'yyyy-MM-dd') AND c.aggDate >= TO_DATE(:currentDate, 'yyyy-MM-dd')")
public List<Customer> filterByDate(#Param("currentDate") #DateTimeFormat(pattern = "yyyy-MM-dd") Calendar currentDate);
}
I also tried other format, but I'm receiving this error:
ORA-01830: date format picture ends before converting entire input string
I'm trying to get this data from database using this http request:
http://localhost/webApp/customer/search/filterByDate?currentDate=2017-07-10
And to be honest, I have no idea what is the problem here... The format date in the database is yy/MM/DD, but it also wasn't working for me... Could you tell me what I'm missing or doing wrong??
I use Spring Boot and Data Rest to create a simple microservice in Java8 and get a wrong serialized value in a Date attribute in my JSON response.
My entity:
#Entity
public class ArchivedInvoice implements Serializable {
...
#Column
private java.util.Date invoiceDate;
...
}
My repository interface:
#RepositoryRestResource(collectionResourceRel = "archivedinvoices", path = "archivedinvoices")
public interface ArchivedInvoiceRepository extends PagingAndSortingRepository < ArchivedInvoice, Long > {
...
#RestResource(rel = "findByDate", path = "findByDate")
public Page< ArchivedInvoice > findByInvoiceDate(#Param("invoiceDate") #Nullable #DateTimeFormat(iso = ISO.DATE) Date invoiceDate, Pageable pageable);
...
}
Postgres saves the attribute in a simple date (invoice_date date NOT NULL - '2016-02-22') but the JSON response returns:
"invoiceDate" : "2016-02-21T23:00:00.000+0000"
How can I avoid this?
java.util.Date is actually a timestamp:
The class Date represents a specific instant in time, with millisecond
precision.
Use java.sql.Date instead if the SQL type is date.
Or if you use java 8, you can try using java.time.LocalDate. For that to work you will need to register Springs JSR310 JPA converters.