Commits

Micha Kops committed 4527d64

Initial import.

Comments (0)

Files changed (9)

+.project
+.classpath
+.settings
+target
+derby.log
+hascode_testdb
+infinitest.filters
+# JPA Entity Listener Examples
+
+Some short examples for adding multiple entity listeners to a JPA 2 entity.
+
+Please feel free to take a look at my blog at [www.hascode.com] for the full tutorial!
+
+---
+
+**2013 Micha Kops / hasCode.com**
+
+   [www.hascode.com]:http://www.hascode.com/
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.hascode.tutorial</groupId>
+	<artifactId>jpa-entitylistener-tutorial</artifactId>
+	<version>1.0.0</version>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<derby.version>10.9.1.0</derby.version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.derby</groupId>
+			<artifactId>derbyclient</artifactId>
+			<version>${derby.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.derby</groupId>
+			<artifactId>derby</artifactId>
+			<version>${derby.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.hibernate</groupId>
+			<artifactId>hibernate-entitymanager</artifactId>
+			<version>4.1.9.Final</version>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.11</version>
+		</dependency>
+		<dependency>
+			<groupId>org.hamcrest</groupId>
+			<artifactId>hamcrest-all</artifactId>
+			<version>1.3</version>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.7</source>
+					<target>1.7</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>

src/main/java/com/hascode/tutorial/entity/Book.java

+package com.hascode.tutorial.entity;
+
+import java.util.Date;
+
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import com.hascode.tutorial.entity.listener.BookEntityListener;
+import com.hascode.tutorial.entity.listener.TitleValidator;
+
+@Entity
+@EntityListeners({ BookEntityListener.class, TitleValidator.class })
+public class Book implements TitleEntity {
+	@Id
+	@GeneratedValue
+	private Long id;
+
+	private String title;
+
+	@Temporal(TemporalType.DATE)
+	private Date published;
+
+	public final Long getId() {
+		return id;
+	}
+
+	public final void setId(final Long id) {
+		this.id = id;
+	}
+
+	@Override
+	public final String getTitle() {
+		return title;
+	}
+
+	public final void setTitle(final String title) {
+		this.title = title;
+	}
+
+	public final Date getPublished() {
+		return published;
+	}
+
+	public final void setPublished(final Date published) {
+		this.published = published;
+	}
+
+	@Override
+	public String toString() {
+		return "Book [id=" + id + ", title=" + title + ", published="
+				+ published + "]";
+	}
+}

src/main/java/com/hascode/tutorial/entity/TitleEntity.java

+package com.hascode.tutorial.entity;
+
+public interface TitleEntity {
+	String getTitle();
+}

src/main/java/com/hascode/tutorial/entity/listener/BookEntityListener.java

+package com.hascode.tutorial.entity.listener;
+
+import javax.persistence.PostLoad;
+import javax.persistence.PrePersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PreUpdate;
+
+import com.hascode.tutorial.entity.Book;
+
+public class BookEntityListener {
+
+	@PrePersist
+	public void prePersist(final Book book) {
+		System.out.println("prePersist: " + book.toString());
+	}
+
+	@PreUpdate
+	public void preUpdate(final Book book) {
+		System.out.println("preUpdate: " + book.toString());
+	}
+
+	@PostLoad
+	public void postLoad(final Book book) {
+		System.out.println("postLoad: " + book.toString());
+	}
+
+	@PreRemove
+	public void preRemove(final Book book) {
+		System.out.println("preRemove: " + book.toString());
+	}
+
+}

src/main/java/com/hascode/tutorial/entity/listener/TitleValidator.java

+package com.hascode.tutorial.entity.listener;
+
+import javax.persistence.PersistenceException;
+import javax.persistence.PrePersist;
+
+import com.hascode.tutorial.entity.TitleEntity;
+
+public class TitleValidator {
+	private final String[] badWords = { "shitty", "xxx", "..." };
+
+	@PrePersist
+	public void checkBadWords(final TitleEntity titleEntity) {
+		for (String badWord : badWords) {
+			if (titleEntity.getTitle().contains(badWord)) {
+				System.err.println("bad word in title detected: " + badWord);
+				throw new PersistenceException("bad word in title detected: "
+						+ badWord);
+				// should use ValidationException if bean validation is present
+			}
+		}
+	}
+}

src/test/java/it/BookIT.java

+package it;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+import java.sql.SQLException;
+import java.util.Date;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+import javax.persistence.PersistenceException;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.hascode.tutorial.entity.Book;
+
+public class BookIT {
+	static EntityManagerFactory emf;
+	static EntityManager em;
+	static EntityTransaction tx;
+
+	@BeforeClass
+	public static void setupClass() throws Exception {
+		emf = Persistence.createEntityManagerFactory("hascode-tutorial");
+		em = emf.createEntityManager();
+		tx = em.getTransaction();
+	}
+
+	@Before
+	public void setUp() {
+		tx.begin();
+	}
+
+	@AfterClass
+	public static void teardownClass() throws SQLException {
+		em.close();
+		emf.close();
+	}
+
+	@After
+	public void tearDown() {
+		tx.rollback();
+	}
+
+	@Test(timeout = 10000)
+	public void shouldTriggerBookLifecycles() throws Exception {
+		Book book = new Book();
+		book.setPublished(new Date());
+		book.setTitle("Some book");
+		em.persist(book);
+		assertThat(book.getId(), is(notNullValue()));
+		assertThat(book.getId(), is(1L));
+
+		book.setPublished(new Date());
+		em.persist(book);
+		em.refresh(book); // we just want to trigger postLoad
+
+		Book book2 = em.find(Book.class, 1L);
+		assertThat(book2, is(notNullValue()));
+		assertThat(book2.getId(), is(book.getId()));
+		assertThat(book2.getTitle(), is(book.getTitle()));
+
+		em.remove(book2);
+	}
+
+	@Test(timeout = 10000, expected = PersistenceException.class)
+	public void testShouldValidateTitle() throws Exception {
+		Book book = new Book();
+		book.setPublished(new Date());
+		book.setTitle("The shitty boook");
+		em.persist(book);
+	}
+}

src/test/resources/META-INF/persistence.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+	version="1.0">
+	<persistence-unit name="hascode-tutorial"
+		transaction-type="RESOURCE_LOCAL">
+		<provider>org.hibernate.ejb.HibernatePersistence</provider>
+		<class>com.hascode.tutorial.entity.Book</class>
+		<properties>
+			<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
+			<property name="javax.persistence.jdbc.url" value="jdbc:derby:hascode_testdb;create=true" />
+			<property name="hibernate.show_sql" value="true" />
+			<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" />
+			<property name="hibernate.hbm2ddl.auto" value="create-drop" />
+		</properties>
+	</persistence-unit>
+</persistence>