0

I would like to persist an instance of my class into objectdb.

@Entity
public class MyClazz {
  @Column(nullable = false)
  DateTime date;
}

With hibernate I just need to annotate the field with an additional annotation.

@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")

But since I want to use objectdb I can't use these annotation, so I get an exception ("Attempt to store an instance of a non persistable type org.joda.time.DateTime")

The problem is that objectdb disables the "support" for serializable types. (see here) I'm pretty sure that they do this for a good reason so want to keep it this way.

As a workaround for now I use a pre and post hook.

@Column(nullable = false)   
private Date date = new Date();

@Transient
private DateTime dateTime;

@PrePersist
private void persist() {
    date = dateTime.toDate();
}

@PostLoad
private void load() {
    dateTime = new DateTime(date.getTime());
}

My question: is there another way? I would like to get rid of the additional date field.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
Marcel Jaeschke
  • 707
  • 7
  • 24
  • So the date you store is dependent on the default timezone of the machine on which the jvm runs? One day a system admin changed the timezone and you started getting events in the past... – Nikola Yovchev Jul 30 '13 at 15:03
  • I already told you, this is just a quick code example no productive code. Yes j.u.Date is the wrong candidate but for the sake of the question: it doesn't care. So please stop nailing me down for things which are not belong to the question. – Marcel Jaeschke Jul 31 '13 at 08:04

2 Answers2

0

In Joda, a DateTime is an instant in the same way that the Java API Date is an instant. The major difference between the two is that Date is not immutable.

Since both types are wrappers around a long integer that represent the number of milliseconds that have elapsed since Jan 1, 1970 UTC one alternative for you is to simply not persist the DateTime at all, but rather simply persist the long integer that it wraps instead.

Here is an excerpt from the Joda Javadoc:

Internally, the class holds two pieces of data. Firstly, it holds the datetime as milliseconds from the Java epoch of 1970-01-01T00:00:00Z. Secondly, it holds a Chronology which determines how the millisecond instant value is converted into the date time fields. The default Chronology is ISOChronology which is the agreed international standard and compatible with the modern Gregorian calendar.

As long as the Chronology used by your application is constant or always known, you can easily regenerate the DateTime from the long integer field with:

DateTime dt = new DateTime(longInstantFieldInMillis, myChronology);
scottb
  • 9,908
  • 3
  • 40
  • 56
  • How is this relevant to the Question? – Stephen C Jul 28 '13 at 14:56
  • @StephenC: How is it not? He asked how to persist a DateTime, I offered an alternative. – scottb Jul 28 '13 at 15:00
  • No. He asked for a way to persist a DataTime that did not involve an extra field. He wants to get rid of that additional field. – Stephen C Jul 28 '13 at 15:02
  • To persist the timestamp (long) was one of my first ideas too. But I want to use an object orientated database. So it make no sense to me when I hide the information (date) by a primitive field. – Marcel Jaeschke Jul 28 '13 at 15:04
  • @StephenC: Uh, well ... he can get rid of the additional date field by persisting the instant as a long integer instead of a DateTime. Admittedly, this solution requires that the data model be changed which may not be feasible, eg. if the database is already very large. My bias is always to persist instants as primitives. Persisting the DateTime can result in persisting the same Chronology object in the database thousands or hundreds of thousands of times. If the Chronology is always known or constant, this redundancy is not required. – scottb Jul 28 '13 at 15:08
  • @MarcelJaeschke: Yes, I understand that. The Date and DateTime objects are such thin wrappers that I tend to think of them as long integers anyway. But I see your point. – scottb Jul 28 '13 at 15:12
  • @scottb: Just want to add that I prefer Date over long because I can see the date as a date in the objectdb explorer. Beside of that my/our style guide say that DateTime should be used for dates. – Marcel Jaeschke Jul 28 '13 at 15:35
  • @MarcelJaeschke it is fairly common to store only timestamps in db, cause it saves space, saves on errors, and prevents db admins from modifying dates with weird queries and makes them use the frontend instead. Using datetime just cause your dbexplorer can read it, is a joke. – Nikola Yovchev Jul 28 '13 at 21:37
  • @baba How to save an information effectively is up to the DBS not to the user. If the DB-Schema effect the API then something is going wrong. Like scottb said; DateTime is mainly a wrapper around a numeric value. But additionally it brings the logic of a date to the user. So I think a smart oodbs is just saving the numeric value too. BTW: To say that the semantic contextual information is a joke, is a joke to me. – Marcel Jaeschke Jul 29 '13 at 07:37
  • Talking about efficiency, I wonder which size is bigger: that of a long, or of a serialized date/string...Besides, the contextual information of a date is not needed. A timestamp is ALL that is needed to uniquely identify a date, no need of context, nor anything else. Also, no chance of pollution of records if running in clustered environment or changing locale...So many reasons against using a dateTime...Only reason to use a datetime is to be readable on a db level, which, of course, is a joke, since if your app requires your db admin to read data and run ad-hoc queries, you messed it up. – Nikola Yovchev Jul 29 '13 at 08:19
  • @baba You don't get the point. Nobody is talking about to store a date into a super big data structure. If a date class (API) is well designed, than it will only need a long (timestamp) to persist the date. (BTW: timestamp will fail you if you need the timezone). – Marcel Jaeschke Jul 30 '13 at 09:21
  • And because you still think it's a joke. To have context information, like "hey this long should be interpreted as a datetime" is necessary, if you need to use an existing db-explorer instead of develop you own. I'm not able to convert a long into a date mentally. Are you?! – Marcel Jaeschke Jul 30 '13 at 09:32
  • @MarcelJaeschke A timestamp is ENOUGH to determine WHEN something happened. It doesn't make ANY sense to store the timezone. A timestamp of 1375185600000 means 2 o'clock (GMT+2) today. It also means 3'o clock on GMT+3. But still that same timestamp is enough to uniquely identify WHEN something happened. Also, there is no reason to design your db around it being EASY TO FRIGGING EXPLORE WITH A FRIGGING DB EXPLORER! You should design your db to be efficient and remove ambiguity. And yes, I am able to convert a long into a date but my math superiority is hardly relevant. – Nikola Yovchev Jul 30 '13 at 12:39
  • @baba Sorry you get me wrong again. I said if you need the timezone information you will fail with timestamp. Example: You want to query all SO post, which was send by the user at afternoon (time of user). If you just store the timestamp (UTC) you can not do that.And there is no reason to become arrogant and to yell at me. – Marcel Jaeschke Jul 30 '13 at 13:04
  • @MarcelJaeschke how do you know on what timezone the user was? You would get his system time? You would use a piece of javascript to detect the user's timezone and send it back to your server? You'd do that for each event? Seems like a waste of bandwidth to me. You are better off determining the user's ip/timezone at time of logging in and not sending any more. See how big systems are designed. They don't store the timezone for events, cause it can be inferred by other details: like user's IP, or even some timezone retrieved from the user at login.But you don't store it for each event – Nikola Yovchev Jul 30 '13 at 14:45
  • I almost can't see why I would save something more than the timestamp in my db. Think about the benefits of not storing it: saving space, independence from server locale, and discourages people from making ad hoc queries to fix faulty data, and gives you freedom to format the date on client side. Also, there is no way to determine the user's timezone, unless you are willing to waste bandwidth to pass it around. If you are doing a school project, you might not mind all those negatives, but if we are talking about real world cases, a solution storing the timezone as well is plain wrong. – Nikola Yovchev Jul 30 '13 at 14:54
  • @baba If you check my profile you will see the name of my employer and that I'm a long time out of school. And believe me, I have several years of experience in this business. Maybe that's the reason why I would never say that timezone information is unnecessary generally. It depends on the requirements you have. If you would work for me or on that project you would see that the timezone information is not completely useless. Beside of that. Who says the requirements will never change?! Actually they will do! Hum... we are off topic for a quite of time. So have a nice day. – Marcel Jaeschke Jul 30 '13 at 16:27
  • One more thing: Not everybody is working on web application these days. There are still a lot of invisible services and embedded systems out there. So maybe the client itself determine the time. – Marcel Jaeschke Jul 30 '13 at 16:31
  • Please illuminate me with an example of a situation where the timezone is relevant and how you collect it. – Nikola Yovchev Jul 30 '13 at 16:47
  • In addition, in the code provided you use the server/machine the jvm runs on' s default timezone and not the user's timezone. Which would mean in your company you like storing faulty data. – Nikola Yovchev Jul 30 '13 at 16:54
  • I can't tell you details, because it's confidential. But assume you receive reports of car accidents from all over the world. With the date+timezone you are able find out that 60% of all accidents happen before 8am. Your second point: You are right, the load method is incorrect. But it's just a quick example. No productive code which would past our tests. So I can assure you our data is not faulty. – Marcel Jaeschke Jul 30 '13 at 21:48
0

I'm pretty sure that they do this for a good reason so want to keep it this way.

Yea. When you save a serialized object in a database, your queries won't be able to perform any tests on the object; e.g. test whether one date is later than another one. In addition, you are making your application vulnerable to the problem of incompatible serial versions. (That's probably not an issue in this specific example, but the issue comes up repeatedly in SO questions ...)

My question: is there another way? I would like to get rid of the additional date field.

Unfortunately, I don't think there is.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216