Yash Agarwal
Yash Agarwal

Reputation: 1035

Deserialize joda time from string in grails?

I had a LocalTime field (using Joda Time) in Grails domain class.

Class WorkDone{
    LocalTime duration
}

Now I have altered this field to String (with Text constraint) so that it can support duration larger than 24 hrs.

String duration

The problem is there is already some data in database. And I want to sanitize that data through database migrations in Grails. I am using Postgres which saves LocalTime as Bytea (binary data).

When I call WorkDone.duration it returns me a String of the form:

\xaced0005737200176f72672e6a6f64612e74696d652e4c6f63616c54696d65fffff44abbf29def0200024a000c694c6f63616c4d696c6c69734c000b694368726f6e6f6c6f677974001a4c6f72672f6a6f64612f74696d652f4368726f6e6f6c6f67793b78700000000000000000737200276f72672e6a6f64612e74696d652e6368726f6e6f2e49534f4368726f6e6f6c6f67792453747562a9c811667137502703000078707372001f6f72672e6a6f64612e74696d652e4461746554696d655a6f6e652453747562a62f019a7c321ae30300007870770500035554437878

How can I extract time from this string?

Upvotes: 6

Views: 600

Answers (3)

Yash Agarwal
Yash Agarwal

Reputation: 1035

I ended up doing the following -

grailsChange{
        change{
            sql.eachRow("Select id,duration from work_done"){
                def wdId =  it.id
                def durationObj = (LocalTime)(new ObjectInputStream(new ByteArrayInputStream(it.duration))).readObject()

                durationObj = durationObj.toString().substring(0,8)

                WorkDone.executeUpdate("update WorkDone wd set wd.duration=:newDuration" +
                    "where wd.id=:wdId",
                    [newDuration:durationObj ,wdId:wdId ])
            }
        }

Upvotes: 1

vzamanillo
vzamanillo

Reputation: 10354

Your data is scaped in bytea Hex format, (starts with \x) take a look at PostgreSQL docs

http://www.postgresql.org/docs/current/static/datatype-binary.html

You have to unescape it before read as ObjectInputStream ang get the LocalTime object, unescape it and then try again as Raphael suggest.

Upvotes: 4

Ashish Joseph
Ashish Joseph

Reputation: 1153

You should have done a data-migration before changing your Data-type to String.

Here is what you should do. 1. Change the Data-type of the field back to LocalTime. 2. Create a new field with String Date. 3. Write a script that would get all date in LocalTime and convert it to String and save it in new field. 4. Once you have your data migrated, delete the old field and then rename your new field to duration.

Upvotes: 1

Related Questions