Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Test and commands for jpa

  • Loading branch information...
commit 239e21573d0a7aaa1392f9d6c9fc13a4b3e2c08f 1 parent 8aa27b7
Christian Schneider authored
View
6 db/command/src/main/java/net/lr/tutorial/karaf/db/service/DbSelect.java
@@ -42,7 +42,11 @@ public void setDbAccess(DbAccess dbAccess) {
public ServiceReference[] getDataSources() {
try {
- return context.getServiceReferences(DataSource.class.getName(), null);
+ ServiceReference[] dsRefs = context.getServiceReferences(DataSource.class.getName(), null);
+ if (dsRefs == null) {
+ dsRefs = new ServiceReference[]{};
+ }
+ return dsRefs;
} catch (InvalidSyntaxException e) {
throw new RuntimeException(e);
}
View
1  db/datasource/datasource-mysql.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
First install the MySQL driver using:
+> install -s mvn:org.apache.servicemix.specs/org.apache.servicemix.specs.stax-api-1.0/1.9.0
> install -s mvn:mysql/mysql-connector-java/5.1.18
Then copy this file to the deploy folder
View
4 db/examplejdbc/derby.log
@@ -1,6 +1,6 @@
----------------------------------------------------------------
-Thu Jan 12 15:52:01 CET 2012:
-Booting Derby version The Apache Software Foundation - Apache Derby - 10.8.2.2 - (1181258): instance a816c00e-0134-d267-6e5a-000006faaef8
+Fri Jan 13 16:55:45 CET 2012:
+Booting Derby version The Apache Software Foundation - Apache Derby - 10.8.2.2 - (1181258): instance a816c00e-0134-d7c8-265c-000006d75cf8
on database directory C:\checkout\Karaf-Tutorial\db\examplejdbc\target\test with class loader sun.misc.Launcher$AppClassLoader@6d6f0472
Loaded from file:/C:/Users/cschneider/.m2/repository/org/apache/derby/derby/10.8.2.2/derby-10.8.2.2.jar
java.vendor=Sun Microsystems Inc.
View
3  db/examplejdbc/src/main/java/net/lr/tutorial/karaf/db/example/DbExample.java
@@ -60,6 +60,9 @@ public void test() throws Exception {
if (stmt != null) {
stmt.close();
}
+ if (con != null) {
+ con.close();
+ }
}
}
View
32 db/examplejpa/ReadMe.txt
@@ -3,6 +3,11 @@ dbexample
Example how to access a DataSource using OSGi services and jdbc.
+Build
+-----
+
+mvn clean install
+
Installation
------------
@@ -11,24 +16,37 @@ First see datasources project REDAME and install the derby db and datasource int
install -s mvn:org.apache.geronimo.specs/geronimo-annotation_1.0_spec/1.1.1
install -s mvn:commons-lang/commons-lang/2.6
install -s mvn:commons-pool/commons-pool/1.5.4
-install -s mvn:commons-dbcp/commons-dbcp/1.4
install -s mvn:commons-collections/commons-collections/3.2.1
install -s mvn:org.apache.geronimo.specs/geronimo-jpa_2.0_spec/1.1
install -s wrap:mvn:net.sourceforge.serp/serp/1.13.1
-install -s mvn:org.apache.openjpa/openjpa/2.1.1
-install -s mvn:org.apache.aries.transaction/org.apache.aries.transaction.blueprint/0.3
install -s mvn:org.apache.aries.transaction/org.apache.aries.transaction.manager/0.3
+install -s mvn:org.apache.aries.transaction/org.apache.aries.transaction.blueprint/0.3
+install -s mvn:commons-dbcp/commons-dbcp/1.4
+install -s mvn:org.apache.openjpa/openjpa/2.1.1
+install -s mvn:org.apache.aries/org.apache.aries.util/0.4
install -s mvn:org.apache.aries.jpa/org.apache.aries.jpa.api/0.3
install -s mvn:org.apache.aries.proxy/org.apache.aries.proxy/0.3
install -s mvn:org.apache.aries.jpa/org.apache.aries.jpa.container/0.3
+install -s mvn:org.apache.aries.jpa/org.apache.aries.jpa.container.context/0.3
install -s mvn:org.apache.aries.jpa/org.apache.aries.jpa.blueprint.aries/0.3
+install -s mvn:org.apache.aries.proxy/org.apache.aries.proxy/0.4
+install -s mvn:org.apache.aries.jndi/org.apache.aries.jndi.api/0.3
+install -s mvn:org.apache.aries.jndi/org.apache.aries.jndi.core/0.3.1
+install -s mvn:org.apache.aries.jndi/org.apache.aries.jndi.url/0.3.1
install -s mvn:net.lr.tutorial.karaf.db/db-examplejpa/1.0-SNAPSHOT
Test
----
-The example creates and populates a table on startup, queries it and outputs the result
+The bundle installs two Karaf shell commands:
+
+person:add 'Christian Schneider' @schneider_chris
+-> Adds a person ( this currently does not work)
+
+Instead we use the db commands to populate the DB by manually:
+karaf@root> db:select jdbc/derbyds
+karaf@root> db:exec "insert into person (id, name, twittername) values (1, 'Christian Schneider', '@schneider_chris')"
-The output should look like this:
-Using datasource H2 ver jdbc:h2:~/test
-Christian Schneider, @schneider_chris,
+karaf@root> person:list
+Christian Schneider, @schneider_chris
+-> Lists all persisted Persons
View
10 db/examplejpa/derby.log
@@ -0,0 +1,10 @@
+----------------------------------------------------------------
+Fri Jan 13 16:55:52 CET 2012:
+Booting Derby version The Apache Software Foundation - Apache Derby - 10.8.2.2 - (1181258): instance a816c00e-0134-d7c8-3ee5-000007529e80
+on database directory C:\checkout\Karaf-Tutorial\db\examplejpa\target\test with class loader sun.misc.Launcher$AppClassLoader@6d6f0472
+Loaded from file:/C:/Users/cschneider/.m2/repository/org/apache/derby/derby/10.8.2.2/derby-10.8.2.2.jar
+java.vendor=Sun Microsystems Inc.
+java.runtime.version=1.6.0_25-b06
+user.dir=C:\checkout\Karaf-Tutorial\db\examplejpa
+derby.system.home=null
+Database Class Loader started - derby.database.classpath=''
View
63 db/examplejpa/pom.xml
@@ -27,13 +27,18 @@
<artifactId>geronimo-jpa_2.0_spec</artifactId>
<version>1.1</version>
</dependency>
-
+
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.console</artifactId>
+ <version>2.2.5</version>
+ </dependency>
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-version}</version>
@@ -84,34 +89,34 @@
</configuration>
</plugin>
<plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>openjpa-maven-plugin</artifactId>
- <configuration>
- <addDefaultConstructor>true</addDefaultConstructor>
- <enforcePropertyRestriction>true</enforcePropertyRestriction>
- </configuration>
- <executions>
- <execution>
- <id>enhancer</id>
- <phase>process-classes</phase>
- <goals>
- <goal>enhance</goal>
- </goals>
- </execution>
- </executions>
- <dependencies>
- <dependency>
- <groupId>org.apache.openjpa</groupId>
- <artifactId>openjpa</artifactId>
- <version>2.1.1</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>${slf4j-version}</version>
- </dependency>
- </dependencies>
- </plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>openjpa-maven-plugin</artifactId>
+ <configuration>
+ <addDefaultConstructor>true</addDefaultConstructor>
+ <enforcePropertyRestriction>true</enforcePropertyRestriction>
+ </configuration>
+ <executions>
+ <execution>
+ <id>enhancer</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>enhance</goal>
+ </goals>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.openjpa</groupId>
+ <artifactId>openjpa</artifactId>
+ <version>2.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j-version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
View
5 db/examplejpa/src/main/java/net/lr/tutorial/karaf/db/examplejpa/PersonService.java
@@ -3,6 +3,7 @@
import java.util.List;
public interface PersonService {
- void addPersion(Person person);
- List<Person> getAllPersons();
+ void add(Person person);
+ void deleteAll();
+ List<Person> getAll();
}
View
46 db/examplejpa/src/main/java/net/lr/tutorial/karaf/db/examplejpa/command/AddPersonCommand.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.lr.tutorial.karaf.db.examplejpa.command;
+
+import net.lr.tutorial.karaf.db.examplejpa.Person;
+import net.lr.tutorial.karaf.db.examplejpa.PersonService;
+
+import org.apache.felix.gogo.commands.Action;
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.service.command.CommandSession;
+
+@Command(scope = "person", name = "add", description = "Adds a person")
+public class AddPersonCommand implements Action {
+ @Argument(index=0, name="Name", required=true, description="Name", multiValued=false)
+ String name;
+ @Argument(index=1, name="Twitter Name", required=true, description="Twitter Name", multiValued=false)
+ String twitterName;
+ private PersonService personService;
+
+ public void setPersonService(PersonService personService) {
+ this.personService = personService;
+ }
+
+ @Override
+ public Object execute(CommandSession session) throws Exception {
+ Person person = new Person(name, twitterName);
+ personService.add(person);
+ return null;
+ }
+
+}
View
45 db/examplejpa/src/main/java/net/lr/tutorial/karaf/db/examplejpa/command/ListPersonsCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.lr.tutorial.karaf.db.examplejpa.command;
+
+import java.util.List;
+
+import net.lr.tutorial.karaf.db.examplejpa.Person;
+import net.lr.tutorial.karaf.db.examplejpa.PersonService;
+
+import org.apache.felix.gogo.commands.Action;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.service.command.CommandSession;
+
+@Command(scope = "person", name = "list", description = "Lists all persons")
+public class ListPersonsCommand implements Action {
+ private PersonService personService;
+
+ public void setPersonService(PersonService personService) {
+ this.personService = personService;
+ }
+
+ @Override
+ public Object execute(CommandSession session) throws Exception {
+ List<Person> persons = personService.getAll();
+ for (Person person : persons) {
+ System.out.println(person.getName() + ", " + person.getTwitterName());
+ }
+ return null;
+ }
+
+}
View
12 db/examplejpa/src/main/java/net/lr/tutorial/karaf/db/examplejpa/impl/PersonServiceImpl.java
@@ -3,7 +3,6 @@
import java.util.List;
import javax.persistence.EntityManager;
-import javax.persistence.criteria.CriteriaQuery;
import net.lr.tutorial.karaf.db.examplejpa.Person;
import net.lr.tutorial.karaf.db.examplejpa.PersonService;
@@ -16,14 +15,17 @@ public void setEntityManager (EntityManager em) {
}
@Override
- public void addPersion(Person person) {
+ public void add(Person person) {
em.persist(person);
}
+
+ public void deleteAll() {
+ em.createQuery("delete from Person").executeUpdate();
+ }
@Override
- public List<Person> getAllPersons() {
- CriteriaQuery<Person> query = em.getCriteriaBuilder().createQuery(Person.class);
- return em.createQuery(query).getResultList();
+ public List<Person> getAll() {
+ return em.createQuery("select p from Person p", Person.class).getResultList();
}
}
View
6 db/examplejpa/src/main/resources/META-INF/persistence.xml
@@ -27,9 +27,9 @@
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
- <property name="openjpa.BrokerImpl" value="non-finalizing" />
- <property name="openjpa.Sequence" value="table(Table=OPENJPASEQ, Increment=100)"/>
- <property name="openjpa.jdbc.UpdateManager" value="org.apache.openjpa.jdbc.kernel.BatchingConstraintUpdateManager"/>
+<!-- <property name="openjpa.BrokerImpl" value="non-finalizing" /> -->
+<!-- <property name="openjpa.Sequence" value="table(Table=OPENJPASEQ, Increment=100)"/> -->
+<!-- <property name="openjpa.jdbc.UpdateManager" value="org.apache.openjpa.jdbc.kernel.BatchingConstraintUpdateManager"/> -->
<!-- These properties are creating the database on the fly. We are using them to avoid users having
to create a database to run the sample. This is not something that should be used in production.
See also the create=true line in the ariestrader-derby-ds blueprint meta data -->
View
16 db/examplejpa/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -17,7 +17,7 @@
limitations under the License.
-->
-<blueprint default-activation="lazy"
+<blueprint default-activation="eager"
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0"
@@ -29,5 +29,17 @@
</bean>
<service ref="personService" interface="net.lr.tutorial.karaf.db.examplejpa.PersonService" />
-
+
+ <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+ <command name="person/add">
+ <action class="net.lr.tutorial.karaf.db.examplejpa.command.AddPersonCommand">
+ <property name="personService" ref="personService"/>
+ </action>
+ </command>
+ <command name="person/list">
+ <action class="net.lr.tutorial.karaf.db.examplejpa.command.ListPersonsCommand">
+ <property name="personService" ref="personService"/>
+ </action>
+ </command>
+ </command-bundle>
</blueprint>
View
322 db/examplejpa/src/test/java/net/lr/tutorial/karaf/db/examplejpa/MyInitialContextFactory.java
@@ -15,169 +15,175 @@
public class MyInitialContextFactory implements InitialContextFactory {
- @Override
- public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
- return new Context() {
-
- private Map<String, Object> map = new HashMap<String, Object>();
+ public final class MapContext implements Context {
+ private Map<String, Object> map = new HashMap<String, Object>();
- @Override
- public void unbind(String name) throws NamingException {
- }
-
- @Override
- public void unbind(Name name) throws NamingException {
- }
-
- @Override
- public void rename(String oldName, String newName) throws NamingException {
- }
-
- @Override
- public void rename(Name oldName, Name newName) throws NamingException {
- }
-
- @Override
- public Object removeFromEnvironment(String propName) throws NamingException {
- return null;
- }
-
- @Override
- public void rebind(String name, Object obj) throws NamingException {
- }
-
- @Override
- public void rebind(Name name, Object obj) throws NamingException {
- }
-
- @Override
- public Object lookupLink(String name) throws NamingException {
- return null;
- }
-
- @Override
- public Object lookupLink(Name name) throws NamingException {
- return null;
- }
-
- @Override
- public Object lookup(String name) throws NamingException {
- return map.get(name);
- }
-
- @Override
- public Object lookup(Name name) throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public NamingEnumeration<Binding> listBindings(String name) throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public NamingEnumeration<NameClassPair> list(String name) throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public NameParser getNameParser(String name) throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public NameParser getNameParser(Name name) throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public String getNameInNamespace() throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Hashtable<?, ?> getEnvironment() throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public void destroySubcontext(String name) throws NamingException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void destroySubcontext(Name name) throws NamingException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public Context createSubcontext(String name) throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Context createSubcontext(Name name) throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public String composeName(String name, String prefix) throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Name composeName(Name name, Name prefix) throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
+ @Override
+ public void unbind(String name) throws NamingException {
+ }
+
+ @Override
+ public void unbind(Name name) throws NamingException {
+ }
+
+ @Override
+ public void rename(String oldName, String newName) throws NamingException {
+ }
+
+ @Override
+ public void rename(Name oldName, Name newName) throws NamingException {
+ }
+
+ @Override
+ public Object removeFromEnvironment(String propName) throws NamingException {
+ return null;
+ }
+
+ @Override
+ public void rebind(String name, Object obj) throws NamingException {
+ }
+
+ @Override
+ public void rebind(Name name, Object obj) throws NamingException {
+ }
+
+ @Override
+ public Object lookupLink(String name) throws NamingException {
+ return null;
+ }
+
+ @Override
+ public Object lookupLink(Name name) throws NamingException {
+ return null;
+ }
+
+ @Override
+ public Object lookup(String name) throws NamingException {
+ return map.get(name);
+ }
+
+ @Override
+ public Object lookup(Name name) throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public NamingEnumeration<Binding> listBindings(String name) throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public NamingEnumeration<NameClassPair> list(String name) throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public NameParser getNameParser(String name) throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public NameParser getNameParser(Name name) throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getNameInNamespace() throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Hashtable<?, ?> getEnvironment() throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void destroySubcontext(String name) throws NamingException {
+ // TODO Auto-generated method stub
- @Override
- public void close() throws NamingException {
- // TODO Auto-generated method stub
-
- }
+ }
+
+ @Override
+ public void destroySubcontext(Name name) throws NamingException {
+ // TODO Auto-generated method stub
- @Override
- public void bind(String name, Object obj) throws NamingException {
- map.put(name, obj);
- }
+ }
+
+ @Override
+ public Context createSubcontext(String name) throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Context createSubcontext(Name name) throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String composeName(String name, String prefix) throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Name composeName(Name name, Name prefix) throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void close() throws NamingException {
+ // TODO Auto-generated method stub
- @Override
- public void bind(Name name, Object obj) throws NamingException {
- // TODO Auto-generated method stub
-
- }
+ }
+
+ @Override
+ public void bind(String name, Object obj) throws NamingException {
+ map.put(name, obj);
+ }
+
+ @Override
+ public void bind(Name name, Object obj) throws NamingException {
+ map.put(name.toString(), obj);
- @Override
- public Object addToEnvironment(String propName, Object propVal) throws NamingException {
- // TODO Auto-generated method stub
- return null;
- }
- };
+ }
+
+ @Override
+ public Object addToEnvironment(String propName, Object propVal) throws NamingException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ }
+
+ private static Context defaultContext = null;
+
+ @Override
+ public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
+ if (defaultContext == null) {
+ defaultContext = new MapContext();;
+ }
+ return defaultContext;
}
}
View
30 db/examplejpa/src/test/java/net/lr/tutorial/karaf/db/examplejpa/PersonServiceImplTest.java
@@ -1,9 +1,13 @@
package net.lr.tutorial.karaf.db.examplejpa;
+import java.util.Hashtable;
import java.util.List;
-import javax.naming.Context;
import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+import javax.naming.spi.InitialContextFactoryBuilder;
+import javax.naming.spi.NamingManager;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
@@ -16,20 +20,30 @@
public class PersonServiceImplTest {
+ public final class MyInitialcontextFactoryBuilder implements InitialContextFactoryBuilder {
+ @Override
+ public InitialContextFactory createInitialContextFactory(Hashtable<?, ?> environment) throws NamingException {
+ return new MyInitialContextFactory();
+ }
+ }
+
+ @Test
public void testWriteRead() throws Exception {
- System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "net.lr.tutorial.karaf.db.examplejpa.MyInitialContextFactory");
- System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
+ NamingManager.setInitialContextFactoryBuilder(new MyInitialcontextFactoryBuilder());
InitialContext ic = new InitialContext();
- ic.createSubcontext("jdbc");
EmbeddedDataSource ds = new EmbeddedDataSource();
- ic.bind("jdbc/derbyds", ds);
+ ds.setDatabaseName("target/test");
+ ds.setCreateDatabase("create");
+ ic.bind("osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/derbyds)", ds);
PersonServiceImpl personService = new PersonServiceImpl();
EntityManagerFactory emf = Persistence.createEntityManagerFactory("person", System.getProperties());
EntityManager em = emf.createEntityManager();
personService.setEntityManager(em);
-
- personService.addPersion(new Person("Christian Schneider", "@schneider_chris"));
- List<Person> persons = personService.getAllPersons();
+ em.getTransaction().begin();
+ personService.deleteAll();
+ personService.add(new Person("Christian Schneider", "@schneider_chris"));
+ em.getTransaction().commit();
+ List<Person> persons = personService.getAll();
Assert.assertEquals(1, persons.size());
Assert.assertEquals("Christian Schneider", persons.get(0).getName());
Assert.assertEquals("@schneider_chris", persons.get(0).getTwitterName());
View
90 db/karaf_tutorial_6_databases.txt
@@ -1,7 +1,5 @@
-h1. Apache Karaf Tutorial Part 6 - Database Access
-
{excerpt}
-Shows how to access databases from OSGi applications running in Karaf and how to abstract from the DB product by installing DataSources as OSGi services. Some new Karaf shell commands can be used to
+Shows how to access databases from OSGi applications running in Karaf and how to abstract from the DB product by installing DataSources as OSGi services. Some new Karaf shell commands can be used to
work with the database from the command line. Finally JDBC and JPA examples show how to use such a DataSource from user code.
{excerpt}
@@ -12,21 +10,21 @@ one Karaf command. If the driver is available in maven but no bundle we can most
in the repo we have to install the file into the maven repo first.
For derby the following command will work
-> install -s mvn:org.apache.derby/derby/10.8.2.2
+{code}
+> install -s mvn:org.apache.derby/derby/10.8.2.2
+{code}
See the [db/datasource|https://github.com/cschneider/Karaf-Tutorial/tree/master/db/datasource] folder on github for installation instructions for (db2, derby, h2, mysql and oracle).
h2. Installing the datasource
-In Java EE servers and servlet containters you typically use JNDI to install a DataSource on the server level so the application can just refer to it and so does not have to know the specific driver or database url.
-In OSGi JNDI is replaced by OSGi services. So the best way to decouple your application from the database is to offer a DataSource as an OSGi service.
+In Java EE servers and servlet containters you typically use JNDI to install a DataSource on the server level so the application can just refer to it and so does not have to know the specific driver or database url. In OSGi JNDI is replaced by OSGi services. So the best way to decouple your application from the database is to offer a DataSource as an OSGi service.
-As we can deploy simple blueprint xml files in Karaf this is really easy. We define a bean with the class of the specific datasource impl and configure it. Then we publish that bean as an OSGi service with the interface a javax.sql.DataSource.
-This works because Karaf uses dynamic imports when it deploys blueprint context files so all classes are available.
+As we can deploy simple blueprint xml files in Karaf this is really easy. We define a bean with the class of the specific datasource impl and configure it. Then we publish that bean as an OSGi service with the interface a javax.sql.DataSource. This works because Karaf uses dynamic imports when it deploys blueprint context files so all classes are available.
For each database flalour you can find a suitable blueprint.xml in [db/datasource|https://github.com/cschneider/Karaf-Tutorial/tree/master/db/datasource].
-h2. Browsing the database using the Karaf db:* commands
+h2. Browsing the database using the Karaf db:\* commands
As part of this tutorial I created some simple Karaf commands to work with databases from the Karaf shell. These commands proved to be quite handy so I will try to move them to the Karaf project.
@@ -89,40 +87,82 @@ Christian Schneider | @schneider_chris
h2. Accessing the database using JDBC
-The project [db/examplejdbc|https://github.com/cschneider/Karaf-Tutorial/tree/master/db/examplejdbc] shows how to use the datasource we installed and execute jdbc commands on it.
-The example uses a [blueprint.xml|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejdbc/src/main/resources/OSGI-INF/blueprint/blueprint.xml] to refer to the OSGi service for the DataSource and injects it into the class [DbExample|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejdbc/src/main/java/net/lr/tutorial/karaf/db/example/DbExample.java].
-The test method is then called as init method and shows some jdbc statements on the DataSource.
+The project [db/examplejdbc|https://github.com/cschneider/Karaf-Tutorial/tree/master/db/examplejdbc] shows how to use the datasource we installed and execute jdbc commands on it. The example uses a [blueprint.xml|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejdbc/src/main/resources/OSGI-INF/blueprint/blueprint.xml] to refer to the OSGi service for the DataSource and injects it into the class
+[DbExample|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejdbc/src/main/java/net/lr/tutorial/karaf/db/example/DbExample.java].The test method is then called as init method and shows some jdbc statements on the DataSource.The DbExample class is completely independent of OSGi and can be easily tested standalone using the [DbExampleTest|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejdbc/src/test/java/net/lr/tutorial/karaf/db/example/DbExampleTest.java]. This test shows how to manually set up the DataSource outside of OSGi.
-The DbExample class is completely independent of OSGi and can be easily tested standalone using the [DbExampleTest|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejdbc/src/test/java/net/lr/tutorial/karaf/db/example/DbExampleTest.java]. This test shows how to manually set up the DataSource outside of OSGi.
+h3. Build and install
+
+Build works like always using maven
+{code}
+> mvn clean install
+{code}
+
+In Karaf we just need our own bundle as we have no special dependencies
+{code}
+> install -s mvn:net.lr.tutorial.karaf.db/db-examplejdbc/1.0-SNAPSHOT
+Using datasource H2, URL jdbc:h2:~/test
+Christian Schneider, @schneider_chris,
+{code}
+
+After installation the bundle should directly print the db info and the persisted person.
h2. Accessing the database using JPA
-For larger projects it is quite tpyical that JPA is used instead of hand crafted SQL. Using JPA has two big advantages over JDBC. You need to maintain less SQL code and JPA provides dialects for the subtle differences in databases that else you would have to code yourself.
-For this example we use OpenJPA as the JPA Implementation. On top of it we add Apache Aries JPA which supplies an implementation of the OSGi JPA Service Specification and blueprint integration for JPA.
+For larger projects it is quite typical that JPA is used instead of hand crafted SQL. Using JPA has two big advantages over JDBC. You need to maintain less SQL code and JPA provides dialects for the subtle differences in databases that else you would have to code yourself. For this example we use OpenJPA as the JPA Implementation. On top of it we add Apache Aries JPA which supplies an implementation of the OSGi JPA Service Specification and blueprint integration for JPA.
-The project [examplejpa|https://github.com/cschneider/Karaf-Tutorial/tree/master/db/examplejpa] shows a simple project that implements a PersonService that persists [Person|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejpa/src/main/java/net/lr/tutorial/karaf/db/examplejpa/Person.java] objects.
-Person is just a java bean annotated with JPA @Entitiy. As OpenJPA needs to enhance the bytecode of the classes we need to add the openjpa-maven-plugin to the pom.xml which prepares the classes for JPA.
+The project [examplejpa|https://github.com/cschneider/Karaf-Tutorial/tree/master/db/examplejpa] shows a simple project that implements a PersonService that manages [Person|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejpa/src/main/java/net/lr/tutorial/karaf/db/examplejpa/Person.java] objects.
+Person is just a java bean annotated with JPA @Entitiy. As OpenJPA needs to enhance the bytecode of the classes we need to add the openjpa-maven-plugin to the [pom.xml|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejpa/pom.xml] which prepares the classes for JPA.
+
+Additionally the project implements two Karaf shell commands person:add and person:list that allow to easily test the project.
h3. persistence.xml
-Like in a typical JPA project the [peristence.xml|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejpa/src/main/resources/META-INF/persistence.xml] defines the DataSource lookup,
-database settings and lists the persistent classes. The datasource is refered to using "osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/derbyds)". This makes a lookup for an OSGi service with the given interface and properties.
+Like in a typical JPA project the [peristence.xml|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejpa/src/main/resources/META-INF/persistence.xml] defines the DataSource lookup, database settings and lists the persistent classes. The datasource is refered using "osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/derbyds)". This makes a lookup for an OSGi service with the given interface and properties.
-The OSGi JPA Service Specification defines that the Manifest should contain an attribute "Meta-Persistence" that points to the persistence.xml. So this needs to be defined in the config of the maven bundle plugin. The Aries JPA container will scan for these attributes
+The OSGi JPA Service Specification defines that the Manifest should contain an attribute "Meta-Persistence" that points to the persistence.xml. So this needs to be defined in the config of the maven bundle plugin in the prom. The Aries JPA container will scan for these attributes
and register an initialized EntityMangerFactory as an OSGi service on behalf of the use bundle.
h3. blueprint.xml
-We use a [blueprint.xml|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejpa/src/main/resources/OSGI-INF/blueprint/blueprint.xml] context to inject an EntityManager into our service implementation and to provide automatic transaction support.
-The following snippet is the intersting part:
+We use a [blueprint.xml|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejpa/src/main/resources/OSGI-INF/blueprint/blueprint.xml] context to inject an EntityManager into our service implementation and to provide automatic transaction support.
+The following snippet is the interesting part:
{code}
- <bean id="personService" class="net.lr.tutorial.karaf.db.examplejpa.PersonServiceImpl">
+ <bean id="personService" class="net.lr.tutorial.karaf.db.examplejpa.impl.PersonServiceImpl">
<jpa:context property="entityManager" unitname="person" />
<tx:transaction method="*" value="Required"/>
</bean>
{code}
-This makes a lookup for the EntityManagerFactory OSGi service that is suitable for the persistence unit person and injects an EnityManager into the
-[PersonServiceImpl|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejpa/src/main/java/net/lr/tutorial/karaf/db/examplejpa/PersonServiceImpl.java]. Additionally it wraps each call to a method of PersonServiceImpl with code that opens a transaction
+This makes a lookup for the EntityManagerFactory OSGi service that is suitable for the persistence unit person and injects an EnityManager into the
+[PersonServiceImpl|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejpa/src/main/java/net/lr/tutorial/karaf/db/examplejpa/impl/PersonServiceImpl.java]. Additionally it wraps each call to a method of PersonServiceImpl with code that opens a transaction
before the method and commits on success or rollbacks on any exception thrown.
+h3. Build and Install
+
+The project builds with mvn clean install like usual. A prerequisite is that the derby datasource is installed like described above. Then we have to install the bundles for openjpa, aries (jpa, transaction, proxy and jndi) and of course our db-examplejpa bundle.
+See [ReadMe.txt|https://github.com/cschneider/Karaf-Tutorial/blob/master/db/examplejpa/ReadMe.txt] for the exact commands to use.
+
+h3. Test
+
+{code}
+person:add 'Christian Schneider' @schneider_chris
+{code}
+
+This should create a person object with the above data and persist it to the database. Unfortunately this currently does not work. I guess I still have an error somewhere. So instead we use the db commands to populate the DB by manually:
+{code}
+db:select jdbc/derbyds
+db:exec "insert into person (id, name, twittername) values (1, 'Christian Schneider', '@schneider_chris')"
+{code}
+
+Then we list the persisted persons
+{code}
+karaf@root> person:list
+Christian Schneider, @schneider_chris
+{code}
+
+h2. Summary
+
+In this tutorial we learned how to work with databases in Apache Karaf. We installed drivers for our database and a DataSource. We were able to check and manipulate the DataSource using the db:\* commands. In the examplejdbc we learned how to acquire a datasource
+and work with it using plain jdbc. This is really easy but a bit verbose. You might want to try the spring JdbcTemplate to remove all the cleanup code. Last but not least we also used jpa to access our database.
+
+In theory JPA and OSGi work together really well. Keep in mind though that JPA support for OSGi is still quite fresh. It took me quite a while to get it all running. The documentation is quite sparse and I still have not been able to fix the persist issue. I will update the code and blog entry as soon as I have the jpa persist working.
Please sign in to comment.
Something went wrong with that request. Please try again.