skip to Main Content

I am creating a Java application that communicates with MySQL database. Using XAMPP 5.6.33-0 and phpMyAdmin. I have the following method that, among other values, inserts a Timestamp into the table RATING:

PreparedStatement pst = myConn.prepareStatement("INSERT INTO RATING  
       (ratingDate) VALUES(?)");
        java.util.Date today = new java.util.Date();
        Timestamp ts = new java.sql.Timestamp(today.getTime());
        pst.setTimestamp(1, ts);
        pst.executeUpdate();

The schema of the RATING relation looks as follows:

CREATE TABLE RATING
(cID INT,
 rID INT,
 stars INT,
 ratingDate TIMESTAMP,
 FOREIGN KEY(cID) REFERENCES CUSTOMER(cID) on delete cascade,
 FOREIGN KEY(rID) REFERENCES ROOM(rID)
 ) ;

So attribute ratingDate is defined as Timestamp. Everything works great except when the Timestamp is inserted its value is always set to all zeros: 0000-00-00 00:00:00

I tried converting the Timestamp to string using t.toString and can clearly see that the Timestamp object is created properly. It seems the problem is with setTimestamp() method. Also, converting the data type of ratingDate to just Date and using setDate() method works fine, but setTimestamp() function always sets the attribute value to all zeros.

There are, of course, workaround for this. I could declare the date as varchar, convert Timestamp to a String and insert it using setString() but I am really wondering what the problem may be. Running Eclipse with Tomcat server. No errors in console.

Thank you in advance for any help, I’d be happy to provide any other necessary information.

2

Answers


  1. Chosen as BEST ANSWER

    After some additional research I figured it out. The problem was that the java Timestamp object uses milliseconds at the end while the timestamp attribute in the MySQL table didn't (it was in the format "yyyy-MM-dd HH:mm:ss"). So this mismatch prevented the insertion of the correct timestamp and instead put a tuple with all zeros into MySQL table. The solution is to format the Timestamp object in the java code to cut off the milliseconds and then insert the Timestamp object into MySQL table:

    java.util.Date today = new java.util.Date();
    java.sql.Timestamp timestamp = new java.sql.Timestamp(today.getTime());
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    pst.setObject(4, formatter.format(timestamp)); 
    

    This worked like a charm. Hope it helps somebody!


  2. Avoid legacy date-time classes

    The all-zeros values is a mystery. But I can tell you that you are using terrible date-time classes that were supplanted years ago by the java.time classes with the adoption of JSR 310. This is making your work more complicated than it needs to be.

    I suggest creating a simple dummy table to narrow down your problem.

    OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
    myPreparedStatement.setObject( … , odt ) ;
    

    Retrieval.

    OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime ) ;
    

    Example app

    I do not use MySQL. But here is a complete example app using the H2 Database Engine.

    package work.basil.example;
    
    
    import org.h2.jdbcx.JdbcDataSource;
    
    import java.sql.*;
    import java.time.OffsetDateTime;
    import java.time.ZoneOffset;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.UUID;
    
    public class H2DateTimeExample
    {
        public static void main ( String[] args )
        {
            H2DateTimeExample app = new H2DateTimeExample ();
            app.demo ();
        }
    
        private void demo ( )
        {
            JdbcDataSource dataSource = new JdbcDataSource ();
            dataSource.setURL ( "jdbc:h2:mem:offsetdatetime_example_db;DB_CLOSE_DELAY=-1" ); // Set `DB_CLOSE_DELAY` to `-1` to keep in-memory database in existence after connection closes.
            dataSource.setUser ( "scott" );
            dataSource.setPassword ( "tiger" );
    
            // Create table.
            String sql = "CREATE TABLE person_ ( n" +
                    " pkey_ UUID NOT NULL DEFAULT RANDOM_UUID() PRIMARY KEY , n" +
                    " name_ VARCHAR NOT NULL , n" +
                    "first_contacted_ TIMESTAMP WITH TIME ZONE NOT NULL " +
                    ") ;";
    //            System.out.println ( sql );
            try (
                    Connection conn = dataSource.getConnection () ;
                    Statement stmt = conn.createStatement () ;
            )
            {
                stmt.execute ( sql );
            } catch ( SQLException e )
            {
                e.printStackTrace ();
            }
    
            // Insert row.
            sql = "INSERT INTO person_ ( name_ , first_contacted_ ) n";
            sql += "VALUES ( ? , ? ) n";
            sql += ";";
            try (
                    Connection conn = dataSource.getConnection () ;
                    PreparedStatement pstmt = conn.prepareStatement ( sql , Statement.RETURN_GENERATED_KEYS ) ;
            )
            {
                OffsetDateTime odt = OffsetDateTime.now ( ZoneOffset.UTC );
    
                pstmt.setString ( 1 , "Jesse Johnson" );
                pstmt.setObject ( 2 , odt );
                pstmt.executeUpdate ();
    
                ResultSet rs = pstmt.getGeneratedKeys ();
    //            System.out.println( "INFO - Reporting generated keys." );
    //            while ( rs.next() ) {
    //                UUID uuid = rs.getObject( 1 , UUID.class );
    //                System.out.println( "generated keys: " + uuid );
    //            }
    
            } catch ( SQLException e )
            {
                e.printStackTrace ();
            }
    
    
            // Query table.
            sql = "TABLE person_ ;";
            try (
                    Connection conn = dataSource.getConnection () ;
                    PreparedStatement pstmt = conn.prepareStatement ( sql ) ;
            )
            {
                try ( ResultSet rs = pstmt.executeQuery () ; )
                {
                    while ( rs.next () )
                    {
                        UUID pkey = rs.getObject ( "pkey_" , UUID.class );
                        String name = rs.getString ( "name_" );
                        OffsetDateTime firstContacted = rs.getObject ( "first_contacted_" , OffsetDateTime.class );
                        System.out.println ( "pkey: " + pkey + " | name: " + name + " | firstContacted: " + firstContacted );
                    }
                }
    
            } catch ( SQLException e )
            {
                e.printStackTrace ();
            }
    
            System.out.println ( "Done." );
    
        }
    }
    

    When run.

    pkey: b14fd25f-1598-4f09-9475-83ac5967a338 | name: Jesse Johnson | firstContacted: 2019-07-28T02:10:07.731005Z

    Done.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search