jpa retrieving date from oracle - java

hi i need to retrieve the data from the oracle Database which has DATE values, i have the following entity:
#Entity
#Table(name="GRUPO_HORARIO_FICHA")
public class grupo_horario {
#Id
#Column(name = "COD_GRUPO_HORARIO")
private String codigo;
#Temporal(TemporalType.TIME) //tried DATE,TIME and TIMESTAMP already
#Column(name = "HORA_INI")
private Date hora_ini; //java.util.Date
#Temporal(TemporalType.TIME) //tried DATE,TIME and TIMESTAMP already
#Column(name = "HORA_FIN")
private Date hora_fin; //java.util.Date
so when i call the following method in the DAO i get null as the date values:
grupo_horario grupo_horarios= new grupo_horario();
try {
grupo_horarios = (grupo_horario) em.createQuery("SELECT g FROM grupo_horario g WHERE g.codigo = :codigo").setParameter("codigo", codigo).getSingleResult();
} catch (NoResultException e) {return null; }
System.out.println("el resultado date=" + grupo_horarios.getCodigo()); // i get the id with no problem at all.
System.out.println("el resultado date=" + grupo_horarios.getHora_ini()); // i get null here, i need to retrieve the time.
the DATE columns in the database should be DATE and not TIMESTAMP, the Dates i have are java.util.Date. im using ojdbc6 and oracle database 10g if that information is needed

looks like my table column was HORA_INICIO and that seemed to be the problem just changed it and its working.

Related

Spring Data and Oracle returns different result from query? Why?

My JPA query is very complex because of that I am using nativequery, But when I run it returns different results from JAVA query and Oracle query. However Oracle query returns correct result.What could be the reason for this ?
I changed SELECT statement, try to fetch all of them by a.* and also try to fetch only necessary column. I also remove DATE comparison statements. However interestingly JPA query returns 4 row and all of them were same exactly. I also try to fetch data without TRUNC keyword in DATE comparison part, and it is not worked. In addition I add schema names in front of tables in native query which is not worked again.
public Optional<LocalDateTime> getPaymentPeriod2(LocalDate reportDate, String loanId)
{
final String reportDateParemeter = reportDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
final String query = "SELECT st.t_no, st.islem_tarihi, st.s_kodu, st.odeme_suresi " +
"FROM k_tarihce st, k_tanim sta, kt_tanim tta " +
"WHERE st.s_kodu = sta.s_kodu " +
"AND tta.s_tipi = sta.s_tipi AND tta.t_kodu = st.t_kodu " +
"AND st.t_no = :loanId AND st.t_kodu in (37,55) " +
"AND st.s_kodu = 'K1' AND (TRUNC(st.odeme_suresi) >= TRUNC(TO_DATE(:reportDateParemeter,'yyyy-mm-dd')))";
final Query loanGetPaymentPeriodQuery = entityManager.createNativeQuery(query, LoanStatusHistory.class);
loanGetPaymentPeriodQuery.setParameter("reportDateParemeter", reportDateParemeter);
loanGetPaymentPeriodQuery.setParameter("loanId", loanId);
List<LoanStatusHistory> loanStatusHistoryList = loanGetPaymentPeriodQuery.getResultList();
return loanStatusHistoryList.isEmpty() ? Optional.empty() : Optional.of(loanStatusHistoryList.get(0).getPaymentPeriod());
}
And my entity is:
#Entity
#Table(name = "K_TARIHCE", schema = "LOS")
#Getter
#Setter
#Builder
#NoArgsConstructor
#AllArgsConstructor
#Cacheable(false)
#IdClass(LoanStatusHistoryId.class)
public class LoanStatusHistory {
#Id
#Column(name = "T_NO")
private String loanId;
#Id
#Column(name = "ISLEM_TARIHI")
private LocalDate processDate;
#Id
#Column(name = "S_KODU")
private String statusCode;
#Column(name = "ODEME_SURESI")
private LocalDateTime paymentPeriod;
#Column(name = "T_KODU")
private String historyCode;
}
class LoanStatusHistoryId implements Serializable {
private String loanId;
private transient LocalDate processDate;
private String statusCode;
}
I want to same result with Oracle SQL developer. My main objective is fetch ODEME_SURESI field.
I found solution, again !interestingly! Here my new code below, I just not mapped my native query with entity, and return some LocalDate.
final Query loanGetPaymentPeriodQuery = entityManager.createNativeQuery(query);
loanGetPaymentPeriodQuery.setParameter("reportDateParemeter", reportDateParemeter);
loanGetPaymentPeriodQuery.setParameter("loanId", loanId);
final List<LocalDate> loanStatusHistoryList = loanGetPaymentPeriodQuery.getResultList();
return loanStatusHistoryList.isEmpty() ? Optional.empty() : Optional.of(loanStatusHistoryList.get(0));
This is the only change I made. I still not know why it worked?.

Select data with ZonedDateTime

I have object
...
#CreatedDate
#Column(name = "created_date", nullable = false)
#JsonIgnore
private ZonedDateTime createdDate = ZonedDateTime.now();
...
table - postgeSQL
create table inventory_request
(...
created_date timestamp,
.....
);
I need to select objects with databases between dates ZonedDateTime.now() and last year - ZonedDateTime.now().minusMonths(12)
my JPA repository
List<Inventory> findByCreatedDateBetween(ZonedDateTime now, ZonedDateTime end);
after execute i have only empty array, but values is present in database
I try use TimeStamp - 'java.lang.IllegalArgumentException: Parameter value [2018-11-20 14:44:23.528] did not match expected type [java.time.ZonedDateTime (n/a)]'
How is fix it? How to get the necessary data please help? Thanks!

Spring JPA hibernate postgresql partion and timestamp without timezone

After searching a lot, I have a trouble to save timestamp data in PostgreSQL base using Spring JPA Hibernate.
Here my main table in PostgreSQL, it's a partitionning table :
CREATE TABLE public.archive_traffic_measure
(
measure_point_id integer NOT NULL,
measure_agregation_id integer NOT NULL,
measure_datetime timestamp without time zone NOT NULL,
measure_type_id integer NOT NULL,
any_flow integer,
f_any_flow smallint,
hgv_flow integer,
f_hgv_flow smallint,
occupation_rate smallint,
f_occupation_rate smallint,
average_speed smallint,
f_average_speed smallint,
CONSTRAINT pk_archive_traffic_measure PRIMARY KEY (measure_point_id, measure_agregation_id, measure_datetime, measure_type_id)
)
Here my main entity with spring JPA hibernate with #SQLInsert to suppress the check and don't have the problem with hibernate that no row is insert (because the row is insert in a child table) :
#Entity
#Table(name = "archive_traffic_measure")
#SQLInsert(sql = "INSERT INTO archive_traffic_measure (measure_point_id," +
"measure_agregation_id," +
"measure_datetime," +
"measure_type_id," +
"any_flow," +
"f_any_flow," +
"hgv_flow," +
"f_hgv_flow," +
"occupation_rate," +
"f_occupation_rate," +
"average_speed," +
"f_average_speed) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", check = ResultCheckStyle.NONE)
public class ArchiveTrafficMeasure implements Serializable {
#EmbeddedId
private ArchiveTrafficMeasureId id;
#Column(name = "any_flow")
private Integer anyFlow;
#Column(name = "f_any_flow")
private Integer F_AnyFlow;
#Column(name = "hgv_flow")
private Integer hgvFlow;
#Column(name = "f_hgv_flow")
private Integer F_hgvFlow;
#Column(name = "occupation_rate")
private Integer occupationRate;
#Column(name = "f_occupation_rate")
private Integer F_occupationRate;
#Column(name = "average_speed")
private Integer averageSpeed;
#Column(name = "f_average_speed")
private Integer F_averageSpeed;
}
And my id's entity with Spring JPA hibernate :
#Embeddable
#Table(name = "archive_traffic_measure")
public class ArchiveTrafficMeasureId implements Serializable {
#Column(name = "measure_point_id")
private int measurePointId;
#Column(name = "measure_agregation_id")
private int measureAgregationId;
#Column(name = "measure_datetime", columnDefinition = "timestamp without time zone")
#Temporal(TemporalType.TIMESTAMP)
private Date measureDateTime;
#Column(name = "measure_type_id")
private int measureType;
}
When I try to insert new data I have this error :
ERROR: column "measure_datetime" is of type timestamp without time zone but
expression is of type integer
The problem is the request be like :
INSERT INTO archive_traffic_measure VALUES (1,2,2018-04-18 17:00:00+01,1,40,null,null,null,null,null,null,null)
So the quote arount the timestamp is missing...
I have try to put the quote in the #SQLInsert "(?,?,'?',?,?,?,?,?,?,?,?,?)" but with that, I have the error :
The column's index is out of bound : 12, number of column : 11.
I have also try "(?,?,''?'',?,?,?,?,?,?,?,?,?)" with double quote
Or "(?,?,?::timestamp,?,?,?,?,?,?,?,?,?)" but nothing is working for far.
Can someone help me ? Thanks in advance.
First, add nullable = false for 'measure_datetime' column definition also remove composite key from #SQLInsert:
#SQLInsert(sql = "INSERT INTO archive_traffic_measure ("any_flow," +
"f_any_flow," +
"hgv_flow," +
"f_hgv_flow," +
"occupation_rate," +
"f_occupation_rate," +
"average_speed," +
"f_average_speed) VALUES (?,?,?,?,?,?,?,?,?)", check = ResultCheckStyle.NONE)
Then, when you persist ArchiveTrafficMeasure, you should set PK as ArchiveTrafficMeasureId and persist it.

Hibernate Incorrect datetime value

Hoping someone can clear this up for me. I'm getting some warnings when I run a unit test that is using hibernate criteria. The specific warnings are:
Mar 10, 2016 11:48:31 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: SQL Warning Code: 1292, SQLState: 22007
Mar 10, 2016 11:48:31 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: Incorrect datetime value: '1454684370' for column 'date_created' at row 1
Mar 10, 2016 11:48:31 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: SQL Warning Code: 1292, SQLState: 22007
Mar 10, 2016 11:48:31 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: Incorrect datetime value: '1454684700' for column 'date_created' at row 1
I can't figure out what Hibernate is complaining about. The column it's talking about, 'date_created', is of type datetime. I've tried passing in every other version of the date object, a string, a java.util.Date, a java.sql.Timestamp, but those just cause actual errors. Specifically they cause:
java.lang.ClassCastException: java.sql.Timestamp cannot be cast to java.lang.Long
or, of course, whatever other type I tried passing instead of Long. The times I'm passing in are epoch times but for some reason I'm getting these errors and the unit tests aren't passing.
Also, in case it might help, here is the specific code in the tests:
public List<Content> findByCollectionName(String collectionName, Long exclusiveBegin, Long inclusiveEnd, Long expiration)
{
if(collectionName == null)
return null;
Session session = currentSession();
session.beginTransaction();
Criteria criteria = session.createCriteria(Content.class).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
criteria.createAlias("collections", "cols");
criteria
.add(Restrictions.and(Restrictions.eq("cols.name", collectionName), buildCriterion(exclusiveBegin, inclusiveEnd, expiration)));
List<Content> list = criteria.list();
session.getTransaction().commit();
return list;
}
private Criterion buildCriterion(Long exclusiveBegin, Long inclusiveEnd, Long expiration)
{
List<Criterion> criterion = new ArrayList<Criterion>();
if(exclusiveBegin != null)
criterion.add(Restrictions.gt("dateCreated", exclusiveBegin));
if(inclusiveEnd != null)
criterion.add(Restrictions.le("dateCreated", inclusiveEnd));
if(expiration != null)
criterion.add(Restrictions.ge("dateCreated", expiration));
Criterion[] array = new Criterion[criterion.size()];
for(int j = 0; j < array.length; j++)
{
array[j] = criterion.get(j);
}
return Restrictions.and(array);
}
EDIT Sorry for the delay, here's the requested additions.
#Entity
#Table(name = "content")
public class Content implements Serializable
{
private static final long serialVersionUID = -8483381938400121236L;
public Content()
{
}
public Content(String messageId, ContentBlock block) throws NullPointerException
{
if(messageId == null || block == null)
throw new NullPointerException("Null objects passed for Content object creation");
this.messageId = messageId;
this.setContentBlock(block);
this.dateCreated = System.currentTimeMillis();
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", columnDefinition = "BIGINT UNSIGNED")
private int id;
#Column(name = "message_id")
private String messageId;
#Column(name = "date_created")
private long dateCreated;
#Column(name = "content_wrapper", columnDefinition = "longblob")
private byte[] contentWrapper;
#ManyToMany(mappedBy = "contentBlocks")
private List<TCollection> collections;
/*#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "message_id")
private TMessage message;*/
I omitted the getters and setters for brevity
As for the database, it's got a regular structure. The TContent table has:
column type
id bigint
user_id int
name varchar
date_created datetime
collection_wrapper longblob
tspoll_expire decimal
Please let me know if I can add anything else or have missed anything. Thanks for taking a look.
In the past I've used the following, which successfully converts between MySQL datetime field and java.util.Date:
#Temporal(TemporalType.TIMESTAMP)
private Date dateTime;
And more recently with Joda-time, the following successfully converts between MySQL 5.7 datetime(3) and org.joda.time.DateTime:
#Column(columnDefinition = "DATETIME(3)")
private DateTime dateTime;
There will be other options but these are the two I'm currently familiar with.
Hibernate has a bug (sort of) when parameter hibernate.hbm2ddl.auto set to update If table contains filed with the same name, for example from previous deployment, it just leave field 'as is' and doesn't change field type.
I think, previously you set date_created as Date type, but later switch it to long.
Possible solutions:
change java bean field type long dateCreated; to Date dateCreated; and work with Date type in code.
manually change database structure accordinly to your java classes. alter table content alter column date_created TYPE bigint I doesn't sure mysql allow to do it, in that case you should write migration procedure.
drop database and recreate it with hibernate (only if content not important/test/garbage)

The data types datetime and time are incompatible in the greater than or equal to operator

I have a variable type time in a column of a table of the database.
How can I compare this value in java with this field I mean can i use date, gregoriancalendar?
I've tried adn I still have this message, please can someone give me an advice
Date d2 = new Date(); // timestamp now
Calendar cal = Calendar.getInstance(); // get calendar instance
cal.setTime(d2); // set cal to date
cal.set(Calendar.HOUR_OF_DAY, 10); // set hour to midnight
cal.set(Calendar.MINUTE, 30); // set minute in hour
cal.set(Calendar.SECOND, 0); // set second in minute
cal.set(Calendar.MILLISECOND, 0); // set millis in second
Date d3 = cal.getTime();
#SuppressWarnings("unchecked")
List<Asistencia> list = (List<Asistencia>) sessionFactory
.getCurrentSession()
.createQuery(
"select new Asistencia( asis.idAsistencia,"
+ "asis.horaInicio, asis.horaFin) "
+ "from Asistencia asis "
+ "where :hour >= asis.horaInicio and :hour <= asis.horaFin")
.setParameter("hour", d3).list();
I also used between
where :hour between asis.horaInicio and asis.horaFin
and the mesage is the same:
ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - The data types datetime and time are incompatible in the greater than or equal to operator.
The data types datetime and time are incompatible in the greater than or equal to operator.
Here the class Asistencia:
public class Asistencia implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private long idAsistencia;
private Date horaInicio;
private Date horaFin;
private int idAula;
private int idCurso;
private int idPeriodo;
private Date fecha;
public Asistencia (){
}
public Asistencia (long idAsistencia, Date horaInicio, Date horaFin){
this.idAsistencia
this.horaInicio = horaInicio;
this.horaFin = horaFin;
}
}
It seems the only problem was I'm using SQL Server 2008 and is necessary to put sendTimeAsDateTime=false in the connections properties.
Here a similar question.
comparing time in sql server through hibernate
I encountered this error using SpringBoot(v2.2.2) and MSSQL server (jdbc7.4.1) when calling a JpaRepository API passing null dates. This was first version Repository API
#Query(value = "SELECT t FROM MyEntity t WHERE "
+ " AND ( ?3 IS NULL OR ( ?3 IS NOT NULL AND t.fromDate<= ?3 ))"
+ " AND ( ?2 IS NULL OR ( ?2 IS NOT NULL AND t.toDate>= ?2 ))")
List<MyEntity> getMyEntity(LocalDate fromDate, LocalDate toDate);
When calling API with null value for input dates i got the exception:
The data types date and varbinary are incompatible in the less than or equal to operator
I solved with a CAST:
#Query(value = "SELECT t FROM MyEntity t WHERE "
+ " AND ( ?3 IS NULL OR ( ?3 IS NOT NULL AND t.fromDate<= CAST( ?3 AS date ) ))"
+ " AND ( ?2 IS NULL OR ( ?2 IS NOT NULL AND t.toDate>= CAST( ?2 AS date ) ))")
List<MyEntity> getMyEntity(LocalDate fromDate, LocalDate toDate);
Without setting that sendTimeAsDateTime property, which is not available for the SQL Server drivers older than 3.0 (and some of us are stuck with what we have, for reasons), you could try to use a String instead of a date. This worked for me using a PreparedStatement and I bet it would work in this scenario also. Change the last line of your first code block to:
.setParameter( "hour", new SimpleDateFormat("HH:mm:ss.SSS").format(d3) ).list();
I've encountered the same issue when querying data by entity property of type javax.time.LocalDate via spring-data-jpa and eclipselink . Connection setting sendTimeAsDateTime=false didn't help. This was fixed by adding spring-data-jpa converter <class>org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters$LocalDateConverter</class> into the persistence.xml file. Hope this helps.
I also have the same issue. My sql data type is Time(7) and each time I want to compare it via JPQL query, that error comes out. Connection string sendTimeAsDateTime=false didn't work. Adding <class>org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters$LocalDateConverter</class> into the persistence.xml also didn't work.
What I do is, store data Time(7) from sql into String, for example this is my table design on sql
StartTime time(7)
In my java class I store that field into String variable
#Entity
#Table(name = "tableSchedule")
public class TableSchedulue implements Serializable {
private static final long serialVersionUID = -9112498278775770919L;
....
#Column(name = "StartTime")
private String startTime;
.....
}
When I use JPQL query like this (in repository)
#Query(value = "SELECT a "
+ "FROM TableSchedule a "
+ "WHERE a.startTime <= ?1 ")
List<TableSchedulue > getTestData(String startTime);
Your string format must HH:mm:ss
It works. Hope it helps
CONS : Because in SQL the type is Time(7) so value 08:00:00 in SQL will become 08:00:00.0000000 in persistence so you need to parse it into your needs

Categories

Resources