Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
EclipseLink/Examples/PolyglotPersistence
This example is a variation of the NoSQL Example with some of the entities mapped to MongoDB and some to relational. The object model and the configuration for MongoDB is described in that example and is not repeated here.
Contents
Domain Model
Two of the entities from the NoSQL example have been altered so that they are mapped to a relational database (Derby embedded in the this case). Those two entities are Discount and Product:
@Entity public class Discount { @Id @GeneratedValue private int id; private float amount; ...
@Entity public class Product { @Id @GeneratedValue private int id; private String description; ...
The Order and OrderLine, mapped to MongoDB, have relationships to Discount and Product, respectively.
@Entity @NoSql(dataFormat=DataFormatType.MAPPED) public class Order { @Id // Use generated OID (UUID) from Mongo. @GeneratedValue @Field(name="_id") private String id; @Basic private String description; @OneToOne(cascade={CascadeType.REMOVE, CascadeType.PERSIST}) private Discount discount; ...
@Embeddable @NoSql(dataFormat=DataFormatType.MAPPED) public class OrderLine implements Serializable { @Basic private int lineNumber; @OneToOne(cascade={CascadeType.REMOVE, CascadeType.PERSIST}) private Product product; ...
Composite Persistence Unit
Composite persistence units provide a way to combine entities associated with different data sources into a single persistence unit. Whether the data source is relational or non-relation is irrelevant. Users of the composite persistence unit are unaware that they are working with a composite and that entities returned from queries or through relationship navigation may be coming from different data sources--they simple interact with a set entities.
In this example there are two composite member persistence units: "relational-pu" containing Discount and Product and "nosql-pu" containing the remaining classes. The persistence.xml for each of these persistence units lists their classes and associates them with the configured data source:
<?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="relational-pu" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <class>relational.model.Product</class> <class>relational.model.Discount</class> <properties> <property name="javax.persistence.jdbc.url" value="jdbc:derby:target/derby/test;create=true" /> <property name="javax.persistence.jdbc.user" value="app" /> <property name="javax.persistence.jdbc.password" value="app" /> <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" /> ...
<?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="nosql-pu" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <class>model.Order</class> <class>model.OrderLine</class> <class>model.Address</class> <class>model.Customer</class> <properties> <property name="eclipselink.target-database" value="org.eclipse.persistence.nosql.adapters.mongo.MongoPlatform" /> <property name="eclipselink.nosql.connection-spec" value="org.eclipse.persistence.nosql.adapters.mongo.MongoConnectionSpec" /> <property name="eclipselink.nosql.property.mongo.port" value="27017" /> <property name="eclipselink.nosql.property.mongo.host" value="localhost" /> ...
The composite persistence unit "composite-pu" is defined through a persistence.xml file that lists the jars containing the composite member persistence units and has the "eclipselink.composite-unit" property set to true:
<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 persistence_1_0.xsd" version="1.0"> <persistence-unit name="composite-pu" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jar-file>relational-pu.jar</jar-file> <jar-file>nosql-pu.jar</jar-file> <properties> <property name="eclipselink.composite-unit" value="true" /> ...
Using a Composite/Polyglot Persistence Unit
Using a composite persistence unit, whether polyglot or not, is exactly like using any persistence unit. You create an EntityMangerFactory and from that you obtain EntityManagers. To create obtain an EntityManagerFactory for the "composite-pu" defined above you would use Persistence.createEntityManagerFactory() as you normally would:
Persistence.createEntityManagerFactory("composite-pu");
Running the Polyglot Example
- MongoDB should be running on localhost
- Clone "examples" from git. The "polyglot" example is stored under the jpa/polyglot folder.
git clone git://git.eclipse.org/gitroot/eclipselink/examples.git
- cd into the jpa/polyglot folder and run mvn to compile and build the composite, composite members, and client jars.
- cd into the client folder to run client programs that use the composite persistence unit. You can run each of the client programs with the following command:
java -classpath "target/*" <Classname>
- example.CreateDatabase will (re)create the necessary tables in the relational database. Since MongoDB is schemaless nothing is necessary to initialize it.
- example.PolyglotDemo runs a sample program that will create a set of entities and persist them to the appropriate database. It will evict all entities from the EclipseLink cache and then query back an Order to illustrate how entities can be loaded transparently from either relational or NoSQL data sources.
- example.CleanDatabases will delete all instances of the domain model classes from both relational and NoSQL databases to allow you to reset the example.