GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing en.wikibooks.org — Java Persistence/Advanced Topics - Wikibooks, open books for an open world Advanced TopicsEventsAn event is a hook into a system that allows the execution of some code when the event occurs. Events can be used to extend, integrate, debug, audit or monitor a system. JPA defines several events for the persistent life-cycle of JPA defines the following events:
Example of Entity event annotations@Entity public class Employee { @Id private String uid; @Basic private Calendar lastUpdated; ... @PrePersist public void prePersist() { this.uid = UIDGenerator.newUUI(); this.lastUpdated = Calendar.getInstance(); } @PreUpdate public void preUpdate() { this.lastUpdated = Calendar.getInstance(); } } Example of EntityListener event annotations@Entity @EntityListeners(EmployeeEventListener.class) public class Employee { @Id private String uid; @Basic private Calendar lastUpdated; ... }
public class EmployeeEventListener { @PrePersist public void prePersist(Object object) { Employee employee = (Employee)object; employee.setUID(UIDGenerator.newUUI()); employee.setLastUpdated(Calendar.getInstance()); } @PreUpdate public void preUpdate(Object object) { Employee employee = (Employee)object; employee.setLastUpdated(Calendar.getInstance()); } } Example of Entity event xml<entity name="Employee" class="org.acme.Employee" access="FIELD"> <pre-persist method-name="prePersist"/> <pre-update method-name="preUpdate"/> <attributes> <id name="uid"/> </attributes> </entity> Example of EntityListener event xml<entity name="Employee" class="org.acme.Employee" access="FIELD"> <entity-listeners> <entity-listener class="org.acme.EmployeeEventListener"> <pre-persist method-name="prePersist"/> <pre-update method-name="preUpdate"/> </entity-listener> </entity-listeners> <attributes> <id name="uid"/> </attributes> </entity> Default Entity ListenersIt is also possible to configure a default Entity listener. This listener will receive events for all of the Entity classes in the persistence unit. Default listeners can only be defined through XML. If a default Entity listener is defined, and a class wants to define its own listener, or does not want the default listener, this can be disabled using the Example default Entity listener xml<?xml version="1.0" encoding="UTF-8"?> <entity-mappings version="2.0" xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"> <persistence-unit-metadata> <persistence-unit-defaults> <entity-listeners> <entity-listener class="org.acme.ACMEEventListener"> <pre-persist method-name="prePersist"/> <pre-update method-name="preUpdate"/> </entity-listener> </entity-listeners> </persistence-unit-defaults> </persistence-unit-metadata> </entity-mappings> Events and InheritanceEntity listeners are inherited. If a subclass does not wish to inherit a superclass Entity listener, then it must define the Events and EmbeddablesJPA does not define any events for Extended EventsThe JPA events are only defined for the Entity life-cycle. There are no EntityMangager events, or system level events. Some JPA providers may provide additional events.
ViewsA database In JPA you can map to a Views can often be used in JPA to work around mapping limitations. For example if a table join is not supported by JPA, or a database function is desired to be called to transform data, this can normally be done inside a view, so JPA can just map to the simplified data. Using views does require database expertise, and the definition of views can be database dependent. InterfacesInterfaces can be used for two main purposes in a model. The first is as a public interface that defines the public API for the class. The second is as a common type that allows multiple distinct implementers. Public InterfacesIf you have a public interface in JPA, you just need to map the implementation class and are fine for the most part.
One issue is that you need to use the implementation class for queries, as JPA does not know about the interface.
For JPQL the default alias is also the implementation class, but you could redefine this to be the public interface by setting the Some JPA providers allow interfaces to be defined.
Example public interface alias@Entity(name="Employee") public class EmployeeImpl implements Employee { ... } If you have a relationship that uses the public interface, instead of the implementation, then JPA will not know how to map this correctly. You can using the Example public interface relationship@Entity(name="Employee") public class EmployeeImpl implements Employee { @ManyToOne(targetEntity=EmployeeImpl.class) private Employee manager; } Interface TypesIf you have a common interfaces with multiple distinct implementers, this can have some issues.
If you use the interface to define a variable relationship, then this is difficult to map.
JPA has no direct support for interfaces or variable relationships. You could change the interface to be a Some JPA providers have support for mapping interfaces, and for variable relationships.
Stored ProceduresA stored procedure is a procedure or function that resides on the database. Stored procedures are typically written in some database specific language that is similar to SQL, such as PL/SQL on Oracle. Some databases such as Oracle also support stored procedures written in Java. Stored procedures can be useful to perform batch data processing tasks. By writing the task in the database, it avoids the cost of sending the data to and from the database client, so can operate much more efficiently. Stored procedures can also be used to access database specific functionality that can only be accessed on the server. Stored procedures can also be used if strict security requirements as required, to avoid giving users access to the raw tables or unverified SQL operations. Some legacy application have also been written in database procedural languages, and need to be integrated with. The disadvantages of using stored procedures is they are less flexible than using SQL, and require developing and maintaining functionality that is often written in a different language than the application developers may be used to, and difficult to develop and debug, and typically using a limited procedural programming language. There is also a general misconception that using stored procedures will improve performance, in that if you put the same SQL the application is executing inside a stored procedure it will somehow become faster. This is a false, and normally the opposite is true, as stored procedures restrict the dynamic ability of the persistence layer to optimize data retrieval. Stored procedures only improve performance when they use more optimal SQL than the application, typically when they perform an entire task on the database. To achieve optimal performance from SQL generated in an application you must use prepared statements - otherwise the database will have to create a new execution plan each time you submit a query. JPA 2.1 StoredProcedureQueryJPA 2.1 supports calling database stored procedures using the
Some databases such as MySQL, SQL Server and Sybase support stored procedure that return result sets. Some databases such as Oracle do not, but do support output parameters that return cursors.
If the stored procedure returns a result set, or a cursor output parameter, The stored procedure parameters are defined through the Example named stored procedure annotation// This stored procedure returns a result set and has one input parameter. @NamedStoredProcedureQuery( name = "ReadAddressById", resultClasses = Address.class, procedureName = "READ_ADDRESS", parameters = { @StoredProcedureParameter(mode=javax.persistence.ParameterMode.IN, name="P_ADDRESS_ID", type=Long.class) } ) @Entity public class Address { ... } Example calling a named stored procedureStoredProcedureQuery query = em.createNamedStoredProcedureQuery("ReadAddressById"); query.setParameter("P_ADDRESS_ID", 12345); List<Address> result = query.getResultList(); Example named cursored stored procedure annotation// This stored procedure returns a cursor output parameter, and has one input parameter. @NamedStoredProcedureQuery( name = "ReadAddressById", resultClasses = Address.class, procedureName = "READ_ADDRESS", parameters = { @StoredProcedureParameter(mode=IN, name="P_ADDRESS_ID", type=Long.class), @StoredProcedureParameter(mode=REF_CURSOR, name="CUR_ADDRESS", type=void.class) } ) @Entity public class Address { ... } Example calling a named stored procedure with a cursor output parameterStoredProcedureQuery query = em.createNamedStoredProcedureQuery("ReadAddressById"); query.setParameter("P_ADDRESS_ID", 12345); query.execute(); List<Address> result = (List<Address>)query.getOutputParameterValue("CUR_ADDRESS"); Example calling a dynamic stored procedureStoredProcedureQuery query = em.createStoredProcedureQuery("VALIDATE_ADDRESS"); query.registerStoredProcedureParameter("P_COUNTRY", String.class, ParameterMode.IN); query.registerStoredProcedureParameter("P_PROVINCE", String.class, ParameterMode.IN); query.registerStoredProcedureParameter("P_CITY", String.class, ParameterMode.IN); query.registerStoredProcedureParameter("P_STREET", String.class, ParameterMode.IN); query.registerStoredProcedureParameter("P_POSTAL_CD", String.class, ParameterMode.IN); query.registerStoredProcedureParameter("OUT_VALID", Boolean.class, ParameterMode.OUT); query.registerStoredProcedureParameter("OUT_ID", Long.class, ParameterMode.OUT); query.setParameter("P_COUNTRY", "Canada"); query.setParameter("P_PROVINCE", "ON"); query.setParameter("P_CITY", "Ottawa"); query.setParameter("P_STREET", "99 Bank"); query.setParameter("P_POSTAL_CD", "K2H8L2"); query.execute(); Boolean isValid = (Boolean)query.getOutputParameterValue("OUT_VALID"); Long id = (Long)query.getOutputParameterValue("OUT_ID"); Stored Procedures in JPA 2.0JPA 2.0 does not have any direct support for stored procedures. Some types of stored procedures can be executed in JPA through using native queries. Native queries in JPA allow any SQL that returns nothing, or returns a database result set to be executed. The syntax to execute a stored procedure depends on the database. JPA native SQL queries do not support stored procedures that use Some JPA providers have extended support for stored procedures, some also support overriding any CRUD operation for an
Example executing a stored procedure on OracleEntityManager em = getEntityManager(); Query query = em.createNativeQuery("BEGIN VALIDATE_EMP(P_EMP_ID=>?); END;"); query.setParameter(1, empId); query.executeUpdate(); PL/SQL Stored ProceduresIn Oracle stored procedures are typically written in Oracle's PL/SQL language. PL/SQL in Oracle supports some additional data-types, that Oracle does not support through SQL or JDBC. These include types such as
Structured Object-Relational Data TypesAt the peak of object-oriented databases (OODBMS) many of the relational database vendors decided to add object-oriented concepts to relational data. These new hybrid databases were then called Object-Relational in that they could store both object and relational data. These object-relational data-types were standardized as part of SQL3 and support was added for them from Java in the JDBC 2.0 API. Although there was lots of hype around the new forms of data, object-relational data never caught on much, as people seemed to prefer their standard relational data. One would not normally recommend the use of object-relational data, as relational data is much more standard, but if dealing with really complex data, it may be something to investigate. Some common object-relational database features include:
Databases that support object-relational data include:
The basic model allows you to define Structs or Object-types to represent your data, the structures can have nested structures, arrays of basic data or other structures, and refs to other structures. You can then store a structure in a normal relational table column, or create a special table to store the structures directly. Querying is basic SQL, with a few extensions to handle traversing the special types. JPA does not support object-relational data-types, but some JPA providers may offer some support.
See also, XML Data TypesWith the advent of XML databases, many relational database decided to add enhanced XML support. Although it was always possible to store XML in a relational database just using a Databases with XML support include:
JPA has no extended support for XML data, although it is possible to store an XML String into the database, just mapped as a If you wish to map the XML data into objects, you could make use of the JAXB specification. You may even be able to integrate this with your JPA objects.
FiltersSome times it is desirable to filter some of the contents of a table from all queries. This is normally because the table is shared, either by multiple types, applications, tenants, or districts, and the JPA application is only interested in a subset of the rows. It may also be that the table includes historical or archive rows that should be ignored by the JPA application. JPA does not provide any specific support for filtering data, but there are some options available. Inheritance can be used to include a type check on the rows for a class. For example, if you had a These solutions do not work with dynamic filtering, where the filter criteria parameters are not known until runtime (such as tenant, or district). Also complex criteria cannot be modeled through inheritance, although database views should still work. One solution is to always append the criteria to any query, such as appending a JPQL string, or JPA Criteria in the application code. Virtual Private Database (VPD) support may also provide a solution. Some databases such as Oracle support VPD, allow context based filtering of rows based on the connected user or proxy certificate. Some JPA providers have specific support for filtering data.
HistoryA common desire in database applications is to maintain a record and history of the database changes. This can be used for tracking and auditing purposes, or to allow undoing of changes, or to keep a record of the system's data over time. Many database have auditing functionality that allows some level of tracking changes made to the data. Some databases such as Oracle's Flashback feature allow the automatic tracking of history at the row level, and even allow querying on past versions of the data. It is also possible for an application to maintain its own history through its data model. All that is required is to add a History can also be used to avoid deletion. Instead of deleting a row, the The history data could either be stored in-place in the altered table, or the table could be left to only contain the current version of the data, and a mirror history table could be added to store the data. In the mirror case, database triggers could be used to write to the history table. For the in-place case a database view could be used to give a view of the table as of the current time. To query the current data from a history table, any query must include the clause where the JPA does not define any specific history support. Oracle flashback can be used with JPA, but any queries for historical data will need to use native SQL. If a mirror history table is used with triggers, JPA can still be used to query to current data. A subclass or sibling class could also be mapped to the history table to allow querying of history data. If a database view is used, the JPA could be used by mapping the If a history table is used JPA could still be used to map to the table, and a Some JPA providers have support for history.
Logical DeletesAuditingSee, Auditing and Security. ReplicationData replication can be used to backup data, for fault tolerance and fail-over, or for load balancing and scaling the database. For replication, changes are written to multiple databases, either by the application, JPA provider, or database back-end. For fail-over, if one of the databases goes down, the other can be used without loss of data or application downtime. For load-balancing, read requests can be load balanced across the replicated databases to reduce the load on each database, and improve the scalability of the application. Most enterprise database support some form of automatic backup or replication. Clustered database such as Oracle RAC also allow for load balancing, fail-over and high availability. If your database supports replication or clustering, then it is normally transparent to JPA. A specialize DataSource (such as Oracle UCP, or WebLogic GridLink) may need to be used to handle load-balancing and fail-over. JPA does not define any specific support for data replication, but some JPA provider provide replication support. If your database does not support replication, you can implement it yourself through having multiple persistence units, and persisting and merging your objects to both databases.
PartitioningData partitioning can be used to scale an application across multiple database machines, or with a clustered database such as Oracle RAC. Partitioning splits your data across each of the database nodes. There is horizontal partitioning, and vertical partitioning. Vertical partitioning is normally the easiest to implement. You can just put half of your classes on one database, and the other half on another. Ideally the two sets would be isolated from each other and not have any cross database relationships. This can be done directly in JPA, by having two different persistence units, one for each database. For horizontal partitioning you need to split your data across multiple database nodes. Each database node will have the same tables, but each node's table will only store part of the data. You can partition the data by the data values, such as range partitioning, value partitioning, hash partitioning, or even round robin. JPA does not define any data partitioning support, so you either need to define a different class per partition, or use JPA vendor specific functionality.
See also, Data IntegrationNoSQL (and EIS, legacy, XML, and non-relational data)See, NoSQL Multi-TenancyDynamic Data |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |