Objektrelationales Mapping mit EclipseLink und Spring Stefan Scheidt OPITZ CONSULTING GmbH
Ihr Referent Stefan Scheidt Senior Architekt bei der OPITZ CONSULTING GmbH Seit über 10 Jahren im Oracle- und Java-Umfeld tätig Schwerpunkt: Leichtgewichtiges Enterprise-Java Autor für Javamagazin, JavaSPEKTRUM, OBJEKTspektrum Referent auf DOAG, JAX und OOP Email: stefan.scheidt@opitz-consulting.de
Agenda Persistenz in Java Objektrelationales Mapping Java Persistence API und EclipseLink Das Spring Framework EclipseLink und Spring in Aktion Fazit
Persistenz in Java Lebensdauer von Daten in Java-Anwendungen ist kurz
Der Impedance Mismatch Unverträglichkeiten beim Versuch, Objekte auf relationale Tabellen abzubilden
Identität?
Beziehungen?
Vererbung? In Java gibt es Vererbung. In RDBMS nicht.
complete persistence framework that is both comprehensive and universal EclipseLink
EclipseLink Fact Sheet Open-Source-Projekt bei eclipse.org Spende der TopLink Codebase durch Oracle Implementiert JPA 1.0 Support für weitere Standards Ausgewählt als JPA-2.0-Referenz
EclipseLink vs. Oracle TopLink TopLink 11g baut auf EclipseLink 1.0 auf Zusätzlich: Integration mit Oracle Coherence Integration für OC4J 10.1.3 Migrationssupport
EclipseLink und Spring in Aktion
Annotationen Neues Sprachmittel in Java 5 zeichnen Codeelemente aus Beispiel: @Entity public class Item { @Override public String tostring() { return "Item '" + name; } }
Einige grundlegende JPA-Mappings @Entity @Table(name = "CATEGORIES") public class Category { @Id @Column(name = "CTGR_ID") @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Version private Long version; @Basic(optional = false) private String name;...
Beziehungen @Entity @Table(name = "ORDERS") public class Order {... @ManyToOne @JoinColumn(name = "CUST_ID", nullable = false) private Customer customer; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) private List<OrderItem> orderitems = new ArrayList<OrderItem>(); }...
Vererbung @Entity @Table(name = "BUSINESS_PARTNERS") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn( name = "TYPE", discriminatortype = DiscriminatorType.STRING) public abstract class AbstractBusinessPartner {... } @Entity @DiscriminatorValue("CUSTOMER") public class Customer extends AbstractBusinessPartner {... }
EclipseLink-Erweiterungen EclipseLink stellt viele Ergänzungen bereit: @PrivateOwned @OptimisticLocking @ReturnInsert/@ReturnUpdate @NamedStoredProcedureQuery und viele weitere
@PrivateOwned Für Parent-Child-Beziehungen In Kombination mit @OneToMany oder @OneToOne Kaskadiert insert und delete Durch parent.remove(child) wird child gelöscht
@PrivateOwned @Entity @Table(name = "ORDERS") public class Order { @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) @PrivateOwned private List<OrderItem> orderitems = new ArrayList<OrderItem>(); }...
@OptimisticLocking Erlaubt Konfiguration des Optimistic Locking. Definition: @Entity @Table(name = "CATEGORIES") @OptimisticLocking(type = OptimisticLockingType.ALL_COLUMNS) public class Category {... } Weitere Typen: CHANGED_COLUMNS, SELECTED_COLUMS, VERSION_COLUMN
@ReturnInsert/@ReturnUpdate Nutzt insert/update returning values Sehr nützlich in Kombination mit DB-Triggern @Entity @Table(name = "ORDERS") public class Order { } @Basic(optional = false) @Temporal(TemporalType.DATE) @ReturnInsert private Date orderdate;...
@NamedStoredProcedureQuery Nutzt Stored Procedures für Abfragen. Definition: @NamedStoredProcedureQuery(name = "findcategorybyid", procedurename = "CTGR_Get_Row", resultclass = Category.class, parameters = { @StoredProcedureParameter(name = "P_CTGR_ID", queryparameter = "CTGR_ID", direction = Direction.IN_OUT), @StoredProcedureParameter(name = "P_NAME", queryparameter = "NAME", direction = Direction.OUT), @StoredProcedureParameter(name = "P_DESCRIPTION", queryparameter = "DESCRIPTION", direction = Direction.OUT) })
@NamedStoredProcedureQuery Verwendung: public Category findbyid(long id) { return (Category) entitymanager.createnamedquery("findcategorybyid").setparameter("ctgr_id", id).getsingleresult(); }
Entity Manager Java-Interface javax.persistence.entitymanager Stellt Methode zur Verwaltung von Entitäten bereit Wird von JPA-Provider implementiert
public interface EntityManager { // "insert" public void persist(object entity); // "update" public <T> T merge(t entity); // "delete" public void remove(object entity); // "post" public void flush(); // "find by primary key" public <T> T find(class<t> entityclass, Object pk); // "select" public Query createquery(string qlstring); } //...
Entity Manager bereitstellen In unmanaged environment : mit EntityManagerFactory In managed environment : mit @PersistenceContext
@PersistenceContext public class CategoryDataAccess { } @PersistenceContext private EntityManager entitymanager; public void persist(category category) { entitymanager.persist(category); } //...
Persistence Unit Konfiguration für ein JPA-Environment Definitiert durch META-INF/persistence.xml
<?xml version="1.0" encoding="utf-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"... > <persistence-unit name="sampleunit" transaction-type="resource_local"> <provider>org.eclipse.persistence.jpa. PersistenceProvider</provider> <class>de.opitzconsulting...category</class> <class>de.opitzconsulting...item</class> <properties> <property name="eclipselink.ddl-generation" value="none "/> <property name="eclipselink.logging.level" value="fine"/> </properties> </persistence-unit> </persistence>
EclipseLink Properties EclipseLink stellt viele Parameter zur Verfügung: eclipselink.jdbc.bind-parameters eclipselink.jdbc.batch-writing eclipselink.jdbc.cache-statements eclipselink.jdbc.exclusive-connection.* eclipselink.jdbc.read-/write-connections.* und viele weitere
Typische Architektur Remote Exporter Präsentationsschicht Service Interface Transaktionsgrenzen Service Implementierung DAO Interface Fach Objekte DAO DAO Implementierung DI-Container Datenbank
Spring Application Context Bauplan für die Bestandteile einer Applikation Meist Sammlung von Bean Definitions in XML
Anbindung an die Datenbank <bean id="datasource" class="org...basicdatasource"> <property name="driverclassname" value="oracle.jdbc.oracledriver" /> <property name="url" value="jdbc:oracle:thin:@..." /> <property name="username value="scott" /> <property name="password value="tiger" /> </bean>
Auswahl des JPA-Providers <bean id="eclipselinkjpavendoradapter" class="org.springframework.orm.jpa.vendor. EclipseLinkJpaVendorAdapter"> </bean>
Bereitstellen des Entity Manager <bean id="entitymanagerfactory" class="org.springframework.orm.jpa. LocalContainerEntityManagerFactoryBean"> <property name="datasource ref="datasource" /> <property name="jpavendoradapter" ref="eclipselinkjpavendoradapter" /> </bean>
Transaktionsmanagement <bean id="transactionmanager" class="org.springframework.orm.jpa. JpaTransactionManager"> <property name="entitymanagerfactory" ref="entitymanagerfactory" /> </bean> <tx:annotation-driven /> Wichtig in META-INF/persistence.xml: <persistence-unit name="..." transaction-type="resource_local">... </persistence-unit>
Übersicht
Datenzugriff: Schnittstelle public interface CategoryDao { Category findbyid(long id); List<Category> findall(); void persist(category category); Category merge(category category); void remove(category category); }
Datenzugriff: Implementierung public class CategoryDaoJpaImpl implements CategoryDao { @PersistenceContext private EntityManager em; public List<Category> findall() { return em.createquery( "select c from Category c order by c.name").getresultlist(); } public void persist(category category) { entitymanager.persist(category); }...
Services implementieren public class InventoryServiceImpl implements InventoryService { @Resource private CategoryDao categorydao; @Resource private ItemDao itemdao; @Transactional public void addnewcategory(category category) { categorydao.persist(category); } @Transactional public void addnewitem(item item) { itemdao.persist(item); }...
Übersicht
JPA bietet standardisiertes Programmiermodell für ORM EclipseLink ist JPA Provider und mehr Greift auf > 10 Jahre Praxis mit ORM zurück Erweiterungen dehnen Grenzen für ORM-Einsatz aus Spring bietet managed JPA Environment Unterstützt EclipseLink als Provider
Vielen Dank für Ihre Aufmerksamkeit! Kontakt: stefan.scheidt@opitz-consulting.de