blob: b51b8c29b18bc0d4efa842710b4e8f380937c6c9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 1998, 2008 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* dclarke - SimpleDynamicMap Example - Bug 277731
* http://wiki.eclipse.org/EclipseLink/Examples/JPA/Dynamic/SimpleDynamicMap
*
* This code is being developed under INCUBATION and is not currently included
* in the automated EclipseLink build. The API in this code may change, or
* may never be included in the product. Please provide feedback through mailing
* lists or the bug database.
******************************************************************************/
package example;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.RelationalDescriptor;
import org.eclipse.persistence.dynamic.DynamicClassLoader;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.indirection.IndirectList;
import org.eclipse.persistence.internal.jpa.CMP3Policy;
import org.eclipse.persistence.jpa.JpaHelper;
import org.eclipse.persistence.mappings.DirectToFieldMapping;
import org.eclipse.persistence.mappings.ManyToManyMapping;
import org.eclipse.persistence.mappings.OneToManyMapping;
import org.eclipse.persistence.mappings.OneToOneMapping;
import org.eclipse.persistence.sessions.server.Server;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.tools.schemaframework.SchemaManager;
public class SimpleDynamicMap_WithRelationships_JPAExample {
/**
*
*/
public static void main(String[] args) throws Exception {
SimpleDynamicMap_WithRelationships_JPAExample example = new SimpleDynamicMap_WithRelationships_JPAExample();
EntityManagerFactory emf = example.createEMF();
try {
example.createDynamicTypes(emf);
example.persistDynamicInstances(emf);
example.queryDynamicInstances(emf);
example.updateDyanmicInstances(emf);
example.deleteDynamicInstances(emf);
example.removeDynamicTypes(emf);
} finally {
emf.close();
}
}
public static final String TYPE_A = "SimpleTypeA";
public static final String TYPE_B = "SimpleTypeB";
public static final String TYPE_C = "SimpleTypeC";
/**
* Create the following dynamic types
*
* SimpleTypeA -> DYNAMIC_A int id -> A_ID (PK) String value -> VALUE B bs
* (1:M)) mappedBy B.a List<C> cs (M:M)-> A_C_JOIN(A_ID, C_ID)
*
* SimpleTypeB -> DYNAMIC_B int id -> B_ID (PK) A a (M:1) -> A_FK (FK)
* Calendar value -> VALUE
*
* SimpleTypeC -> DYNAMIC_C int id -> C_ID byte[] value -> LOB
*/
public void createDynamicTypes(EntityManagerFactory emf) throws ClassNotFoundException {
ServerSession session = (ServerSession) JpaHelper.getServerSession(emf);
DynamicClassLoader dcl = DynamicClassLoader.lookup(session);
Class aClass = dcl.createDynamicClass("model." + TYPE_A, DynamicMapEntity.class);
Class bClass = dcl.createDynamicClass("model." + TYPE_B, DynamicMapEntity.class);
Class cClass = dcl.createDynamicClass("model." + TYPE_C, DynamicMapEntity.class);
// Create SimpleTypeA with direct mappings
RelationalDescriptor descriptorA = new RelationalDescriptor();
descriptorA.setJavaClass(aClass);
descriptorA.setTableName("DYNAMIC_A");
descriptorA.setPrimaryKeyFieldName("A_ID");
descriptorA.setCMPPolicy(new CMP3Policy());
DirectToFieldMapping mapping = (DirectToFieldMapping) descriptorA.addDirectMapping("id", "A_ID");
mapping.setAttributeAccessor(new ValueAccessor(mapping, Integer.class));
mapping = (DirectToFieldMapping) descriptorA.addDirectMapping("value", "VALUE");
mapping.setAttributeAccessor(new ValueAccessor(mapping, String.class));
// Create SimpleTypeB with direct mappings
RelationalDescriptor descriptorB = new RelationalDescriptor();
descriptorB.setJavaClass(bClass);
descriptorB.setTableName("DYNAMIC_B");
descriptorB.setPrimaryKeyFieldName("B_ID");
descriptorB.setCMPPolicy(new CMP3Policy());
mapping = (DirectToFieldMapping) descriptorB.addDirectMapping("id", "B_ID");
mapping.setAttributeAccessor(new ValueAccessor(mapping, Integer.class));
mapping = (DirectToFieldMapping) descriptorB.addDirectMapping("value", "VALUE");
mapping.setAttributeAccessor(new ValueAccessor(mapping, Calendar.class));
// Create SimpleTypeC with direct mappings
RelationalDescriptor descriptorC = new RelationalDescriptor();
descriptorC.setJavaClass(cClass);
descriptorC.setTableName("DYNAMIC_C");
descriptorC.setPrimaryKeyFieldName("C_ID");
descriptorC.setCMPPolicy(new CMP3Policy());
mapping = (DirectToFieldMapping) descriptorC.addDirectMapping("id", "C_ID");
mapping.setAttributeAccessor(new ValueAccessor(mapping, Integer.class));
mapping = (DirectToFieldMapping) descriptorC.addDirectMapping("value", "VALUE");
mapping.setAttributeAccessor(new ValueAccessor(mapping, byte[].class));
// Add 1:M: A.bs
OneToManyMapping aToBMapping = new OneToManyMapping();
aToBMapping.setAttributeName("bs");
aToBMapping.setReferenceClass(bClass);
aToBMapping.useTransparentList();
aToBMapping.setCascadeAll(true);
aToBMapping.setAttributeAccessor(new ValueAccessor(aToBMapping, IndirectList.class));
aToBMapping.addTargetForeignKeyFieldName("A_FK", "A_ID");
descriptorA.addMapping(aToBMapping);
// Add M:M: A.cs
ManyToManyMapping aToCMapping = new ManyToManyMapping();
aToCMapping.setAttributeName("cs");
aToCMapping.setReferenceClass(cClass);
aToCMapping.useTransparentList();
aToCMapping.setCascadeAll(true);
aToCMapping.setAttributeAccessor(new ValueAccessor(aToCMapping, IndirectList.class));
aToCMapping.setRelationTableName("DYNAMIC_JOIN_A_C");
aToCMapping.addSourceRelationKeyFieldName("A_ID", "A_ID");
aToCMapping.addTargetRelationKeyFieldName("C_ID", "C_ID");
descriptorA.addMapping(aToCMapping);
// Add 1:1: B.a (fetch=EAGER)
OneToOneMapping bToAMapping = new OneToOneMapping();
bToAMapping.setAttributeName("a");
bToAMapping.setReferenceClass(aClass);
bToAMapping.dontUseIndirection();
bToAMapping.setAttributeAccessor(new ValueAccessor(bToAMapping, descriptorA.getJavaClass()));
bToAMapping.addForeignKeyFieldName("A_FK", "A_ID");
descriptorB.addMapping(bToAMapping);
List<ClassDescriptor> descriptors = new ArrayList<ClassDescriptor>();
descriptors.add(descriptorA);
descriptors.add(descriptorB);
descriptors.add(descriptorC);
session.addDescriptors(descriptors);
createTables(emf);
}
/**
* Replace all of the tables.
*
* @param emf
*/
private void createTables(EntityManagerFactory emf) {
SchemaManager sm = new SchemaManager(JpaHelper.getServerSession(emf));
try {
sm.dropTable(DynamicMapHelper.getDescriptor(emf, TYPE_B).getTableName());
sm.dropTable(((ManyToManyMapping) DynamicMapHelper.getDescriptor(emf, TYPE_A).getMappingForAttributeName("cs")).getRelationTableName());
sm.dropTable(DynamicMapHelper.getDescriptor(emf, TYPE_A).getTableName());
sm.dropTable(DynamicMapHelper.getDescriptor(emf, TYPE_C).getTableName());
} catch (DatabaseException dbe) {
}
sm.createDefaultTables(false);
}
public void persistDynamicInstances(EntityManagerFactory emf) {
System.out.println("*** START: SimpleDynamicMap_WithRelationships_JPAExample.persistDynamicInstances ***");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Map entityA = DynamicMapHelper.newInstance(emf, TYPE_A);
entityA.put("id", 1);
entityA.put("value", "value-1");
Map entityB = DynamicMapHelper.newInstance(emf, TYPE_B);
entityB.put("id", 1);
entityB.put("a", entityA);
entityB.put("value", Calendar.getInstance());
// Add entityB to A's 1:M
List bs = new ArrayList();
bs.add(entityB);
entityA.put("bs", bs);
Map entityC1 = DynamicMapHelper.newInstance(emf, TYPE_C);
entityC1.put("id", 1);
entityC1.put("value", "TEST DATA".getBytes());
Map entityC2 = DynamicMapHelper.newInstance(emf, TYPE_C);
entityC2.put("id", 2);
entityC2.put("value", "TEST DATA FOR C2".getBytes());
// Add entityB to A's 1:M
List cs = new ArrayList();
cs.add(entityC1);
cs.add(entityC2);
entityA.put("cs", cs);
em.persist(entityC1);
em.persist(entityC2);
em.persist(entityB);
em.persist(entityA);
em.getTransaction().commit();
em.close();
JpaHelper.getServerSession(emf).getIdentityMapAccessor().initializeAllIdentityMaps();
}
public List<Map> queryDynamicInstances(EntityManagerFactory emf) {
System.out.println("*** START: SimpleDynamicMap_WithRelationships_JPAExample.queryDynamicInstances ***");
EntityManager em = emf.createEntityManager();
try {
List<Map> as = em.createQuery("SELECT s FROM SimpleTypeA s WHERE s.value LIKE 'v%'").getResultList();
return as;
} finally {
em.close();
}
}
public void updateDyanmicInstances(EntityManagerFactory emf) {
System.out.println("*** START: SimpleDynamicMap_WithRelationships_JPAExample.updateDyanmicInstances ***");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Map entityA = (Map) em.find(DynamicMapHelper.getClass(emf, TYPE_A), 1);
entityA.put("value", "value-1+");
Map entityB = DynamicMapHelper.newInstance(emf, TYPE_B);
entityB.put("id", 2);
entityB.put("a", entityA);
entityB.put("value", Calendar.getInstance());
em.persist(entityB);
List<Map<String, Object>> bs = (List<Map<String, Object>>) entityA.get("bs");
bs.add(entityB);
entityB.put("a", entityA);
em.getTransaction().commit();
em.close();
}
public void deleteDynamicInstances(EntityManagerFactory emf) {
System.out.println("*** START: SimpleDynamicMap_WithRelationships_JPAExample.deleteDynamicInstances ***");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Map entityA = (Map) em.find(DynamicMapHelper.getClass(emf, TYPE_A), 1);
em.remove(entityA);
em.getTransaction().commit();
em.close();
}
/**
* Remove the persistent type from the meta-model and clear the cache.
*
* Application should ensure there are no operations active against the
* persistence context using this type when it is being removed.
*/
public void removeDynamicTypes(EntityManagerFactory emf) {
Server session = JpaHelper.getServerSession(emf);
Class classA = DynamicMapHelper.getClass(emf, TYPE_A);
Class classB = DynamicMapHelper.getClass(emf, TYPE_B);
Class classC = DynamicMapHelper.getClass(emf, TYPE_C);
// Must clear the cache first
session.getIdentityMapAccessor().initializeIdentityMap(classA);
session.getIdentityMapAccessor().initializeIdentityMap(classB);
session.getIdentityMapAccessor().initializeIdentityMap(classC);
session.getDescriptors().remove(classA);
session.getProject().getOrderedDescriptors().remove(session.getProject().getAliasDescriptors().remove(TYPE_A));
session.getDescriptors().remove(classB);
session.getProject().getOrderedDescriptors().remove(session.getProject().getAliasDescriptors().remove(TYPE_B));
session.getDescriptors().remove(classC);
session.getProject().getOrderedDescriptors().remove(session.getProject().getAliasDescriptors().remove(TYPE_C));
}
/**
* Create a database session with no descriptors. The property values used
* to populate the DatabaseLogin object are loaded from a 'test.properties'
* file stored in the user's home.
*
* The test.properties file could appear as:
*
* eclipselink.jdbc.driver=oracle.jdbc.OracleDriver
* eclipselink.jdbc.url=jdbc:oracle:thin:@localhost:1521:ORCL
* eclipselink.jdbc.user=scott eclipselink.jdbc.pwd=tiger
* eclipselink.target-
* database=org.eclipse.persistence.platform.database.OraclePlatform
*
*
* @return newly created and logged in Session
*/
public EntityManagerFactory createEMF() {
Properties testProps = new Properties();
FileInputStream in = null;
try {
in = new FileInputStream("test.properties");
testProps.load(in);
} catch (FileNotFoundException e) {
} catch (IOException e) {
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
return Persistence.createEntityManagerFactory("dynamic-simple-map", testProps);
}
}