First we need to understand two important concepts: times and durations. Consider the sentences below:
- The meeting was at two o'clock in the afternoon
- The film is two hours long
In the first case, "two hours" is a time: a specific time of the day.
In the second case, "two hours" is a duration: an amount of time, not necessarily related to a specific time (it is not said that hours begin or end, nor is it said whether he was actually assisted).
What can be confusing is that both use the same words (hours, minutes, seconds) and even the display form can be the same (a clock shows "02:00" when it is 2 hours, a stopwatch shows "02:00" when it has been 2 hours). But they are different concepts.
That said, the guy TIME
mysql serves for both: it can either contain a timetable or a duration (hence its crease values range from '-838:59:59' to '838:59:59').
Already the class java.sql.Time
represents only one time, and it’s not for durations. So much so that it only accepts values between 0 and 23 for hours, and values above that are truncated:
System.out.println(Time.valueOf("25:59:59")); // 01:59:59
Therefore, it is not possible to map durations above 24 hours to a java.sql.Time
.
In Java 8, there is a specific class for durations: java.time.Duration
. From JDBC 4.2 and Hibernate 5, there is support for Duration
, that is mapped to BIGINT
, then it would be necessary to change the type of the column of the bank, to contain only one number, corresponding to the total in nanoseconds (which is the accuracy of this API).
Or, you could create a AttributeConverter
to convert the values to a Duration
:
@Converter
public class DurationConverter implements AttributeConverter<Duration, Long> {
@Override
public Long convertToDatabaseColumn(Duration duration) {
return duration == null ? null : duration.getSeconds();
}
@Override
public Duration convertToEntityAttribute(Long dbData) {
return dbData == null ? null : Duration.ofSeconds(dbData);
}
}
...
@Column(name="TEMPO_REPOUSO")
@Convert(DurationConverter.class)
private Duration tempoRepouso;
Only then the query would have to return the amount of seconds corresponding to the duration, something like SELECT TIME_TO_SEC(TEMPO_REPOUSO) etc
. And as it stands, I suspect it only serves for queries (upgrades and insertions in this field would need another conversion, as SEC_TO_TIME
to convert the amount of seconds to the TIME
mysql).
Our many thanks I will test here what you mentioned, your reply also added a lot of knowledge to me, I could not be specific but in my case is Duration even the data I need to work here.
– Diego Souza
@Diegosouza Blz, don’t forget that, if it works and solve your problem, you can accept the answer, see here how and why to do it. It is not mandatory, but it is a good practice of the site, to indicate to future visitors that it solved the problem. And when I get 15 points, you can also vote in all the answers you found useful.
– hkotsubo
Hello @hkotsubo after a lot of research testing, I was able to solve the problem by taking your answer as base... converted the data in the database that was Time to Long (to represent the period recorded in seconds) and ai yes on the java side using Long from the database, I turned it into Period using the class (org.apache.Commons.lang.time.Durationformatutils). Thank you very much helped too!
– Diego Souza