JPA - Java Persitence API#

Download APIhttp://mirrors.ibiblio.org/pub/mirrors/maven2/javax/persistence/persistence-api/1.0/

Special topic: Mapping a many-to-many join table with extra column using JPA with EclipseLink

  • Defines a common set of functionality for ORM (object relation mapping)
  • Uses Annotations (Since Java 5.0) or XML mappings
  • You need a "Persistence Provider", because the JPA contains just the rules
  • Providers are (you can use any)
    • EclipseLink, former TopLink (comes with glassfish)
    • Hibernate (comes with JBoss)
    • OpenJPA (comes with Geronimo)
  • JPQL reference

Use JPA and EclipseLink on Java SE (Standalone, without Container or AppServer)#

(see also here and here and this example)

1. Create a folder "meta-inf" under your src and create the file "persistence.xml" with all information for the EntityManagerFactory (provider) to create an instance of EntityManager:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
	xmlns="http://java.sun.com/xml/ns/persistence">
	<persistence-unit name="dp">
		<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
		<class>ebel.auth.User</class>
		<exclude-unlisted-classes>true</exclude-unlisted-classes>
		<properties>
			<property name="eclipselink.logging.level" value="FINE" />
			<property name="eclipselink.logging.thread" value="true" />
			<property name="eclipselink.logging.session" value="true" />
			<property name="eclipselink.logging.timestamp" value="true" />
			<property name="eclipselink.logging.exceptions" value="true" />


			<property name="eclipselink.jdbc.url" value="jdbc:mysql://localhost:3306/databasename" />
			<property name="eclipselink.jdbc.user" value="root" />
			<property name="eclipselink.jdbc.password" value="xxx" />
			<property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.Driver" />
			<property name="eclipselink.jdbc.read-connections.min"
				value="1" />
			<property name="eclipselink.jdbc.write-connections.min"
				value="1" />
			<!-- <property name="eclipselink.ddl-generation" value="create-tables" />
			 -->
		</properties>
	</persistence-unit>
</persistence>
You can lookup settings here:
EntityManagerFactory Propertieshttp://wiki.eclipse.org/EclipseLink/Features/JPA#EntityManagerFactory_Properties
EclipseLink Specific Settings (Properties)http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29
Annotationshttp://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html#IndexOfAnnotations

2. Get the libs
(you can download glassfish and copy the jars)

JDBC-Driver
my-sql-connector-java-5.1.7-bin.jar (or any other jdbc driver)

EclipseLink
org.eclipse.persistence.antlr.jar
org.eclipse.persistence.asm.jar
org.eclipse.persistence.core.jar
org.eclipse.persistence.jpa.jar

JPA
javax.persistence.jar

3. Get an Entity Manager

    emf = Persistence.createEntityManagerFactory("dp");
    em = emf.createEntityManager();
    ...
    em.close();
    emf.close()    
Note1: You should encapsulate the creation of the Entity Manager in a Singleton Pattern, e.g. make sure you use and reuse only one instance of it. Otherwise you get the whole initialization for each instantiation. Especially if you use <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> all tables will be dropped and recreated each time you instantiate the entity manager.

4. Use it (for example save object User)

	em.getTransaction().begin();
	User u = new User("hugo", "password");
        em.persist(u);
	em.getTransaction().commit();

Use JPA with Dependency Injection#

  • This works only with EJBs
  • It is not sufficient to annotate a class only !
  • You need to let the AppServer give you an EJB, e.g. request one instance from JNDI
  • the app server should tell you the JNDI name of the EJB during boot in the log
  • see also here

5. JPA OneToMany not deleting child, use following provider additions:

EclipseLink@PrivateOwned
Hibernate@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE, org.hibernate.annotations.CascadeType.MERGE, org.hibernate.annotations.CascadeType.PERSIST, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})