@@ -8,6 +8,7 @@ It covers the different demos made during the talk and is organised like that:
8
8
* ` jdbc-blueprint ` : Maven project using camel-jdbc component and Blueprint XML DSL
9
9
* ` sql-spring ` : Maven project using camel-sql component and Spring XML DSL
10
10
* ` sql-blueprint ` : Maven project using camel-sql component and Blueprint XML DSL
11
+ * ` jpa-javase ` : Maven project with JUnit tests showing JPA API usage with local and JTA transactions
11
12
12
13
# Initial setup
13
14
@@ -27,22 +28,40 @@ You can use any of available methods to access PostgreSQL server (e.g., by mappi
27
28
28
29
$ docker run -d --name fuse-postgresql-server -e POSTGRES_USER=fuse -e POSTGRES_PASSWORD=fuse -p 5432:5432 postgres:9.6.4
29
30
30
- 2 . Create ` reportdb ` database by from the ` fuse-postgresql-server ` container:
31
+ 2 . Create ` reportdb ` database from the ` fuse-postgresql-server ` container:
31
32
32
33
$ docker exec -ti fuse-postgresql-server /bin/bash
33
- root@3e37b4b579c7 :/# psql -U fuse -d fuse
34
- psql (9.4.0 )
34
+ root@58b0d9de9c5b :/# psql -U fuse -d fuse
35
+ psql (9.6.4 )
35
36
Type "help" for help.
36
37
fuse=# create database reportdb owner fuse encoding 'utf8';
37
38
CREATE DATABASE
38
- fuse=# \q
39
+ fuse=# \c reportdb
40
+ You are now connected to database "reportdb" as user "fuse".
41
+ reportdb=# create schema report;
42
+ CREATE SCHEMA
43
+ reportdb=# \q
44
+
45
+ 3 . Create ` reportdb2 ` database from the ` fuse-postgresql-server ` container (for XA purposes):
46
+
47
+ $ docker exec -ti fuse-postgresql-server /bin/bash
48
+ root@58b0d9de9c5b:/# psql -U fuse -d fuse
49
+ psql (9.6.4)
50
+ Type "help" for help.
51
+ fuse=# create database reportdb2 owner fuse encoding 'utf8';
52
+ CREATE DATABASE
53
+ fuse=# \c reportdb2
54
+ You are now connected to database "reportdb2" as user "fuse".
55
+ reportdb2=# create schema report;
56
+ CREATE SCHEMA
57
+ reportdb2=# \q
39
58
40
- 3 . Initialize database ` reportdb ` by creating schema, table and populating the table with data.
59
+ 4 . Initialize database ` reportdb ` by creating schema, table and populating the table with data.
41
60
42
61
$ cd $PROJECT_HOME/database
43
62
$ docker cp src/config/postgresql/reportdb-postgresql-script.sql fuse-postgresql-server:/tmp
44
63
$ docker exec -ti fuse-postgresql-server /bin/bash
45
- $ root@58b0d9de9c5b:/# psql -U fuse -d reportdb -f /tmp/reportdb-postgresql-script.sql
64
+ root@58b0d9de9c5b:/# psql -U fuse -d reportdb -f /tmp/reportdb-postgresql-script.sql
46
65
...
47
66
DROP SCHEMA
48
67
CREATE SCHEMA
@@ -52,6 +71,13 @@ You can use any of available methods to access PostgreSQL server (e.g., by mappi
52
71
INSERT 0 1
53
72
INSERT 0 1
54
73
74
+ 5 . Configure PostgreSQL database to allow XA transactions by setting ` max_prepared_transactions ` to the value equal
75
+ or greater than ` max_connections ` setting (` 100 ` in the case of ` postgres:9.6.4 ` image).
76
+
77
+ root@58b0d9de9c5b:/# sed -i 's/^#max_prepared_transactions = 0/max_prepared_transactions = 200/' /var/lib/postgresql/data/postgresql.conf
78
+
79
+ 5 . Restart ` fuse-postgresql-server ` container. Your PostgreSQL database is ready to use.
80
+
55
81
# Running examples
56
82
57
83
## ` jdbc-spring ` and ` jdbc-blueprint `
@@ -118,3 +144,88 @@ to be invoked.
118
144
119
145
$ cd $PROJECT_HOME/sql-blueprint
120
146
$ mvn clean package camel:run
147
+
148
+ ## ` jpa-javase `
149
+
150
+ This project should be examined before running ` jpa-spring ` and ` jpa-blueprint ` (and supporting ` jpa-ds ` and ` jpa-model ` ).
151
+ ` jpa-javase ` shows few _ canonical_ ways of using JPA API with Hibernate JPA provider.
152
+ According to JPA 2.0 specification (JSR 317), JPA can successfully be used outside application server - in pure JavaSE
153
+ environment. Using JPA this way is described as _ application-managed Entity Manager_ .
154
+
155
+ In this mode, it's the role of application developer to create ` EntityManagerFactory ` and obtain ` EntityManager ` . (In
156
+ application server, i.e., when using _ container-managed Entity Manager_ , ` EntityManager ` instance is injected to application
157
+ code using ` @javax.persistence.PersistenceContext ` annotation).
158
+
159
+ ` jpa-javase ` provides 3 unit tests that illustrate few uses cases related to JPA:
160
+
161
+ * ` com.fusesource.examples.persistence.part1.DiscoveryTest.discovery() ` : a tiny example of using JPA discover API,
162
+ where we can check what is the configured (discovered) ` javax.persistence.spi.PersistenceProvider ` instance.
163
+ * ` com.fusesource.examples.persistence.part1.JavaSETest.bootstrapAndUseApplicationManagedResourceLocalEntityManager() ` :
164
+ Full example using ` transaction-type="RESOURCE_LOCAL" ` that shows how to:
165
+ * create dbcp2 ` javax.sql.DataSource `
166
+ * use ` javax.persistence.Persistence.createEntityManagerFactory() ` to _ create_ application-managed EMF using provided properties
167
+ * use ` javax.persistence.EntityManagerFactory.createEntityManager() ` to _ obtain_ EntityManager
168
+ * use ` javax.persistence.EntityTransaction ` API to manually demarcate JPA transactions according to declared ` transaction-type="RESOURCE_LOCAL" `
169
+ * use ` javax.persistence.EntityManager.persist() ` to simply use JPA API
170
+ * use plain JDBC code to verify that record was indeed persisted to database
171
+ * ` com.fusesource.examples.persistence.part1.JavaSETest.bootstrapAndUseApplicationManagedJTAEntityManager() ` :
172
+ Full example using ` transaction-type="JTA" ` that shows how to:
173
+ * create fully functional ` javax.transaction.TransactionManager ` /` javax.transaction.UserTransaction ` instances using
174
+ aries.transaction.manager
175
+ * create 2 ` org.postgresql.xa.PGXADataSource ` instances for XA-aware access to PostgreSQL database
176
+ * create 2 ` javax.sql.DataSource ` instances that are using JCA API to interact with aries.jdbc and provide
177
+ XA-aware, JTA-enlisting, pooling data sources
178
+ * use ` javax.persistence.Persistence.createEntityManagerFactory() ` to _ create_ application-managed EMF using provided properties
179
+ * use ` javax.persistence.EntityManagerFactory.createEntityManager() ` to _ obtain_ EntityManager
180
+ * use ` javax.transaction.UserTransaction ` API to manually demarcate JPA transactions according to declared ` transaction-type="JTA" `
181
+ * use ` javax.persistence.EntityManager.joinTransaction() ` to tie JPA to JTA
182
+ * use ` javax.persistence.EntityManager.persist() ` to simply use JPA API
183
+ * use plain JDBC to insert row to 2nd database within the same global JTA transaction
184
+ * use plain JDBC code to verify that record was indeed persisted to both databases
185
+
186
+ ## ` jpa-spring ` and ` jpa-blueprint ` - TODO
187
+
188
+ install -s mvn:org.postgresql/postgresql/42.1.4
189
+ install -s mvn:org.apache.commons/commons-pool2/2.4.2
190
+ install -s mvn:org.apache.commons/commons-dbcp2/2.1.1
191
+ features:install jndi jpa hibernate camel-jpa
192
+ features:install camel-jpa
193
+ features:install transaction connector
194
+ install -s mvn:com.fusesource.examples.camel-persistence-part1/jpa-ds/1.0
195
+
196
+ JBossFuse:karaf@root> ls 317
197
+
198
+ FuseSource :: Examples :: Camel Persistence :: JPA Data Source (317) provides:
199
+ ------------------------------------------------------------------------------
200
+ Bundle-SymbolicName = com.fusesource.examples.camel-persistence-part1.jpa-ds
201
+ Bundle-Version = 1.0.0
202
+ objectClass = [javax.sql.DataSource]
203
+ org.springframework.osgi.bean.name = reportdb
204
+ osgi.jndi.service.name = jdbc/reportdb
205
+ service.id = 659
206
+ ----
207
+ Bundle-SymbolicName = com.fusesource.examples.camel-persistence-part1.jpa-ds
208
+ Bundle-Version = 1.0.0
209
+ objectClass = [org.springframework.osgi.context.DelegatedExecutionOsgiBundleApplicationContext, org.springframework.osgi.context.ConfigurableOsgiBundleApplicationContext, org.springframework.context.ConfigurableApplicationContext, org.springframework.context.ApplicationContext, org.springframework.context.Lifecycle, java.io.Closeable, org.springframework.beans.factory.ListableBeanFactory, org.springframework.beans.factory.HierarchicalBeanFactory, org.springframework.context.MessageSource, org.springframework.context.ApplicationEventPublisher, org.springframework.core.io.support.ResourcePatternResolver, org.springframework.beans.factory.BeanFactory, org.springframework.core.io.ResourceLoader, java.lang.AutoCloseable, org.springframework.beans.factory.DisposableBean]
210
+ org.springframework.context.service.name = com.fusesource.examples.camel-persistence-part1.jpa-ds
211
+ service.id = 660
212
+
213
+ ### Aries JPA internals
214
+
215
+ org.apache.aries.jpa.container bundle:
216
+
217
+ * ` org.apache.aries.jpa.container.parsing.PersistenceDescriptorParser ` service implemented by
218
+ ` org.apache.aries.jpa.container.parsing.impl.PersistenceDescriptorParserImpl ` - parses ` META-INF/persistence.xml `
219
+ descriptors into ` org.apache.aries.jpa.container.parsing.impl.PersistenceUnitImpl ` objects using
220
+ ` org.apache.aries.jpa.container.parsing.impl.JPAHandler `
221
+ * ` org.apache.aries.jpa.container.impl.PersistenceBundleManager ` - locates, parses and manages persistence units
222
+ defined in OSGi bundles. Contains ` Map<Bundle, EntityManagerFactoryManager> `
223
+
224
+ Parsed ` org.apache.aries.jpa.container.parsing.impl.PersistenceUnitImpl ` is changed into
225
+ ` org.apache.aries.jpa.container.unit.impl.ManagedPersistenceUnitInfoImpl ` and ` getPersistenceUnitInfo() ` is called
226
+ to get ` javax.persistence.spi.PersistenceUnitInfo ` instance which is then finally used as argument to
227
+ ` javax.persistence.spi.PersistenceProvider.createContainerEntityManagerFactory() ` .
228
+
229
+ org.apache.aries.jpa.container.context bundle:
230
+
231
+ * provides contextual (proxied, thread-local) access to context-related ` javax.persistence.EntityManager ` instance.
0 commit comments