Java PersistenceJava Persistence
Standard meets Reality
Arne Limburg // open knowledge GmbH
Standard meets Reality
Arne Limburg // open knowledge GmbH
JPA 2.0
The technical objective of this work is
to provide an object/relational mapping facilityfor the Java application developer
using a Java domain model
to manage a relational database.Zitat: JPA Spezifikation, v 2.0
AgendaAgenda
JPA CoreJPA Core
EE IntegrationEE Integration
Wolkige Zukunft?Wolkige Zukunft?
Persistenz in Java EE
Am Anfang war dieJDBC-API…
Image: digitalart / FreeDigitalPhotos.net
Persistenz in Java EE
Erster Versuch:- Bean-Managed PersistenceZweiter Versuch:- Container-Managed PersistenceParallel: JDO
Image: digitalart / FreeDigitalPhotos.net
Persistenz in Java EE
Schon besser: CMP 2Open Source auf der Überholspur:
Castor, IBatis, Hibernate
Ein Neubeginn: JPA
Image: digitalart / FreeDigitalPhotos.net
JPA aus 10.000 Metern
Building Blocks
EntityManagerFactoryEntityManagerFactoryEntityManagerFactoryEntityManagerFactory
EntityManager
QueryQueryQueryQuery
EntityTra
nsaction
CriteriaQueryCriteriaQueryCriteriaQueryCriteriaQueryCacheCacheCacheCache
Entity
EntityListener
MappedSuperclass
Embeddable
Eine JPA Entität@Entity @Table (name = "TAB_USER")public class User {
@Id @Column(name = "USER_ID" )private int id ;…
}
Ab JPA 2.1: Custom Converter@Entity @Table (name = "TAB_USER")public class User {
@Id @Column(name = "USER_ID" )private int id ;
@Convert (converter = MyConverter. class )private X509Certificate certificate ;…
}
Image: scottchan / FreeDigitalPhotos.net
Beziehungen
Granularität
Vererbung
Herausforderungen
Beziehungen – many-to-one@Entitypublic class User {
@ManyToOne@JoinColumn (name = "ROLE_ID" )private Role role ;…
}
Beziehungen - Bidirektional@Entitypublic class Role {
@OneToMany(mappedBy = "role" )private List<User> users ;…
}
Beziehungen – one-to-one@Entitypublic class User {
@OneToOne@JoinColumn (name = "ROLE_ID" )private Role role ;…
}
Beziehungen – geteilte Id@Entitypublic class Role {
@Id@OneToOneprivate User user ;…
}
Beziehungen – many-to-many@Entitypublic class User {
@ManyToMany@JoinTable (name = "TAB_USER_ROLES",
joinColumns = …,inverseJoinColumns = …)
private List<Role> roles ;…
}
Beziehungen – owning side@Entitypublic class Role {
@ManyToMany(mappedBy = "roles" )private List<User> users ;…
}
Image: scottchan / FreeDigitalPhotos.net
Beziehungen
Granularität
Vererbung
Herausforderungen
Granularität - Embeddables@Entitypublic class User {
@Embedded @AttributeOverride (…)private Role role ;…
}
@Embeddablepublic class Role {
…}
Granularität - ElementCollection@Entitypublic class User {
@ElementCollection@CollectionTable (name = "…",
joinColumns = …)private List<Role> roles ;…
}
Granularität – Simple Values@Entitypublic class User {
@ElementCollection@CollectionTable (name = "…",
joinColumns = …)private List<String> roles ;…
}
Image: scottchan / FreeDigitalPhotos.net
Beziehungen
Granularität
Vererbung
Herausforderungen
Vererbung – Single Table@Entity@Inheritance (strategy = SINGLE_TABLE)@DiscriminatorColumn (name = "…")public class User {
…}@Entity@DiscriminatorValue ( "…")public class Admin extends User {
…}
Vererbung – Table per Class@Entity@Inheritance (strategy = TABLE_PER_CLASS)public class User {
…}
@Entitypublic class Admin extends User {
…}
Vererbung – Joined@Entity@Inheritance (strategy = JOINED)public class User {
…}
@Entitypublic class Admin extends User {
…}
Vererbung – Secondary Table@Entity@Inheritance (strategy = JOINED)public class User {
…}
@Entity @SecondaryTable (name = "…")public class Admin extends User {
…}
Vererbung – Mapped Superclass
@MappedSuperclasspublic class AbstractUser {
…}
AgendaAgenda
JPA CoreJPA Core
EE IntegrationEE Integration
Wolkige Zukunft?Wolkige Zukunft?
EE IntegrationEE Integration
Integration mit CDIIntegration mit CDI
Integration mit EJBIntegration mit EJB
Entity-LebenszyklusEntity-Lebenszyklus
New
Managed Detached
Removed
entityManager.persistentityManager.merge
entityManager.remove
entityManager.detachentityManager.close
entityManager.mergeentityManager.findquery.getResultList()query.getSingleResult()
Entity-Lebenszyklus
New
Managed
Removed
entityManager.persistentityManager.merge
entityManager.remove
entityManager.detachentityManager.close
entityManager.mergeentityManager.findquery.getResultList()query.getSingleResult()
Entity-Lebenszyklus
Detached
Achtung:
Lazy-Initialization nicht im Zustand „detached“
Wann wird der EntityManagereigentlich geschlossen?
Fragestellungen• EntityManager
– Container- vs. Application-Managed– Transactional vs. Extended
• Transaction– JTA vs. Resource Local– Synchronized vs. Unsynchronized
• Datasource– JNDI vs. local– JTA vs. Non-JTA
Application-Managed
• Erzeugung via entityManagerFactory.createEntityManager(…)
• Transaktionsbehandlung (Manuell) – JTA entityManager.joinTransaction()
– RESOURCE_LOCAL entityManager.getTransaction().begin() entityManager.getTransaction().commit()
• Scope EXTENDED (Manuelle Verwaltung)
Application-Managed
• Erzeugung via entityManagerFactory.createEntityManager(…)
• Transaktionsbehandlung (Manuell) – JTA entityManager.joinTransaction()
– RESOURCE_LOCAL entityManager.getTransaction().begin() entityManager.getTransaction().commit()
• Scope EXTENDED (Manuelle Verwaltung)
Nachteil:
Keine PerstenceContext-Propagation!
EE IntegrationEE Integration
Integration mit CDIIntegration mit CDI
Integration mit EJBIntegration mit EJB
Entity-LebenszyklusEntity-Lebenszyklus
EE IntegrationEE Integration
Integration mit EJBIntegration mit EJB
@Statelesspublic class UserDaoEjb {
@PersistenceContextprivate EntityManager em;…
}
@Statelesspublic class UserDaoEjb {
@PersistenceContextprivate EntityManager em;…
public void businessMethod() {// EntityManager available
}}
Transaction-Scoped
@Statelesspublic class UserDaoEjb {
@PersistenceContextprivate EntityManager em;…
}
@Statelesspublic class UserDaoEjb {
@PersistenceContextprivate EntityManager em;…
public void businessMethod() {// EntityManager available
}}
@Statelesspublic class UserDaoEjb {
@PersistenceContextprivate EntityManager em;…@TransactionAttribute ( NEVER)public void businessMethod() {
// EntityManager not available}
}
Transaction-Scoped
Java-EE-5-Schichtenarchitektur
Transaktions-grenze
Vorsicht mit Lazy-Initialization
@Statefulpublic class UserDaoEjb {
@PersistenceContext (type = EXTENDED)private EntityManager em;…
}
@Statefulpublic class UserDaoEjb {
@PersistenceContext (type = EXTENDED)private EntityManager em;…
public void businessMethod() {// EntityManager available
}}
Session-Scoped
@Statefulpublic class UserDaoEjb {
@PersistenceContext (type = EXTENDED)private EntityManager em;…
}
@Statefulpublic class UserDaoEjb {
@PersistenceContext (type = EXTENDED)private EntityManager em;…
public void businessMethod() {// EntityManager available
}}
@Statefulpublic class UserDaoEjb {
@PersistenceContext (type = EXTENDED)private EntityManager em;…@TransactionAttribute ( NEVER)public void businessMethod() {
// EntityManager available}
}
Session-Scoped
@Statefulpublic class UserDaoEjb {
@PersistenceContext (synchronization = UNSYNCHRONIZED)
private EntityManager em;…
}
@Statefulpublic class UserDaoEjb {
@PersistenceContext (synchronization = UNSYNCHRONIZED)
private EntityManager em;…public void businessMethod() {
// no flush after invocation}
}
Unsynchronized (ab JPA 2.1)
@Statefulpublic class UserDaoEjb {
@PersistenceContext (synchronization = UNSYNCHRONIZED)
private EntityManager em;…
}
@Statefulpublic class UserDaoEjb {
@PersistenceContext (synchronization = UNSYNCHRONIZED)
private EntityManager em;…public void businessMethod() {
// no flush after invocation}
}
@Statefulpublic class UserDaoEjb {
@PersistenceContext (synchronization = UNSYNCHRONIZED)
private EntityManager em;…public void businessMethod() {
em.joinTransaction();// flush‘n‘commit after invocation
}}
Unsynchronized (ab JPA 2.1)
Producer für CDI@Statelesspublic class UserServiceEjb {
@Produces @PersistenceContextprivate EntityManager em;…
}
public class UserDao {@Injectprivate EntityManager em;
}
Fazit EJB-Integration
• Injection in Session Beans(stateful und stateless)
• Transaktionsgrenze– Methodenaufruf der Session Bean
(inklusive Transaction-Propagation)
• Scopes– Transaction (alle Session Beans)– Session (Stateful Session Beans)
EE IntegrationEE Integration
Integration mit EJBIntegration mit EJB
EE IntegrationEE Integration
Integration mit CDIIntegration mit CDI
Integration mit CDI (ab JPA 2.1)
public class MyEntityListener {
@Inject @Currentprivate User user ;
@PrePersistpublic void setCreator(MyEntity e) {
e.setCreator( user );}
}
Integration mit CDI (ab JPA 2.1)
public class MyEntityListener {
@Inject @Currentprivate User user ;
@PrePersistpublic void setCreator(MyEntity e) {
e.setCreator( user );}
}
Achtung:
Verhalten bei Zugriff auf andere Entitäten oder Verändern von Beziehungen ist nicht
standardisiert.
Integration mit CDIaußerhalb des Standards
CDI bietet viele Scopes und ausgefeiltes
Lifecycle-Management!
Kann das nicht für den EntityManager genutzt werden?
Request-Scoped EntityManager@ApplicationScopedpublic class MyPersistenceUnit {
@Produces@RequestScopedpublic EntityManager createEntityManager(
EntityManagerFactory factory) {return factory.createEntityManager();
}…
}
Lifecycle-Management von CDI@ApplicationScopedpublic class MyPersistenceUnit {
…
public void closeEntityManager(@Disposes EntityManager entityManager) {
entityManager.close();}
}
Schichtenarchitektur mit CDIEntityManagerlifecycle
Lazy-Initializationmöglich
Schichtenarchitektur mit CDIEntityManagerlifecycle
Lazy-Initializationmöglich
Offen:
Transaktionsgrenze
Transactional-Interceptor mit CDI@Transactional @Interceptorpublic class MyTransactionalInterceptor {
@Injectprivate EntityManager em;
…}
Transactional-Interceptor mit CDI@InterceptorBindingpublic @interface Transactional {}
Transactional-Interceptor mit CDI@Transactional @Interceptorpublic class MyTransactionalInterceptor {
@Injectprivate EntityManager em;
…}
Transactional-Interceptor mit CDI…@AroundInvokepublic Object startTransaction(
InvocationContext context) throws … {em.getTransaction().begin();try {
return context.proceed();} finally {
em.getTransaction().commit();}
}
Transactional-Interceptor mit CDI@ApplicationScopedpublic class MyUserDao {
@Injectprivate EntityManager em;
@Transactionalpublic void persist(User user) {
em.persist(user);}
}
Weitere Scopes?@ApplicationScopedpublic class MyPersistenceUnit {
@Produces@RequestScopedpublic EntityManager createEntityManager(
EntityManagerFactory factory) {return factory.createEntityManager();
}…
}
Conversation-Scope?@ApplicationScopedpublic class MyPersistenceUnit {
@Produces@ConversationScopedpublic EntityManager createEntityManager(
EntityManagerFactory factory) {return factory.createEntityManager();
}…
}
Custom Scope@ApplicationScopedpublic class MyPersistenceUnit {
@Produces@MyCustomScopedpublic EntityManager createEntityManager(
EntityManagerFactory factory) {return factory.createEntityManager();
}…
}
AgendaAgenda
JPA CoreJPA Core
EE IntegrationEE Integration
Wolkige Zukunft?Wolkige Zukunft?
Wolkige Zukunft?Wolkige Zukunft?
JPA und NoSQLJPA und NoSQL
MandantenfähigkeitMandantenfähigkeit
Wolkige Zukunft?Wolkige Zukunft?
MandantenfähigkeitMandantenfähigkeit
Mandantenfähigkeit in JPA 2.1
• Ein Mandant pro Applikation• Drei Strategien des Datenzugriffs
– SEPARATE_DATABASE– SEPARATE_SCHEMA– SHARED_TABLE (mit @TenantId Spalte)
Wolkige Zukunft?Wolkige Zukunft?
JPA und NoSQLJPA und NoSQL
MandantenfähigkeitMandantenfähigkeit
Wolkige Zukunft?Wolkige Zukunft?
JPA und NoSQLJPA und NoSQL
NoSQL – „Not only SQL“
• Nicht relational • Distributed• Big Data• Eventually Consistent
statt ACID• Map-Reduce statt SQL
• Key-Value– SimpleDB, Infinispan, Coherence, …
• Wide-Column– BigTable, Cassandra, …
• Document-Databases– MongoDB, CouchDB, …
• Object-Databases• … (z.B. Graph-Databases)
Varianten
Abfragemöglichkeiten
• Nach Primärschlüssel• SQL-like Abfragesprache (z.B.
SimpleDB)• Map-Reduce• …
Joins sind teuer!
Wie passt das zu JPA?
Fokus von JPA auf RDBMS
• Id-Generierungsstrategien• Joins• Subclassing• Polymorphie• Transaktionen
Vision
• Trennung von– Mapping (@Entity, @Id)– Relationale Spezifika
(@Table, @Column)?
• Querying• Transaktions-Behandlung
Stand der Dinge
Implementierungen • SimpleJPA (SimpleDB)• Datanucleus-appengine
(BigTable)• Hibernate-OGM
(Infinispan, MongoDB, …)
Fazit
Cloud Computing in Java EE• in Java EE 7
– Mandantenfähigkeit– JSR 347: Data Grids for the Java Platform
• In Java EE 8???
Fazit
Cloud Computing• in Java EE 7
– Mandantenfähigkeit– JSR 347: Data Grids for the Java Platform
• In Java EE 8???
JPA in der Cloud gibt es!
Der Weg von NoSQL in den JPA-Standard ist aber noch weit!
Vielen Dank für Ihre Zeit.
Kontakt:
open knowledge GmbHBismarckstr. 1326122 Oldenburg
ArneLimburg_openknowledge
Q&A