Support mapping files - Fixes ARIES-1711
diff --git a/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/blueprint/aries/itest/BlueprintTest.java b/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/blueprint/aries/itest/BlueprintTest.java
index dacdcc0..f37ac34 100644
--- a/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/blueprint/aries/itest/BlueprintTest.java
+++ b/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/blueprint/aries/itest/BlueprintTest.java
@@ -61,7 +61,7 @@
} finally {
coordination.end();
}
- carService.deleteCar(BLUE_CAR_PLATE);
+ carService.deleteCar(BLUE_PLATE);
Assert.assertEquals(0, carService.getCars().size());
}
}
@@ -132,22 +132,22 @@
private void carLifecycle(CarService carService) {
assertNoCoordination();
if (carService.getCar(BLACK_CAR_PLATE) != null) {
- carService.deleteCar(BLUE_CAR_PLATE);
+ carService.deleteCar(BLUE_PLATE);
}
carService.addCar(createBlueCar());
- assertBlueCar(carService.getCar(BLUE_CAR_PLATE));
- carService.deleteCar(BLUE_CAR_PLATE);
+ assertBlueCar(carService.getCar(BLUE_PLATE));
+ carService.deleteCar(BLUE_PLATE);
}
private void carRealTransactionalLifecycle(CarService carService) throws IllegalStateException, SystemException, NotSupportedException {
assertNoCoordination();
if (carService.getCar(BLACK_CAR_PLATE) != null) {
- carService.deleteCar(BLUE_CAR_PLATE);
+ carService.deleteCar(BLUE_PLATE);
}
ut.begin();
carService.addCar(createBlueCar());
ut.rollback();
- Assert.assertNull(carService.getCar(BLUE_CAR_PLATE));
+ Assert.assertNull(carService.getCar(BLUE_PLATE));
}
private void assertNoCoordination() {
diff --git a/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/JPAContainerTest.java b/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/JPAContainerTest.java
index 73c12f6..7ba38fe 100644
--- a/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/JPAContainerTest.java
+++ b/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/JPAContainerTest.java
@@ -57,25 +57,49 @@
public void testCarEMF() throws Exception {
carLifecycleRL(getEMF(TEST_UNIT).createEntityManager());
}
+
+ @Test
+ public void testTruckEMF() throws Exception {
+ truckLifecycleRL(getEMF(TEST_UNIT).createEntityManager());
+ }
@Test
- public void testEMFXA() throws Exception {
+ public void testCarEMFXA() throws Exception {
EntityManager em = getEMF(XA_TEST_UNIT).createEntityManager();
carLifecycleXA(ut, em);
em.close();
}
@Test
- public void testDataSourceFactoryLifecycle() throws Exception {
+ public void testTruckEMFXA() throws Exception {
+ EntityManager em = getEMF(XA_TEST_UNIT).createEntityManager();
+ truckLifecycleXA(ut, em);
+ em.close();
+ }
+
+ @Test
+ public void testCarDataSourceFactoryLifecycle() throws Exception {
carLifecycleRL(getEMF(DSF_TEST_UNIT).createEntityManager());
}
@Test
- public void testDataSourceFactoryXALifecycle() throws Exception {
+ public void testTruckDataSourceFactoryLifecycle() throws Exception {
+ truckLifecycleRL(getEMF(DSF_TEST_UNIT).createEntityManager());
+ }
+
+ @Test
+ public void testCarDataSourceFactoryXALifecycle() throws Exception {
EntityManager em = getEMF(DSF_XA_TEST_UNIT).createEntityManager();
carLifecycleXA(ut, em);
em.close();
}
+
+ @Test
+ public void testTruckDataSourceFactoryXALifecycle() throws Exception {
+ EntityManager em = getEMF(DSF_XA_TEST_UNIT).createEntityManager();
+ truckLifecycleXA(ut, em);
+ em.close();
+ }
@Test
@@ -106,7 +130,7 @@
ut.begin();
em.joinTransaction();
- changeToRed(em.find(Car.class, BLUE_CAR_PLATE));
+ changeToRed(em.find(Car.class, BLUE_PLATE));
em.remove(em.find(Car.class, GREEN_CAR_PLATE));
em.persist(createBlackCar());
ut.commit();
@@ -133,8 +157,8 @@
private void cleanup(EntityManager em) throws Exception {
ut.begin();
em.joinTransaction();
- delete(em, BLACK_CAR_PLATE);
- delete(em, BLUE_CAR_PLATE);
+ delete(em, Car.class, BLACK_CAR_PLATE);
+ delete(em, Car.class, BLUE_PLATE);
ut.commit();
}
@@ -142,7 +166,7 @@
assertEquals(2, car.getNumberOfSeats());
assertEquals(2000, car.getEngineSize());
assertEquals("red", car.getColour());
- assertEquals(BLUE_CAR_PLATE, car.getNumberPlate());
+ assertEquals(BLUE_PLATE, car.getNumberPlate());
}
@Test
@@ -165,6 +189,25 @@
}
@Test
+ public void testTruckEMFBuilderExternalDS() throws Exception {
+ DataSourceFactory dsf = getService(DataSourceFactory.class,
+ "(" + OSGI_JDBC_DRIVER_CLASS + "=org.apache.derby.jdbc.EmbeddedDriver)");
+
+ EntityManagerFactoryBuilder emfBuilder = getService(EntityManagerFactoryBuilder.class,
+ "(osgi.unit.name=" + EXTERNAL_TEST_UNIT + ")");
+
+ Properties jdbcProps = new Properties();
+ jdbcProps.setProperty("url", "jdbc:derby:memory:DSFTEST;create=true");
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("javax.persistence.nonJtaDataSource", dsf.createDataSource(jdbcProps));
+ props.put("javax.persistence.transactionType", RESOURCE_LOCAL.name());
+
+ EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
+ truckLifecycleRL(emf.createEntityManager());
+ }
+
+ @Test
public void testCarEMFBuilderExternalDSXA() throws Exception {
EntityManagerFactoryBuilder emfBuilder = getService(EntityManagerFactoryBuilder.class,
"(osgi.unit.name=" + EXTERNAL_TEST_UNIT + ")");
@@ -177,6 +220,20 @@
EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
carLifecycleXA(ut, emf.createEntityManager());
}
+
+ @Test
+ public void testTruckEMFBuilderExternalDSXA() throws Exception {
+ EntityManagerFactoryBuilder emfBuilder = getService(EntityManagerFactoryBuilder.class,
+ "(osgi.unit.name=" + EXTERNAL_TEST_UNIT + ")");
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("javax.persistence.jtaDataSource", ds);
+ props.put("javax.persistence.transactionType", JTA.name());
+ //EclipseLink also needs a non-jta-datasource
+ props.put("javax.persistence.nonJtaDataSource", ds);
+ EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
+ truckLifecycleXA(ut, emf.createEntityManager());
+ }
@Test
public void testCarEMFBuilderNoNonJTADataSource() throws Exception {
@@ -187,9 +244,25 @@
Properties jdbcProps = new Properties();
jdbcProps.setProperty("url", "jdbc:derby:memory:TESTNOJTA;create=true");
props.put("javax.persistence.dataSource", dsf.createDataSource(jdbcProps));
+ props.put("javax.persistence.transactionType", RESOURCE_LOCAL.name());
EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
carLifecycleRL(emf.createEntityManager());
}
+
+ @Test
+ public void testTruckEMFBuilderNoNonJTADataSource() throws Exception {
+ EntityManagerFactoryBuilder emfBuilder = getService(EntityManagerFactoryBuilder.class,
+ "(osgi.unit.name=" + EXTERNAL_TEST_UNIT + ")");
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ Properties jdbcProps = new Properties();
+ jdbcProps.setProperty("url", "jdbc:derby:memory:TESTNOJTA;create=true");
+ props.put("javax.persistence.dataSource", dsf.createDataSource(jdbcProps));
+ props.put("javax.persistence.transactionType", RESOURCE_LOCAL.name());
+
+ EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
+ truckLifecycleRL(emf.createEntityManager());
+ }
}
diff --git a/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/itest/AbstractCarJPAITest.java b/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/itest/AbstractCarJPAITest.java
index df36b7b..e81af3a 100644
--- a/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/itest/AbstractCarJPAITest.java
+++ b/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/itest/AbstractCarJPAITest.java
@@ -21,11 +21,12 @@
import javax.transaction.UserTransaction;
import org.apache.aries.jpa.container.itest.entities.Car;
+import org.apache.aries.jpa.container.itest.entities.mapped.Truck;
import org.junit.Assert;
import org.osgi.framework.BundleException;
public abstract class AbstractCarJPAITest extends AbstractJPAItest {
- protected static final String BLUE_CAR_PLATE = "A1AAA";
+ protected static final String BLUE_PLATE = "A1AAA";
protected static final String GREEN_CAR_PLATE = "B2BBB";
protected static final String BLACK_CAR_PLATE = "C3CCC";
@@ -34,10 +35,19 @@
car.setNumberOfSeats(5);
car.setEngineSize(1200);
car.setColour("blue");
- car.setNumberPlate(BLUE_CAR_PLATE);
+ car.setNumberPlate(BLUE_PLATE);
return car;
}
+ protected Truck createBlueTruck() {
+ Truck truck = new Truck();
+ truck.setMaxLoad(5000.0d);
+ truck.setEngineSize(1200);
+ truck.setColour("blue");
+ truck.setNumberPlate(BLUE_PLATE);
+ return truck;
+ }
+
protected Car createGreenCar() {
Car car;
car = new Car();
@@ -64,7 +74,15 @@
assertEquals(5, car.getNumberOfSeats());
assertEquals(1200, car.getEngineSize());
assertEquals("blue", car.getColour());
- assertEquals(BLUE_CAR_PLATE, car.getNumberPlate());
+ assertEquals(BLUE_PLATE, car.getNumberPlate());
+ }
+
+ protected void assertBlueTruck(Truck truck) {
+ Assert.assertNotNull("Blue car not found (null)", truck);
+ assertEquals(5000.0d, truck.getMaxLoad(), 0.0d);
+ assertEquals(1200, truck.getEngineSize());
+ assertEquals("blue", truck.getColour());
+ assertEquals(BLUE_PLATE, truck.getNumberPlate());
}
protected void assertGreenCar(Car car) {
@@ -92,7 +110,7 @@
em.persist(car);
em.getTransaction().commit();
- Car car2 = em.find(Car.class, BLUE_CAR_PLATE);
+ Car car2 = em.find(Car.class, BLUE_PLATE);
assertBlueCar(car2);
em.getTransaction().begin();
em.remove(car2);
@@ -101,6 +119,25 @@
}
/**
+ * Create, find and delete truck using resource local transactions
+ * @param emf
+ * @throws BundleException
+ */
+ protected void truckLifecycleRL(EntityManager em) throws BundleException {
+ em.getTransaction().begin();
+ Truck truck = createBlueTruck();
+ em.persist(truck);
+ em.getTransaction().commit();
+
+ Truck truck2 = em.find(Truck.class, BLUE_PLATE);
+ assertBlueTruck(truck2);
+ em.getTransaction().begin();
+ em.remove(truck2);
+ em.getTransaction().commit();
+ em.close();
+ }
+
+ /**
* Create, find and delete car using XA Transactions
* @param ut
* @param em
@@ -109,23 +146,45 @@
protected void carLifecycleXA(UserTransaction ut, EntityManager em) throws Exception {
ut.begin();
em.joinTransaction();
- delete(em, BLUE_CAR_PLATE);
+ delete(em, Car.class, BLUE_PLATE);
em.persist(createBlueCar());
ut.commit();
- Car c = em.find(Car.class, BLUE_CAR_PLATE);
+ Car c = em.find(Car.class, BLUE_PLATE);
assertBlueCar(c);
ut.begin();
em.joinTransaction();
- delete(em, BLUE_CAR_PLATE);
+ delete(em, Car.class, BLUE_PLATE);
ut.commit();
}
- protected void delete(EntityManager em, String plateId) {
- Car car = em.find(Car.class, plateId);
- if (car != null) {
- em.remove(car);
+ /**
+ * Create, find and delete car using XA Transactions
+ * @param ut
+ * @param em
+ * @throws Exception
+ */
+ protected void truckLifecycleXA(UserTransaction ut, EntityManager em) throws Exception {
+ ut.begin();
+ em.joinTransaction();
+ delete(em, Truck.class, BLUE_PLATE);
+ em.persist(createBlueTruck());
+ ut.commit();
+
+ Truck t = em.find(Truck.class, BLUE_PLATE);
+ assertBlueTruck(t);
+
+ ut.begin();
+ em.joinTransaction();
+ delete(em, Truck.class, BLUE_PLATE);
+ ut.commit();
+ }
+
+ protected <T> void delete(EntityManager em, Class<T> type, String plateId) {
+ T vehicle = em.find(type, plateId);
+ if (vehicle != null) {
+ em.remove(vehicle);
}
}
}
diff --git a/itests/jpa-container-testbundle/src/main/java/org/apache/aries/jpa/container/itest/entities/mapped/Truck.java b/itests/jpa-container-testbundle/src/main/java/org/apache/aries/jpa/container/itest/entities/mapped/Truck.java
new file mode 100644
index 0000000..3fb51a1
--- /dev/null
+++ b/itests/jpa-container-testbundle/src/main/java/org/apache/aries/jpa/container/itest/entities/mapped/Truck.java
@@ -0,0 +1,64 @@
+/*
+ * 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 WARRANTIESOR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.jpa.container.itest.entities.mapped;
+
+public class Truck {
+
+ private String numberPlate;
+
+ private String colour;
+
+ private int engineSize;
+
+ private double maxLoad;
+
+ public String getNumberPlate() {
+ return numberPlate;
+ }
+
+ public void setNumberPlate(String numberPlate) {
+ this.numberPlate = numberPlate;
+ }
+
+ public String getColour() {
+ return colour;
+ }
+
+ public void setColour(String colour) {
+ this.colour = colour;
+ }
+
+ public int getEngineSize() {
+ return engineSize;
+ }
+
+ public void setEngineSize(int engineSize) {
+ this.engineSize = engineSize;
+ }
+
+ public double getMaxLoad() {
+ return maxLoad;
+ }
+
+ public void setMaxLoad(double maxLoad) {
+ this.maxLoad = maxLoad;
+ }
+
+
+}
diff --git a/itests/jpa-container-testbundle/src/main/java/org/apache/aries/jpa/container/itest/entities/mapped/packageinfo b/itests/jpa-container-testbundle/src/main/java/org/apache/aries/jpa/container/itest/entities/mapped/packageinfo
new file mode 100644
index 0000000..c72722a
--- /dev/null
+++ b/itests/jpa-container-testbundle/src/main/java/org/apache/aries/jpa/container/itest/entities/mapped/packageinfo
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+version 1.0.0
diff --git a/itests/jpa-container-testbundle/src/main/resources/META-INF/custom-mapping.xml b/itests/jpa-container-testbundle/src/main/resources/META-INF/custom-mapping.xml
new file mode 100644
index 0000000..7b8d8e2
--- /dev/null
+++ b/itests/jpa-container-testbundle/src/main/resources/META-INF/custom-mapping.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entity-mappings 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 http://xmlns.jcp.org/xml/ns/persistence/orm_2_0.xsd"
+ version="2.0">
+
+ <package>org.apache.aries.jpa.container.itest.entities.mapped</package>
+ <entity class="org.apache.aries.jpa.container.itest.entities.mapped.Truck" name="Truck">
+ <named-query name="GET_DEVELOPER">
+ <query>SELECT DISTINCT record FROM Car record ORDER BY record.engineSize</query>
+ </named-query>
+ <attributes>
+ <id name="numberPlate">
+ <column name="PLATE" length="255" />
+ </id>
+ <basic name="colour">
+ <column name="COLOUR" length="255" />
+ </basic>
+ <basic name="engineSize">
+ <column name="ENGINE_SIZE" />
+ </basic>
+ <basic name="maxLoad">
+ <column name="MAX_LOAD" length="255" />
+ </basic>
+ </attributes>
+ </entity>
+</entity-mappings>
\ No newline at end of file
diff --git a/itests/jpa-container-testbundle/src/main/resources/META-INF/persistence.xml b/itests/jpa-container-testbundle/src/main/resources/META-INF/persistence.xml
index 6d4fd63..535803c 100644
--- a/itests/jpa-container-testbundle/src/main/resources/META-INF/persistence.xml
+++ b/itests/jpa-container-testbundle/src/main/resources/META-INF/persistence.xml
@@ -26,6 +26,7 @@
<description>Test persistence unit for the JPA Container and Context iTests</description>
<non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=testds)</non-jta-data-source>
+ <mapping-file>META-INF/custom-mapping.xml</mapping-file>
<properties>
<!-- This is to avoid compile time enhancement which would conflict with hibernate -->
<property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>
@@ -45,6 +46,7 @@
<description>Test persistence unit for the JPA Container advanced iTests</description>
<jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=testdsxa)</jta-data-source>
+ <mapping-file>META-INF/custom-mapping.xml</mapping-file>
<properties>
<!-- These properties are creating the database on the fly. We are using them to avoid the tests having to create a database -->
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
@@ -58,6 +60,7 @@
<persistence-unit name="dsf-test-unit" transaction-type="RESOURCE_LOCAL">
<description>Test persistence unit for the JPA Container DataSourceFactory iTests</description>
+ <mapping-file>META-INF/custom-mapping.xml</mapping-file>
<properties>
<!-- These properties are creating the database on the fly. We are using them to avoid the tests having
to create a database -->
@@ -74,6 +77,7 @@
<persistence-unit name="dsf-xa-test-unit" transaction-type="JTA">
<description>Test persistence unit for the JPA Container DataSourceFactory iTests</description>
+ <mapping-file>META-INF/custom-mapping.xml</mapping-file>
<properties>
<!-- These properties are creating the database on the fly. We are using them to avoid the tests having to create a database -->
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
@@ -89,6 +93,7 @@
<persistence-unit name="external-test-unit">
<description>Test persistence unit for the JPA Container External DataSource iTests</description>
+ <mapping-file>META-INF/custom-mapping.xml</mapping-file>
<properties>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
diff --git a/jpa-container/src/main/java/org/apache/aries/jpa/container/parser/impl/JPAHandler.java b/jpa-container/src/main/java/org/apache/aries/jpa/container/parser/impl/JPAHandler.java
index d2f0386..307a76b 100644
--- a/jpa-container/src/main/java/org/apache/aries/jpa/container/parser/impl/JPAHandler.java
+++ b/jpa-container/src/main/java/org/apache/aries/jpa/container/parser/impl/JPAHandler.java
@@ -103,6 +103,8 @@
pu.setNonJtaDataSourceName(s);
else if ("class".equals(elementName))
pu.addClassName(s);
+ else if("mapping-file".equals(elementName))
+ pu.addMappingFile(s);
else if ("exclude-unlisted-classes".equals(elementName))
pu.setExcludeUnlisted(Boolean.parseBoolean(s));
else if ("shared-cache-mode".equals(elementName))
diff --git a/jpa-container/src/main/java/org/apache/aries/jpa/container/parser/impl/PersistenceUnit.java b/jpa-container/src/main/java/org/apache/aries/jpa/container/parser/impl/PersistenceUnit.java
index 34e7911..1652f99 100644
--- a/jpa-container/src/main/java/org/apache/aries/jpa/container/parser/impl/PersistenceUnit.java
+++ b/jpa-container/src/main/java/org/apache/aries/jpa/container/parser/impl/PersistenceUnit.java
@@ -44,6 +44,7 @@
private Bundle bundle;
private ClassLoader classLoader;
private Set<String> classNames;
+ private Set<String> mappingFileNames;
private boolean excludeUnlisted;
private DataSource jtaDataSource;
private String jtaDataSourceName;
@@ -65,11 +66,16 @@
this.props = new Properties();
this.classLoader = bundle.adapt(BundleWiring.class).getClassLoader();
this.classNames = new HashSet<String>();
+ this.mappingFileNames = new HashSet<String>();
}
public void addClassName(String className) {
this.classNames.add(className);
}
+
+ public void addMappingFile(String mappingFileName) {
+ this.mappingFileNames.add(mappingFileName);
+ }
public void addProperty(String name, String value) {
props.put(name, value);
@@ -116,7 +122,7 @@
@Override
public List<String> getMappingFileNames() {
- return Collections.emptyList();
+ return new ArrayList<String>(mappingFileNames);
}
public String getName() {