Frage

In meiner SQL Server 2000-Datenbank, ich habe einen Zeitstempel (in Funktion nicht in Datentyp) Spalte des Typ DATETIME namens lastTouched gesetzt als der Standardwert getdate() / bindend.

Ich bin mit dem Netbeans 6.5 JPA Entitätsklassen erzeugt, und habe dies in meinem Code

@Basic(optional = false)
@Column(name = "LastTouched")
@Temporal(TemporalType.TIMESTAMP)
private Date lastTouched;

Allerdings, wenn ich versuche, das Objekt in die Datenbank habe ich bekommen,

javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.generic.Stuff.lastTouched

Ich habe versucht, die Einstellung der @Basic Einstellung (optional = true), aber das wirft eine Ausnahme sagen, die Datenbank nicht null Werte für die TIMESTAMP Spalte, die es nicht mit Absicht.

erlaubt
ERROR JDBCExceptionReporter - Cannot insert the value NULL into column 'LastTouched', table 'DatabaseName.dbo.Stuff'; column does not allow nulls. INSERT fails.

ich das vorher bekam in reinem Hibernate zu arbeiten, aber ich habe Sinn zu JPA umgeschaltet und habe keine Ahnung, wie ihm zu sagen, dass diese Spalte auf der Seite Datenbank erzeugt wird annehmen wird. Beachten Sie, dass ich immer noch mit Hibernate als meine JPA Persistence Layer.

War es hilfreich?

Lösung

Ich reparierte das Problem durch den Code zu ändern

@Basic(optional = false)
@Column(name = "LastTouched", insertable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date lastTouched;

So ist die Timestamp-Spalte wird ignoriert, wenn SQL-Einsätze zu erzeugen. Nicht sicher, ob dies der beste Weg ist, um dies zu realisieren. Feedback ist willkommen.

Andere Tipps

Ich weiß, das ist ein bisschen spät, aber ich habe Erfolg eine Timestamp-Spalte mit

mit Anmerkungen versehen
@Column(name="timestamp", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")

Dies sollte auch mit CURRENT_DATE und CURRENT_TIME arbeiten. Ich bin mit JPA / Hibernate mit Oracle, so YMMV.

@Column(nullable = false, updatable = false)
@CreationTimestamp
private Date created_at;

Dies funktionierte für mich. weitere Informationen

Ich habe diesen gut funktioniert mit JPA2.0 und MySQL 5.5.10, für Fälle, in denen ich nur über das letzte Mal wurde darauf geachtet, die Zeile geändert. MySQL wird ein Zeitstempel auf der ersten Insertion, und jedes Mal, UPDATE auf der Zeile aufgerufen erstellen. (Hinweis: das wird problematisch sein, wenn ich sorgte mich, ob das UPDATE gemacht tatsächlich eine Änderung).

Der „Zeitstempel“ -Spalte in diesem Beispiel ist wie ein „letzter berührt“ column.x`

Der folgende Code verwendet eine separate Spalte „Version“ für die optimistische Sperren.

private long version;
private Date timeStamp

@Version
public long getVersion() {
    return version;
}

public void setVersion(long version) {
    this.version = version;
}

// columnDefinition could simply be = "TIMESTAMP", as the other settings are the MySQL default
@Column(name="timeStamp", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
public Date getTimeStamp() {
    return timeStamp;
}

public void setTimeStamp(Date timeStamp) {
    this.timeStamp = timeStamp;
}

(HINWEIS:. @Version nicht auf einer MySQL „DATETIME-“ Spalte funktioniert, wo der Attributtyp „Date“ in der Entity-Klasse ist dafür war, dass Datum wurde einen Wert bis auf die Millisekunde zu erzeugen, war jedoch nicht MySQL die Millisekunde zu speichern, so dass, wenn es einen Vergleich zwischen tat, was in der Datenbank war, und die „angehängt“ Einheit, sie dachten, dass sie unterschiedliche Versionsnummern)

hatten

Aus dem MySQL-Handbuch über TIMESTAMP :

With neither DEFAULT nor ON UPDATE clauses, it is the same as DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.

Ich glaube nicht, dass jede Datenbank Auto-Update-Zeitstempel (z Postgres) hat. Also habe ich beschlossen, in meinem Code manuell überall dieses Feld zu aktualisieren. Dies wird mit jeder Datenbank arbeiten:

thingy.setLastTouched(new Date());
HibernateUtil.save(thingy);

Es gibt Gründe, Auslöser zu verwenden, aber für die meisten Projekte, das ist nicht einer von ihnen. Trigger graben Sie noch tiefer in eine bestimmte Datenbank-Implementierung.

MySQL 5.6 .28 (Ubuntu 15.10, OpenJDK 64-Bit 1.8.0_66) scheint sehr nachsichtig zu sein, nicht über

erfordert etwas
@Column(name="LastTouched")

MySQL 5.7 0,9 (CentOS 6, OpenJDK 64-Bit 1.8.0_72) funktioniert nur mit

@Column(name="LastTouched", insertable=false, updatable=false)

nicht:

FAILED: removing @Temporal
FAILED: @Column(name="LastTouched", nullable=true)
FAILED: @Column(name="LastTouched", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")

Meine andere Systeminformationen (identisch in beiden Umgebungen)

  • Hibernate-EntityManager 5.0.2
  • Hibernate-Validator 5.2.2
  • mysql-connector-java 5.1.38
@Column(name = "LastTouched", insertable = false, updatable = false, columnDefinition = "TIMESTAMP default getdate()")
@Temporal(TemporalType.TIMESTAMP)
private Date LastTouched;`enter code here`
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top