TIPS & TECHNIQUES FOR USING ECLIPSE DALI … & TECHNIQUES FOR USING ECLIPSE DALI ... • For Eclipse...
Transcript of TIPS & TECHNIQUES FOR USING ECLIPSE DALI … & TECHNIQUES FOR USING ECLIPSE DALI ... • For Eclipse...
TIPS & TECHNIQUES FOR USING ECLIPSE DALI TOOLS
TO DEPLOY JPA/JEE APPS ANYWHERE!
March 27, 2012
Ali Manji – Software Analyst, IBM
email: [email protected]
twitter: @torontoIBMer
What should we talk about?
Using Eclipse with the Dali Persistence Tools, lets look at techniques to:
1. develop enterprise-grade applications that are either:
a. built from the bottom-up with a pre-existing database
b. built from the top-down starting with business domain entities requiring persistence
storage (e.g. Derby, MySQL, and DB2, Google Big Data)
2. incorporate a JPA approach into your existing JEE architecture
3. minimize data-impedance mismatch issues
2
Development Environment (1 of 2)
IDE Version
Eclipse 3.6 – Helios
3.7 SR 2 – Indigo
IBM Rational Application Developer 8.0.4 (based upon Eclipse 3.6.x)
• For Eclipse environment use the “Eclipse IDE for Java EE Developers”
bundle.
• This bundle contains the Web Tools Project which inclused the Dali JPA project
and the EJB tools project among others
Note: Used JDK or JRE 1.7 for projects and server environments (unless provided by the IDE or
Application Server)
4
Development Environment (2 of 2)
Plugins / Features Version
Google Plugin For Eclipse 2.5.2 (for Eclipse 3.7)
Oracle Glassfish Server Tools 2.0.0 – Download from “New Server” wizard
JBossAS Tools 2.3.0 – Download from “New Server” wizard
5
Caution: Building on a stack…always a work in progress
6
“The road to success is always under construction.” – Lily Tomlin
Source: http://www.flickr.com/photos/tmray02/4639274135, Tom Ray
JEE Deployment Topologies
Derby MySQL DB2
GlassFish Server Open Source Edition Y Y Y
WebSphere Application Server (1) Y Y Y
Google App Engine N/A N/A N/A
JBoss Y Y Y
* (1) Used IBM Rational development environment – Rational Application Developer
to exploit OOTB server tooling add-ons and other productivity conveniences for
WebSphere Application Server v8 test/deployment
7
Application Servers
Application Server Version
GlassFish Server Open Source Edition (See Note 1) 3.1.2 (JEE6)
WebSphere Application Server 8.0.0.2
JBoss (See Note 2) 7.1
Google App Engine (uses Jetty) 1.6.3
8
Note 1:
• Made use of EclipseLink 2.3.2 (for Indigo) JPA Platform / User Library implementation
donated by Oracle (TopLink)
Note 2:
• Makes use of Hibernate JPA implementation
Data stores
Database / Data store Version
Derby 10.8.2.2
MySQL Community Server
Connector J (JBDC Driver)
5.5.21
5.1.18
DB2 Enterprise Server Edition 9.7 (on Red Hat Linux)
Google Big Table 1.6.3
9
What should we talk about?
Using Eclipse with the Dali Persistence Tools, lets look at techniques to:
1. develop enterprise-grade applications that are either:
a. built from the bottom-up with pre-existing database
b. built from the top-down starting with business domain entities requiring persistence
storage (e.g. Derby, MySQL, and DB2, Google Big Data)
2. incorporate a JPA approach into your existing JEE architecture
3. minimize data-impedance mismatch issues
10
“Bottom-up” JPA Tips / Techniques (1 of 4)
11
1. Limit navigability of relationships (tighter encapsulation / data hiding).
PrimaryMember has a bi-directional relationship with Address
PrimaryMember has an address (good!)
Address has a collection of Primarymembers (not so good!)
“Bottom-up” JPA Tips / Techniques (2 of 4)
12
1. Limit navigability of relationships (tighter encapsulation / data hiding).
“Bottom-up” JPA Tips / Techniques (3 of 4)
13
2. “Clean-up” generated code to reflect true 1-1 aggregate relationships.
• Most/many DBs do NOT support 1-1 relationships for performance reasons, BUT
• Simple aggregate relationships are COMMON in Java-based domain
models/designs
• This is an example of where the data-impedance mismatch problem
manifests itself between the 2 different “world-views” (i.e. relational tables
vs. objects as real-world abstractions)
After:
Before:
“Bottom-up” JPA Tips / Techniques (4 of 4)
14
3. Adjust generated code to reflect rich Java types that can be mapped from
less rich primitives or other types as introspected from the DBs
• You have options. e.g. Date, Timestamp, Calendar, etc.
What should we talk about?
Using Eclipse with the Dali Persistence Tools, lets look at techniques to:
1. develop enterprise-grade applications that are either:
a. built from the bottom-up with pre-existing database
b. built from the top-down starting with business domain entities requiring
persistence storage (e.g. Derby, MySQL, and DB2, Google Big Data)
2. incorporate a JPA approach into your existing JEE architecture
3. minimize data-impedance mismatch issues
15
Uniqueness
16
“Always remember you're unique, just like everyone else.” – Alison Boulter
Source: http://www.flickr.com/photos/amboo213/5562707049, Amboo
“Top-down” JPA Tips / Techniques
1. Use the data store’s native features to automatically generate values for
your class’s id attributes.
• Value lies in abstracting away the focus of your data store’s requirement for a
unique key value. Application’s business logic is paramount
17
SQL for Unique ID generation
For MySQL
CREATE TABLE BANK.Customer (clientID INTEGER NOT NULL AUTO_INCREMENT, firstName
VARCHAR(255), lastName VARCHAR(255), yearOfBirth INTEGER, PRIMARY KEY (clientID))
ENGINE = innodb;
For DB2 / Derby:
CREATE TABLE NULLID.CUSTOMER (
CLIENTID INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH +0,
INCREMENT BY +1),
FIRSTNAME VARCHAR(254), LASTNAME VARCHAR(254), YEAROFBIRTH INTEGER, PRIMARY
KEY (clientid));
18
What should we talk about?
Using Eclipse with the Dali Persistence Tools, lets look at techniques to:
1. develop enterprise-grade applications that are either:
a. built from the bottom-up with pre-existing database
b. built from the top-down starting with business domain entities requiring persistence
storage (e.g. Derby, MySQL, and DB2, Google Big Data)
2. incorporate a JPA approach into your existing JEE architecture
3. minimize data-impedance mismatch issues
19
Incorporating JPA into existing JEE Architecture
1. JPA is annotation and Resource Injection (RI) friendly, use them wherever possible
• Eliminate messy JNDI code for resource declarations, lookup, and initialization
NOTE: Only works with complete & compliant JEE Application Servers
• E.g. Google App Engine not a complete JEE container.. (Reference over
here)
2. Use JPA with your AppServer’s Transaction Management support wherever possible
(container management / connection pooling).
3. Continue good practice common to wrapper JPA bean in front of a session bean (to
secure container management services)
• In JEE 6, possible to use as JPA beans as a “managed bean” for direct access in
JSF pages (and facelets).
20
What should we talk about?
Using Eclipse with the Dali Persistence Tools, lets look at techniques to:
1. develop enterprise-grade applications that are either:
a. built from the bottom-up with pre-existing database
b. built from the top-down starting with business domain entities requiring persistence
storage (e.g. Derby, MySQL, and DB2, Google Big Data)
2. incorporate a JPA approach into your existing JEE architecture
3. minimize data-impedance mismatch issues
21
Questions
22
Thank You
Ali Manji – Software Developer, IBM
email: [email protected]
twitter: @torontoIBMer
Tips & Techniques for using Eclipse Dali Tools to deploy JPA/JEE
Apps anywhere!
Adding Server Adapters to your Eclipse Development
Environment (3 of 3)
Question: Why use a Server adapter?
Answer: Fabulous productivity enhancer, for test, debug, deploy roundtrip cycle
Eliminate or minimize need to:
1. To leave your Eclipse environment to test/debug your application
2. To understand the AppServer’s deployment process, file structure, configuration
– development abstraction
3. Cycle of zipping up jars, wars, ears and copying over and restarting application
or entire server
With most server adapters the following steps in the below cycle are automatic:
1. Detection of changes to application
2. Re-published
3. Applications are restarted
27
Key steps/considerations for Google App Engine (GAE) – 1 of 2
1. GAE runtime needs JDK using JRE not sufficient.
2. Google has its own Web Project that you have to use and it is different from Java EE
> Dynamic Web Project
3. Using Oracle’s JDK requires use of the JVM argument: -XX:-UseSplitVerifier
4. GAE does not have support for many JPA annotations, notably these:
@PersistenceContext EntityManager em;
@Resource private UserTransaction utx;
Have to use programmatic alternative instead:
EntityManager em = EMF.get().createEntityManager();
…..
EntityTransaction utx = em.getTransaction();
31
Key steps/considerations for Google App Engine (GAE) – 2 of 2
1. JEE 6 Annotations also not available yet for Web Containers: Can’t use this annotation yet: @WebServlet("/CreateCustomerServlet")
2. GAE/DataNucleus has some specific limitations on types that you can use to
represent the ID/Primary key field. You can’t use private int clientID; More details
here.
3. In addition to these annotations required by JPA
@Id
@GeneratedValue(strategy = IDENTITY)
MUST ALSO USE
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
32
Google App Engine – persistence.xml
<?xml version="1.0" encoding="UTF-8" ?>
<persistence 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_1_0.xsd" version="1.0">
<persistence-unit name="transactions-optional">
<provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider>
<class>org.acme.membership.domain.Membership</class>
<properties>
<property name="datanucleus.NontransactionalRead" value="true"/>
<property name="datanucleus.NontransactionalWrite" value="true"/>
<property name="datanucleus.ConnectionURL" value="appengine"/>
</properties>
</persistence-unit>
</persistence>
34
JDO with Google App Engine
http://www.ibm.com/developerworks/rational/library/building
-java-data-objects-application-using-rational-software-
architect-and-google-application-engine/index.html
35
Key steps/considerations for Glassfish
1. GlassFish runtime needs JDK using JRE not sufficient
2. Download EclipseLink to use along with Glassfish
3. Create (proprietary) file glassfish-resources.xml in the EAR’s meta-inf directory
(http://javahowto.blogspot.com/2011/02/glassfish-embedded-jpa-ejb-datasource.html)
4. Copy JBDC drivers from vendor to: X:\glassfish3\glassfish\lib • (except Derby)
36
Glassfish with Derby: persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
…..
<jta-data-source>java:app/jdbc/BANK</jta-data-source>
<class>org.acme.bank.domain.Customer</class>
<properties>
<property name="eclipselink.target-database" value="Derby" />
</properties>
</persistence-unit>
</persistence>
37
Glassfish with Derby: glassfish-resources.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd"> <resources> <jdbc-connection-pool name="derbyGF_CustomerPool" res-type="javax.sql.DataSource" datasource classname="org.apache.derby.jdbc.ClientDataSource40" pool-resize-quantity="1" max-pool-size="5" steady-pool-size="0" statement-timeout-in-seconds="60"> <property name="serverName" value="localhost" /> <property name="portNumber" value="1527" /> <property name="dataBaseName" value="D:\DERBY_DBS\BANK" /> <property name="connectionAttributes" value=";create=true" /> <property name="driverType" value="4" /> <property name="user" value=“USER" /> <property name="password" value=“PASSWORD" /> </jdbc-connection-pool> <jdbc-resource enabled="true" jndi-name="jdbc/BANK" object-type="user" pool-name="derbyGF_CustomerPool" /> </resources>
38
GlassFish with MySQL: persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<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-unit name="BankAppWeb">
<jta-data-source>java:app/jdbc/BANK</jta-data-source>
<class>org.acme.bank.domain.Customer</class>
<properties>
<property name="eclipselink.target-database" value="MySQL4" />
</properties>
</persistence-unit>
</persistence>
39
Glassfish with MySQL: glassfish-resources.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN"
"http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-connection-pool name=“mySQLGF_CustomerPool"
res-type="javax.sql.DataSource" datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"
pool-resize-quantity="1" max-pool-size="5" steady-pool-size="0"
statement-timeout-in-seconds="60">
<property name="serverName" value="localhost" />
<property name="portNumber" value="3306" />
<property name="dataBaseName" value="BANK" />
<property name="connectionAttributes" value=";create=true" />
<property name="driverType" value="4" />
<property name="user" value="root" />
<property name="password" value=“PASSWORD" />
</jdbc-connection-pool>
<jdbc-resource enabled="true" jndi-name="jdbc/BANK"
object-type="user" pool-name=“mySQLGF_CustomerPool" />
</resources>
40
Key steps/considerations for Glassfish with DB2
With GlassFish additionally requires specifying DB2’s schema value – even if you use the default
schema value for the database (e.g. NULLID).
Solution from Neil Hague:
The standard JPA solution to setting a default schema for your persistence unit is to configure the schema setting in the persistence-unit-
defaults. This is defined in 1 and only 1 XML Mapping file (orm.xml) as follows:
<entity-mappings ...>
<persistence-unit-metadata>
<persistence-unit-defaults>
<schema>default_schema_name</schema>
</persistence-unit-defaults>
...
</entity-mappings>
Source over here
Alternative solution:
• Explicitly include schema attribute in table annotation for each class:
@Table(schema = "NULLID")
41
Glassfish with DB2: persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<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-unit name="BankAppWeb">
<jta-data-source>java:app/jdbc/BANK</jta-data-source>
<class>org.acme.bank.domain.Customer</class>
<properties>
<property name="eclipselink.target-database" value="DB2" />
</properties>
</persistence-unit>
</persistence>
42
Glassfish with DB2: glassfish-resources.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN"
"http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-connection-pool name="derbyGF_CustomerPool"
res-type="javax.sql.DataSource" datasource-classname="com.ibm.db2.jcc.DB2SimpleDataSource"
pool-resize-quantity="1" max-pool-size="5" steady-pool-size="0"
statement-timeout-in-seconds="60" >
<property name="serverName" value="hasanali.torolab.ibm.com" />
<property name="portNumber" value="50000" />
<property name="databaseName" value="BANK" />
<property name="driverType" value="4" />
<property name="user" value="db2inst1" />
<property name="password" value=“PASSWORD" />
</jdbc-connection-pool>
<jdbc-resource enabled="true" jndi-name="jdbc/BANK"
object-type="user" pool-name="derbyGF_CustomerPool" />
</resources>
43
WebSphere Application Server
With Derby
http://www.ibm.com/developerworks/rational/library/jpa-rational-application-
developer-was-8
With DB2
http://www.ibm.com/developerworks/rational/library/10/create-bottom-up-jpa-
entities-with-rational-application-developer-db2-and-websphere-application-
server/index.html
With MySQL
• No Support for MySQL in WebSphere Application Server
44
Key steps/considerations for JBoss
1. Runtime needs JDK using JRE not sufficient
2. Uses Hibernate JPA implementation
3. Copy Database libraries (JARs) to: JBOSS_HOME\modules\XXXX – where you
create directory XXXX
4. Create (proprietary) file module.xml which goes in directory created created in #2
5. Update (proprietary) standalone.xml to define data source information
45
JBoss with MySQL: module.xml / standalone.xml
module.xml
<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.0" name="com.mysql"> <resources> <resource-root path="mysql-connector-java-5.1.18-bin.jar"/> </resources> <dependencies> <module name="javax.api"/> </dependencies> </module>
Excerpt of standalone.xml
<datasource jta="true" jndi-name="java:/MyBankDB2DS" pool-name="MyBankDB2DS" enabled="true" use-java-context="true" use-ccm="true"> <connection-url>jdbc:db2://hasanali.torolab.ibm.com:50000/MyBank:retrieveMessagesFromServerOnGetMessage=true;</connection-url> <driver>db2jcc</driver> <security> <user-name>db2inst1</user-name> <password>PASSWORD</password> </security> <timeout> <idle-timeout-minutes>0</idle-timeout-minutes> <query-timeout>600</query-timeout> </timeout> </datasource>
46
JBoss persistence.xml
Excerpts of persistence.xml
…
<!-- For use with JBoss & MySQL-->
<jta-data-source>java:/MyBankMySQLDS</jta-data-source>
…
<!-- For use with JBoss -->
<property name="showSql" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
…
47