public interface JpaIntegration
beanClassName
to the fully
qualified class name of the
JPA entity. For example:
<DataSource ID="countryDS" serverType="jpa" beanClassName="com.smartgwt.sample.showcase.server.jpa.Country" > <fields> <!-- ... Fields definition ... --> </fields> </DataSource>
DataSource.autoDeriveSchema
is supported for deriving DataSource fields from JPA
entities automatically (except with JPA 1.0; see below).
Full support is provided for executing simple Criteria
, with
AdvancedCriteria
supported if you have Power Edition or above. However, note that there are limitations with
case
sensitive search in MySQL since MySQL automatically uses the 'like' operator in a
case-insensitive manner and JPA does not correct this. See MySQL Reference Manual
:: C.5.5.1 Case Sensitivity in String Searches for more information.
If create a custom DataSource based on the built-in JPA functionality, subclass
com.isomorphic.jpa.JPA2DataSource
.
In case of "pre-existing beans" approach, see com.smartgwt.client.docs.HbBeans
for the
information how incoming
DSRequest data is used and what to expect in DSResponse.
For JPA integration where Java beans have been explicitly declared,
JPADataSource supports automatic handling of JPA relations that don't declare a
concrete field to hold ID values - see JpaHibernateRelations
.
JPA configuration should be specified in the persistence.xml
file as usual, and
placed
in the /WEB-INF/classes/META-INF
directory. For JPA 2.0 make sure you correctly
declare its usage in persistence.xml
:
<persistence version="2.0" 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" > ... </persistence>
JPADataSource supports operations with composite primary keys. Setting data source level
property
idClassName
to fully qualified
class name indicates,
that entity uses composite primary key.
JPADataSource supports automatic handling of JPA relations that don't declare a concrete
field to hold ID values - see JpaHibernateRelations
.
To use JPA 1.0, set serverType="jpa1" instead. JPA 1.0 does not support
DataSource.autoDeriveSchema
. For JPA 1.0, the concrete implementation class (for subclassing
to
create a custom DataSource) is com.isomorphic.jpa.JPADataSource
.
JPA provides three mechanisms for transactions: for JEE applications JPA provides integration
with JTA (Bean Managed Transactions and Container Managed Transactions); for JSE applications
JPA has a native
EntityTransaction
implementation (Locally Managed Transactions). Spring framework
is another popular
way for declaring transactions in application.
The transaction mechanism should be configured in the server.properties
file by setting
property jpa.emfProvider
to the fully qualified class name of the provider
(implementation of com.isomorphic.jpa.EMFProviderInterface
). Smart GWT comes
with five implementations:
com.isomorphic.jpa.EMFProviderLMT
- for Locally Managed Transactions.
Every fetch or DML operation starts a new transaction and commits after successful
execution.jpa.persistenceUnitName
property from
the server.properties
file. The value of
this property needs
to be set to
the name of the persistence unit configured in persistence.xml
file. For
example:jpa.persistenceUnitName: PERSISTENCE_UNIT_NAME
com.isomorphic.jpa.EMFProviderBMT
- for Bean Managed Transactions.
Every fetch or DML operation acquires the transaction object from the container and starts
it.server.properties
file:
jpa.entityManager
and jpa.entityManagerFactory
containing appropriate resource name references configured in
/WEB-INF/web.xml
. Configuration example:<!-- EntityManager resource reference name declaration --> <persistence-context-ref> <persistence-context-ref-name>persistence/em</persistence-context-ref-name> <persistence-unit-name>PERSISTENCE_UNIT_NAME</persistence-unit-name> </persistence-context-ref> <!-- EntityManagerFactory resource reference name declaration --> <persistence-unit-ref> <persistence-unit-ref-name>persistence/emf</persistence-unit-ref-name> <persistence-unit-name>PERSISTENCE_UNIT_NAME</persistence-unit-name> </persistence-unit-ref> #Property values for sample references: jpa.entityManager: persistence/em jpa.entityManagerFactory: persistence/emf
com.isomorphic.jpa.EMFProviderCMT
- for Container Managed Transactions.
Every fetch or DML operation acquires the transaction object from the JEE container.
After successful method execution the container commits the transaction. In case of execution
failure tx.setRollbackOnly()
is used to notify container to rollback the
transaction.server.properties
file:
jpa.entityManager
and jpa.entityManagerFactory
containing appropriate resource name references configured in
/META-INF/ejb-jar.xml
. Configuration example:<?xml version="1.0" encoding="UTF-8"?> <ejb-jar version = "3.0" xmlns = "http://java.sun.com/xml/ns/javaee" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"> <enterprise-beans> <session> <ejb-name>TestEJB</ejb-name> <persistence-context-ref> <persistence-context-ref-name>persistence/em</persistence-context-ref-name> <persistence-unit-name>PERSISTENCE_UNIT_NAME</persistence-unit-name> </persistence-context-ref> <persistence-unit-ref> <persistence-unit-ref-name>persistence/emf</persistence-unit-ref-name> <persistence-unit-name>PERSISTENCE_UNIT_NAME</persistence-unit-name> </persistence-unit-ref> </session> </enterprise-beans> </ejb-jar> #Property values for sample references: jpa.entityManager: persistence/em jpa.entityManagerFactory: persistence/emf
com.isomorphic.jpa.EMFProviderNoTransactions
- transactions are
not used.server.properties
file this
implementation reads the
jpa.persistenceUnitName
property which must containt the name of
persistence unit
configured in persistence.xml
file. For example:jpa.persistenceUnitName: PERSISTENCE_UNIT_NAME
com.isomorphic.jpa.EMFProviderSpring
- for Spring Framework managed
Transactions.
Every fetch or DML operation acquires the transaction object from the Spring Application
Context.server.properties
file:
jpa.entityManagerFactory
and jpa.transaction
containing appropriate bean names configured in Spring Application Context.
You have to declare additional bean in your Spring Application Context to allow Smart GWT
to acquire reference to context.
Configuration example:<!-- SpringApplicationContextProvider bean definition required to get access to application context. --> <bean id="springApplicationContextProvider" class="com.isomorphic.spring.SpringApplicationContextProvider" /> <!-- Connection to data base --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" p:driverClassName="DRIVER_CLASS" p:url="CONNECTION_URL" p:username="DB_USER_NAME" p:password="DB_USER_PASSWORD" /> <!-- Reference to JPA EntityManagerFactory --> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="database" value="DB_TYPE" /> </bean> </property> <property name="persistenceUnitName" value="PERSISTENCE_UNIT_NAME" /> </bean> <!-- Reference to JpaTransactionManager --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> #Property values for sample bean names: jpa.entityManagerFactory: entityManagerFactory jpa.transaction: transactionManager
jpa.emfProvider
to your own implementation of
com.isomorphic.jpa.EMFProviderInterface
if you have specific requirements for
transaction handling. EMF
will instantiate provided implementation on
initialization (static) and
will use same instance every time. By using own implementation you can have complete control
over creating/using
EntityManagerFactory
and EntityManager
instances.
Additional configurations:
In case you have several persistence units defined in your persistence.xml
you can
have additional
configurations in server.properties
file.
Additional configurations
(prefixed with jpa.
) should have name, emfProvider
property and other
properties required by specified EMF provider implementation.
For example:jpa.configName.emfProvider: com.isomorphic.jpa.EMFProviderLMT jpa.configName.persistenceUnitName: ANOTHER_PERSISTENCE_UNIT_NAMETo use additional JPA configuration you have to set
jpaConfig
property in
data source
definition:<DataSource ID="countryDS" serverType="jpa" beanClassName="com.smartgwt.sample.showcase.server.jpa.Country" jpaConfig="configName" >Transaction management:
RPCManager
(DSRequest
has reference to
RPCManager
):RPCManager
(if available);RPCManager
);DSRequest.registerCallback()
for onSuccess()
/
onFailure()
execution to commit/roll back transaction;DSRequest.setFreeOnExecute()
to false
to postpone releasing
of EntityManager
avoiding lazy loading exceptions when creating JS response and
traversing through persistent object tree;RPCManager.registerFreeResourcesHandler()
for
freeResources()
execution to release EntityManager
.EntityManager
and transaction in your custom data source
implementation you can
acquire it by JPAConnectionHolder holder = DataSource.getTransactionObject(req, EMF.TRANSACTION_ATTR);
JPAConnectionHolder
instance contains references to entity manager and transaction
object
used by JPADataSource
. You should never commit/rollback automatic transaction.
Overall commit/rollback will be issued by RPCManager
and will be handled by
JPADataSource
object which started transaction.
RPCManager
:EntityManager
if
DSRequest.setFreeOnExecute()
is set to true
(defalut);onSuccess()
/onFailure()
to
commit/roll back
transaction and to call freeResources()
to release
EntityManager
.DSRequest req = new DSRequest("myDS", "fetch"); req.setFreeOnExecute(false); DSResponse resp = req.execute(); List dataList = resp.getDataList(); //... traverse through persistent object tree // Commit current transaction. ((JPADataSource) r.getDataSource()).onSuccess(); // Release entity manager. ((JPADataSource) r.getDataSource()).freeResources(req);
For fields with numeric types, the record
data
in DSRequests will automatically
be converted to the type of the target field, before the request is received in a DMI. For
details, see DsRequestBeanTypes
.
In some cases you may not be able to immediately use the built-in JPADataSource - in
this case take a look at manual Hibernate
integration
.
SqlConnectionPooling