Skip to content

Instantly share code, notes, and snippets.

@php-coder
Created November 24, 2011 10:51
Show Gist options
  • Save php-coder/1391084 to your computer and use it in GitHub Desktop.
Save php-coder/1391084 to your computer and use it in GitHub Desktop.
JPA @EntityListeners example
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@EntityListeners({
CreatedAtListener.class,
UpdatedAtListener.class
})
@Table(name = "articles")
public class Article implements Creatable, Updatable {
@Id
@GeneratedValue
private Integer id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String author;
@Column(name = "created_at", nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
@Column(name = "updated_at", nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date updatedAt;
@Override
public String toString() {
return "Article [id=" + id + ", title=" + title + ", author=" + author
+ ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + "]";
}
// getters and setters ommited
}
import java.util.Date;
public interface Creatable {
void setCreatedAt(final Date date);
}
import java.util.Date;
import javax.persistence.PrePersist;
public class CreatedAtListener {
@PrePersist
public void setCreatedAt(final Creatable entity) {
entity.setCreatedAt(new Date());
}
}
public void createAndUpdateArticleExample() {
final Article article = new Article();
article.setAuthor("Test");
article.setTitle("title");
System.out.println("Before creation: " + article);
entityManager.persist(article);
System.out.println("After creation: " + article);
try {
SECONDS.sleep(2);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
article.setAuthor("Test2");
entityManager.persist(article);
entityManager.flush();
System.out.println("After flush: " + article);
}
Before creation: Article [id=null, title=title, author=Test, createdAt=null, updatedAt=null]
After creation: Article [id=1, title=title, author=Test, createdAt=Thu Nov 24 16:36:48 NOVT 2011, updatedAt=Thu Nov 24 16:36:48 NOVT 2011]
After flush: Article [id=1, title=title, author=Test2, createdAt=Thu Nov 24 16:36:48 NOVT 2011, updatedAt=Thu Nov 24 16:36:50 NOVT 2011]
import java.util.Date;
public interface Updatable {
void setUpdatedAt(final Date date);
}
import java.util.Date;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
public class UpdatedAtListener {
@PrePersist
@PreUpdate
public void setUpdatedAt(final Updatable entity) {
entity.setUpdatedAt(new Date());
}
}
@cyberroot
Copy link

Nice one! Which package Creatable.java and Updatable.java files goes to?

@krichter722
Copy link

Entities shouldn't implement interfaces if it can be avoided because it gets you into avoidable trouble with targetEntity.

@marvinren
Copy link

Nice

@firatkucuk
Copy link

I don't know why but it didn't work.

@wodencafe
Copy link

wodencafe commented Dec 19, 2017

Unfortunately this isn't working for me either, when I try to save my entity, I get:

Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value : com.business.model.Contactable.modifiedDate
	at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:92)
	at org.hibernate.action.internal.AbstractEntityInsertAction.nullifyTransientReferencesIfNotAlready(AbstractEntityInsertAction.java:115)
	at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:69)
	at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:626)
	at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:280)
	at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:261)
	at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:306)
	at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318)
	at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275)
	at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
	at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
	at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67)
	at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189)
	at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132)
	at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58)
	at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:782)
	... 30 more

To make this work, I had to remove nullable = false from the Created Date and Updated Date @column annotations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment