I have this db table in an H2 database called "mytable" and two of the fields have the type "TIMESTAMP".
I have writen the following query in order to update the table:
UPDATE mytable
SET START_TIME_ = "2018-01-01 01:01:01" , END_TIME_ = "2020-01-01 01:01:01";
I was wondering how could I modify my query so that it generates at the START_TIME_ and END_TIME_ fields random dates between 2018-01-01 01:01:01 and 2020-01-01 01:01:01. As the H2 timestamp is not a UNIX timestamp I am unsure how to go about it. I appreciate any help you can provide.
In H2 1.4.200 you can use
UPDATE mytable SET
START_TIME_ = #T := TIMESTAMP '2018-01-01 01:01:01'
+ RAND() * INTERVAL '730 00:00:00' DAY TO SECOND,
END_TIME_ = #T + (TIMESTAMP '2020-01-01 01:01:01' - #T) * RAND();
INTERVAL '730 00:00:00' DAY TO SECOND can be replaced with the subtraction operation between high and low bounds (TIMESTAMP '2020-01-01 01:01:01' - TIMESTAMP '2018-01-01 01:01:01').
Note that distribution of START_TIME_ is linear here, but distribution of END_TIME_ is not. If such distribution doesn't satisfy your needs, you need to use some more complex expressions, but you can use the same datetime arithmetic operations in them.
Please also note that inline variable assignment syntax uses the := operator and not the = operator.
I'm mapping a TIME column of a MySQL database in Hibernate (5.4.6.Final) as a java.time.LocalTime class.
This is the declaration of the mapping into the entity:
#Column(name = "TIMEVAL")
public LocalTime TIMEVAL;
The column in the database has value 00:30:00, however Hibernate it's building the instance of TIMEVAL with a value of 01:30:00.
I thought about a difference of time-zones (Ignoring the fact that the TIME data-type doesn't have a time-zone) between the server and the hibernate connection, but I setup each connection and the server as UTC.
And by executing the queries:
SELECT ##global.time_zone;
SELECT ##session.time_zone;
The result of the Hibernate session and the server were all +00:00.
Following the Hibernate configuration:
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
spring.datasource.url=jdbc:mysql://localhost:3306/..?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&allowMultiQueries=true
And here's the MySQL configuration:
default-time-zone=+00:00
I tried also:
Specifying the MySQL column as VARCHAR(8), but Hibernate always retrieves 01:30:00;
Changing the Entity data-type to Duration, but Hibernate throws an error saying that it can't map TIME to java.lang.Long.
What do I need to modify in order to have Hibernate build the LocalTime instance with the value of the database column?
As #Andreas pointed out in the comments. The JVM time zone wasn't in UTC.
I needed to change the JVM time zone to get the correct value out of the database.
So, by adding the following param to the JVM options:
-Duser.timezone=UTC
Finally the LocalTime instance was built with the value of 00:30:00 as the value of the database column.
I totally fail when i want use this data type. I get exception:
Unknown data type: "DATETIMEOFFSET"; SQL statement:
ALTER TABLE PUBLIC.usr_user ALTER COLUMN next_password_change_date DATETIMEOFFSET [50004-196]
Is there any way around that?
Unfortunately, there is no DATETIMEOFFSET data type in h2 like in SQL server.
Reference: http://www.h2database.com/html/datatypes.html
Way around that will be to choose a different date type e.g. DATE, TIMESTAMP or TIMESTAMP WITH TIME ZONE.
I am using Spark Cassandra connector in Java to insert data. My data has a timeuuid and timestamp field. I have the following table:
CREATE TABLE abc.log (
time_uuid timeuuid,
session_id text,
event text,
time timestamp,
sequence int,
PRIMARY KEY (customer)
);
I am using this code to insert:
JavaRDD<EventLog> rdd = sc.parallelize(eventLogs);
javaFunctions(rdd)
.writerBuilder("dove", "event_log", mapToRow(EventLog.class))
.saveToCassandra();
how do I insert the timeuuid and timestamp fields? Using normal insert I would just use the now() function, how do I do that here?
You may use com.datastax.driver.core.utils.UUIDs for this.
The UUIDsTest utilizes the class like this to create a TimeUUID:
UUID uuid = UUIDs.timeBased();
Note that UUID is java.util.UUID. Note sure if you need it for your use case, but after that you can retrieve timestamp of the UUID by calling UUIDs.unixTimestamp(uuid);.
As for your timestamp, you pass an instance of java.util.Date, as proposed on the docs.
The latest Java JDBC drivers for postgres claim to support UUIDs natively; working against Postgres 9.2 (mac).
Indeed, when a PreparedStatement is used, I can step through the driver code, and even walk
through the specialised 'setUuid' function in AbstractJdbc3gStatement.java. By all indications, it should 'just work'.
However, it does not work. The database flings back an error, which I receive thus:
Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: uuid = bytea
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Position: 139
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2157) ~[postgresql-9.2-1002.jdbc4.jar:na]
Yes, indeed, setUuid in the JDBC driver does send that as a bytea :
private void setUuid(int parameterIndex, UUID uuid) throws SQLException {
if (connection.binaryTransferSend(Oid.UUID)) {
byte[] val = new byte[16];
ByteConverter.int8(val, 0, uuid.getMostSignificantBits());
ByteConverter.int8(val, 8, uuid.getLeastSignificantBits());
bindBytes(parameterIndex, val, Oid.UUID);
} else {
bindLiteral(parameterIndex, uuid.toString(), Oid.UUID);
}
}
What gives?
Is there some magic rune required in the actual database to bless this conversion ?
tl;dr
myPreparedStatement.setObject(
… ,
java.util.UUID.randomUUID()
)
Details
(a) Show us your code.
PreparedStatement::setObject does work when passing a java.util.UUID. You likely have some other issue in your code.
(b) See my blog post UUID Values From JDBC to Postgres for a bit of discussion and example code.
// Generate or obtain data to store in database.
java.util.UUID uuid = java.util.UUID.randomUUID(); // Generate a random UUID.
String foodName = "Croissant";
// JDBC Prepared Statement.
PreparedStatement preparedStatement = conn.prepareStatement( "INSERT INTO food_ (pkey_, food_name_ ) VALUES (?,?)" );
int nthPlaceholder = 1; // 1-based counting (not an index).
preparedStatement.setObject( nthPlaceholder++, uuid );
preparedStatement.setString( nthPlaceholder++, foodName );
// Execute SQL.
if ( !( preparedStatement.executeUpdate() == 1 ) ) {
// If the SQL reports other than one row inserted…
this.logger.error( "Failed to insert row into database." );
}
(c) I'm not sure what you mean by
The latest Java JDBC drivers for postgres claim to support UUIDs natively
Which driver? There are at least two open-source JDBC drivers for Postgres, the current/legacy one and a new rewrite "next generation" one. And there are other commercial drivers as well.
"natively"? Can you link to the documentation you read? The SQL spec has no data type for UUID (unfortunately ☹), therefore the JDBC spec has no data type for UUID. As a workaround, the JDBC driver for Postgres uses the setObject and getObject methods on PreparedStatement move the UUID across the chasm between Java ↔ SQL ↔ Postgres. See the example code above.
As the PreparedStatement JDBC doc says:
If arbitrary parameter type conversions are required, the method setObject should be used with a target SQL type.
Perhaps by "natively", you confused Postgres' native support for UUID as a data type with JDBC having a UUID data type. Postgres does indeed support UUID as a data type, which means the value is stored as 128-bits rather than multiple times that if it were stored as as ASCII or Unicode hex string. And being native also means Postgres knows how to build an index on a column of that type.
The point of my blog post mentioned above was that I was pleasantly surprised by how simple it is to bridge that chasm between Java ↔ SQL ↔ Postgres. In my first uneducated attempts, I was working too hard.
Another note about Postgres supporting UUID… Postgres knows how to store, index, and retrieve existing UUID values. To generate UUID values, you must enable the Postgres extension (plugin) uuid-ossp. This extension wraps a library provided by The OSSP Project for generating a variety of kinds of UUID values. See my blog for instructions.
By the way…
If I knew how to petition the JDBC expert group or JSR team to make JDBC aware of UUID, I certainly would. They are doing just that for the new date-time types being defined in JSR 310: Date and Time API.
Similarly, if I knew how to petition the SQL standards committee to add a data type of UUID, I would. But apparently that committee is more secretive than the Soviet Politburo and slower than a glacier.
I used the following approach to add UUID and other objects to postgres:
PGobject toInsertUUID = new PGobject();
toInsertUUID.setType("uuid");
toInsertUUID.setValue(uuid.toString());
PreparedStmt stmt = conn.prepareStatement(query);
stmt.setObject(placeHolder,toInsertUUID);
stmt.execute();
This way you will be stopping yourself from doing type casting. This piece of code worked perfectly for me for any time for example even json.
This worked for me using the org.postgresql.postgresql 42.2.5
myPreparedStatement.setObject(4, UUID.randomUUID(),java.sql.Types.OTHER)
Without java.sql.Types.OTHER I got an error
try
.setParameter("uuid", uuid, PostgresUUIDType.INSTANCE);