'How to get 'now time' from database using CrudRepository?
I have this example of entity:
@Entity
public class User {
private String name;
private Date creationDate;
public User(String name) {
this.name = name;
this.creationDate= Calendar.getInstance().getTime();
}
}
and this example of repo:
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
public User findByName(String name);
}
But when I need to do:
User user = new User();
I cant get creationDate anymore from:
Calendar.getInstance().getTime();
Because some people are changing the time from OS, and the time of the creation are being persisted wrong. so I need some:
SELECT SYSDATE FROM DUAL;
SELECT now();
To set the creationDate from user.
Do I need a new repo to get the time, or I can use this UserRepository to get the creationDate from database?? I've tried create a UtilsRepository, where I might get the date from database:
public interface UtilsRepository extends JpaRepository<Date, String> {
@Modifying
@Transactional(readOnly = false)
@Query("select now()")
public Date getDataBaseDate();
}
But it isnt working. I'm getting this error, and I think that is not the best way to do that.
Exception in Application init method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application init method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:912)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'utilsRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class java.util.Date
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:757)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174)
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:841)
... 2 more
Caused by: java.lang.IllegalArgumentException: Not a managed type: class java.util.Date
at org.hibernate.jpa.internal.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:210)
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:68)
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:67)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:152)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:99)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:81)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:199)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:266)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:252)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
... 18 more
Solution 1:[1]
Caused by: java.lang.IllegalArgumentException: Not a managed type: class java.util.Date occurs because Date is not an entity so you won't be able to use your UtilsRepository as is. You should be able to use
@Query(value = "SELECT SYSDATE FROM DUAL", nativeQuery = true)
on your UserRepository
Solution 2:[2]
To build off of @laccf's answer: this solution will work only if you can limit the result to 1 and exactly 1 record. You can do this by adding a parameter, id for example.
@Query("select CURRENT_TIMESTAMP as now from Foo where id = ?1")
Instant getNow(String id);
This is a very hacky solution, but it will work (provided you have a table you know will have the record). It results in the Hibernate query:
select CURRENT_TIMESTAMP as col_0_0_ from foo foo0_ where foo.id=?
I did try using @Query("select CURRENT_TIMESTAMP", nativeQuery = true), it produces the error No Dialect mapping for JDBC type: 2014; nested exception is org.hibernate.MappingException: No Dialect mapping for JDBC type: 2014. I'm pretty sure this is because the native database type is TIMESTAMP WITH TIMEZONE, this could probably be fixed with some explicit mapping.
Another (Less Hacky?) Solution
Make a custom repository fragment.
@Repository
public class TimestampRepositoryImpl implements TimestampRepository {
private final EntityManager entityManager;
public TimestampRepositoryImpl(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
public Instant getNow() {
return (Instant)
entityManager
.createNativeQuery("select current_timestamp as now;")
.unwrap(NativeQuery.class)
.addScalar("now", InstantType.INSTANCE)
.getSingleResult();
}
}
public interface UserRepository extends JpaRepository<User, Long>,
JpaSpecificationExecutor<User>,
TimestampRepository {}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jens Schauder |
| Solution 2 |
