In meiner SQL Server 2000 - Datenbank, habe ich einen Zeitstempel (in Funktion nicht in Datentyp) Spalt vom Typ DATETIME
namens lastTouched
Satz getdate()
als den Standardwert / bindend.
Ich verwende die von Netbeans 6.5 generierten JPA-Entitätsklassen und habe diese in meinem Code
@Basic(optional = false)
@Column(name = "LastTouched")
@Temporal(TemporalType.TIMESTAMP)
private Date lastTouched;
Wenn ich jedoch versuche, das Objekt in die Datenbank zu stellen, erhalte ich Folgendes:
javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.generic.Stuff.lastTouched
Ich habe versucht, das auf @Basic
zu setzen (optional = true)
, aber das löst eine Ausnahme aus, die besagt, dass die Datenbank keine null
Werte für die TIMESTAMP
Spalte zulässt , was nicht beabsichtigt ist.
ERROR JDBCExceptionReporter - Cannot insert the value NULL into column 'LastTouched', table 'DatabaseName.dbo.Stuff'; column does not allow nulls. INSERT fails.
Ich habe dies zuvor im reinen Ruhezustand zum Laufen gebracht, bin aber inzwischen auf JPA umgestiegen und habe keine Ahnung, wie ich sagen soll, dass diese Spalte auf der Datenbankseite generiert werden soll. Beachten Sie, dass ich immer noch den Ruhezustand als JPA-Persistenzschicht verwende.
quelle
Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: @Temporal should only be set on a java.util.Date or java.util.Calendar
Mir ist klar, dass dies etwas spät ist, aber ich hatte Erfolg damit, eine Zeitstempelspalte mit zu kommentieren
@Column(name="timestamp", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
Dies sollte auch mit
CURRENT_DATE
und funktionierenCURRENT_TIME
. Ich verwende JPA / Hibernate mit Oracle, also YMMV.quelle
insertable=false, updatable=false
ERROR 4371 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '
TIMESTAMP DEFAULT CURRENT_TIMESTAMP` nicht null,full_content
Langtext nicht null 'in Zeile 1. My column is:
@Column (nullable = false, name = "created_at", updatable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP") `undprivate Timestamp createdAt;
@Column(nullable = false, updatable = false) @CreationTimestamp private Date created_at;
das hat bei mir funktioniert. Mehr Info
quelle
Fügen Sie die
@CreationTimestamp
Anmerkung hinzu:@CreationTimestamp @Column(name="timestamp", nullable = false, updatable = false, insertable = false) private Timestamp timestamp;
quelle
Ich habe dies gut mit JPA2.0 und MySQL 5.5.10, für Fälle, in denen es mir nur darum geht, wann die Zeile das letzte Mal geändert wurde. MySQL erstellt beim ersten Einfügen einen Zeitstempel und jedes Mal, wenn UPDATE in der Zeile aufgerufen wird. (HINWEIS: Dies ist problematisch, wenn es mich interessiert, ob das UPDATE tatsächlich eine Änderung vorgenommen hat oder nicht).
Die Spalte "Zeitstempel" in diesem Beispiel ähnelt einer Spalte "zuletzt berührt" .x`
Der folgende Code verwendet eine separate Spalte "Version" für optimistisches 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 funktioniert nicht in einer MySQL-Spalte "DATETIME", in der der Attributtyp "Date" in der Entity-Klasse lautet. Dies lag daran, dass Date einen Wert bis zur Millisekunde generiert hat, MySQL jedoch die Millisekunde nicht gespeichert hat Als also ein Vergleich zwischen dem Inhalt der Datenbank und der "angehängten" Entität durchgeführt wurde, dachte man, sie hätten unterschiedliche Versionsnummern.
Aus dem MySQL-Handbuch zu TIMESTAMP :
quelle
Ich glaube nicht, dass jede Datenbank Zeitstempel für die automatische Aktualisierung hat (z. B. Postgres). Daher habe ich beschlossen, dieses Feld überall in meinem Code manuell zu aktualisieren. Dies funktioniert mit jeder Datenbank:
thingy.setLastTouched(new Date()); HibernateUtil.save(thingy);
Es gibt Gründe, Trigger zu verwenden, aber für die meisten Projekte ist dies keiner von ihnen. Trigger führen Sie noch tiefer in eine bestimmte Datenbankimplementierung ein.
MySQL 5.6.28 (Ubuntu 15.10, OpenJDK 64-Bit 1.8.0_66) scheint sehr nachsichtig zu sein und erfordert nichts weiter
@Column(name="LastTouched")
MySQL 5.7 .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 anderen Systeminformationen (in beiden Umgebungen identisch)
quelle
Wenn Sie Ihre Entität mit
@DynamicInsert
z@Entity @DynamicInsert @Table(name = "TABLE_NAME") public class ClassName implements Serializable {
Im Ruhezustand wird SQL ohne
null
Werte generiert . Dann fügt die Datenbank ihren eigenen Standardwert ein. Dies hat Auswirkungen auf die Leistung. Siehe [Dynamisches Einfügen] [1].quelle
Ich poste dies für Leute, die nach einer Antwort suchen, wenn sie MySQL und Java Spring Boot JPA verwenden, wie @immanuelRocha sagt, nur @CreationTimeStamp auf die @ Spalte im Frühjahr setzen und in MySQL den Standardwert auf "CURRENT_TIMESTAMP" setzen.
Fügen Sie im Frühjahr nur die Zeile hinzu:
quelle
Das funktioniert auch bei mir: -
@Temporal(TemporalType.TIMESTAMP) @Column(name = "CREATE_DATE_TIME", nullable = false, updatable = false, insertable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP") public Date getCreateDateTime() { return createDateTime; } public void setCreateDateTime(Date createDateTime) { this.createDateTime = createDateTime; }
quelle
Wenn Sie in Java 8 und Hibernate 5 oder Spring Boot JPA entwickeln, verwenden Sie die folgenden Anmerkungen direkt in Ihrer Entity-Klasse. Der Ruhezustand ruft den aktuellen Zeitstempel von der VM ab und fügt Datum und Uhrzeit in die Datenbank ein.
public class YourEntity { @Id @GeneratedValue private Long id; private String name; @CreationTimestamp private LocalDateTime createdDateTime; @UpdateTimestamp private LocalDateTime updatedDateTime; … }
quelle
@Column(name = "LastTouched", insertable = false, updatable = false, columnDefinition = "TIMESTAMP default getdate()") @Temporal(TemporalType.TIMESTAMP) private Date LastTouched;`enter code here`
quelle
Das hat bei mir funktioniert:
@Column(name = "transactionCreatedDate", nullable = false, updatable = false, insertable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
quelle