MySql und JPA-Timestamp Problem

marky8264

Aktives Mitglied
hi,

ich habe eine Tabelle, welche als Primärschlüssel das Erstellungsdatum hat. Um zu verhindern das es zu Überschneidungen kommen kann, hab ich mir gedacht, das Datum als Timestamp zu speichern.

Das Problem ist nun, das es so aussieht, als würde jetzt das Datum zu ungenau sein, weil bei den Unit-Tests sich die Datensätze überschneiden. 🙁

Könnte dies jetzt daran liegen, das JPA den Timestamp mit dem MySQl-Datetime-Typ mappt oder weil ich im Programm Date verwende? ???:L

Hier ein Ausschnitt aus dem Mapping:
Java:
@Id
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="a_created_at",nullable=false)
    private Date createdAt=new Date();

mfg
 
Oder sie sind einfach gleich, weil sie zu schnell hintereinander erstellt werden. Der Standart-Konstruktor erstellt ein Datum "nur" auf die Millisekunde genau.

Java:
package de.javaforum.test;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DatumTest {

	public static void main(String [] args) {
		Date date1, date2, date3, date4, date5, date6, date7, date8, date9;
		DateFormat formatter = new SimpleDateFormat("HH:mm:ss-S");
		
		date1 = new Date();
		date2 = new Date();
		date3 = new Date();
		date4 = new Date();
		date5 = new Date();
		date6 = new Date();
		date7 = new Date();
		date8 = new Date();
		date9 = new Date();

		System.out.println(formatter.format(date1));
		System.out.println(formatter.format(date2));
		System.out.println(formatter.format(date3));
		System.out.println(formatter.format(date4));
		System.out.println(formatter.format(date5));
		System.out.println(formatter.format(date6));
		System.out.println(formatter.format(date7));
		System.out.println(formatter.format(date8));
		System.out.println(formatter.format(date9));	
	}
}

Es hat schon einige Testläufe gebraucht, bis man mal einen Unterschied sehen konnte:
Code:
16:14:18-845
16:14:18-845
16:14:18-845
16:14:18-845
16:14:18-845
16:14:18-845
16:14:18-846
16:14:18-846
16:14:18-846
 
danke für die Antwort.

Ich glaube das du recht hast. Habe jetzt folgendes ausprobiert:
Java:
 @Id
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="a_created_at",nullable=false)
    private Date createdAt=new Date(System.nanoTime());

aber jetzt steht in da DB-Tabelle ein falsches Datum ???:L:
Code:
3661-12-10 13:21:36

mfg
 
Das war grade unglücklich ausgedrückt. Mit Date geht das so nicht, da Date nur auf Milisekunden genau ist.

Der Konstruktor Date(long date) erwartet die Anzahl der Milisekunden seit dem [c]January 1, 1970, 00:00:00 GMT.[/c]. Was du da reinsteckst, ist aber was komplett anderes ... deswegen kommt da auch so ein merkwürdiges Datum bei raus.

Für die Unit-Tests kannst du das ja ruhig erstmal so lassen. Grundsätzlich solltest du dich aber fragen, ob du hier nicht am Model nachbessern solltest.

Nur interessehalber: spricht denn irgendwas gegen eine fortlaufende ID? Den Timestamp kannst du ja trotzdem abspeichern.
 
Asso, das erklärt natürlich die Ausgabe.

es geht mir ja nicht um die Unit-Tests. Mein Programm soll eine Mehrbenutzeranwendung werden. Auch wenn die Wahrscheinlichkeit sehr gering ist, dass es zur Überschneidungen kommt, besteht die Gefahr.

Grundsätzlich spricht zwar nichts dagegen. Der Grund für die Auswahl liegt darin, dass ich einen zweiteiligen Schlüssel verhindern wollte.

Allerdings werde ich deinen Rat befolgen und einfach eine zusätzliche Spalte, welche die Nanosekunden als Long enthält, hinzufügen.

Danke für deine Hilfe 🙂
mfg
 
Das versteh ich jetzt nicht ...

Du willst einen zweiteiligen Schlüssel verhindern, aber nimmst dann für die Eindeutigkeit doch noch eine weitere Spalte zusätzlich? Das widerspricht sich doch. Außerdem könntest du dann doch gleich nur die nanoTime-Spalte nehmen (das wäre jedenfalls fast identisch) ...
Das ursprüngliche Problem hast du damit übrigens auch nicht beseitigt, sondern es tritt nur noch viel seltener ein. Mit einer fortlaufenden ID hättest du solche Probleme nicht.
 
sry, hab mich falsch ausgedrückt.

Mein Primärschlüssel würde normalerweise aus 2 Spalten bestehen:
Typ + fortlaufende ID (eindeutig innerhalb eines Typs)

Deswegen wollte ich nur eine Spalte nämlich den Erstellungszeitpunkt nehmen.

Ja ich weiß, aber die Wahrscheinlichkeit ist gering genug. 😉
mfg
 
Optimistic locking mit version wird von JPA direkt unterstüzt 😉

*verschoben*
 
Zuletzt bearbeitet von einem Moderator:

Zurück
Oben