The purpose is to activate Hibernate with an in-memory database instance and illustrate basic CRUD (Create, Read, Update, Delete) operations. We use a simple JPA annotated item and Pojomatic for a nice string representation:
@Entity @AutoProperty public class Item implements Serializable { @Id @GeneratedValue(strategy=GenerationType.AUTO) private long ID; // Setter & Getters, Pojomatic methods... }
public static void save(Object o) { EntityTransaction et = EM.getTransaction(); et.begin(); EM.persist(o); et.commit(); } public static <T> T get(Class<T> entityType, Object key) { return EM.find(entityType, key); } public static void update(Object o) { EntityTransaction et = EM.getTransaction(); et.begin(); EM.merge(o); et.commit(); } public static void delete(Object o) { EntityTransaction et = EM.getTransaction(); et.begin(); EM.remove(o); et.commit(); }
private static EntityManagerFactory EMF; private static EntityManager EM; public static void main(String[] args) { // Creating resources EMF = Persistence.createEntityManagerFactory("Standalone"); EM = EMF.createEntityManager(); // Create Item i = new Item(); i.setName("Item A"); System.out.println("Before saving : " + i); save(i); System.out.println("After saving : " + i); // Read Item retr = get(Item.class, i.getID()); System.out.println("Retrieved I : " + retr); // Update i.setName("Item B"); System.out.println("Updated : " + i); update(i); retr = get(Item.class, i.getID()); System.out.println("Retrieved II : " + retr); // Delete System.out.println("Deleting : " + i); delete(i); retr = get(Item.class, i.getID()); System.out.println("Retrieved III : " + retr); // Closing resources EM.close(); EMF.close(); }
Before saving : Item{ID: {0}, name: {Item A}} After saving : Item{ID: {1}, name: {Item A}} Retrieved I : {1}, name: {Item A}} Updated : Item{ID: {1}, name: {Item B}} Retrieved II : Item{ID: {1}, name: {Item B}} Deleting : Item{ID: {1}, name: {Item B}} Retrieved III : null
REM: The way transactions are used in the above example is not clean. Typically, one should wrap them in a try catch as following to trigger rollbacks when necessary:
EntityTransaction et = EM.getTransaction(); try { et.begin(); EM.merge(o); // Or any other operations... et.commit(); } catch(Exception ex) { et.rollback(); throw ex; }
The Web Application version of this example is available here. More about JPA transaction types and the Java Transaction API (JTA) here.
--------------------
The persistence.xml file is configured as following (with hsqldb):
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="Standalone" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>com.jverstry.standalone.Item</class> <properties> <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/> <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:testdb"/> <property name="javax.persistence.jdbc.user" value="sa"/> <property name="javax.persistence.jdbc.password" value=""/> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="create"/> </properties> </persistence-unit> </persistence>
<dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>2.2.8</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.1.5.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.1.5.Final</version> </dependency> <dependency> <groupId>org.pojomatic</groupId> <artifactId>pojomatic</artifactId> <version>1.0</version> <type>jar</type> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.6.6</version> </dependency> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>6.0</version> <type>jar</type> <scope>provided</scope> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.0.0.GA</version> <scope>test</scope> </dependency>
Nice post ? By the way did I miss the try catch finally block in main method while closing resource ?
ReplyDeleteJavin
10 OOOPS and SOLID design principle for java developers
This code is only created to illustrate general principles. Please refrain from posting links to your blog if it is not directly related to the matter (self-promotion vs reader value). Else, I will delete your comments. Thanks.
DeleteGood stuff. Look forward to the whole series.
ReplyDelete