use of org.eclipse.persistence.mappings.OneToManyMapping in project eclipselink by eclipse-ee4j.
the class ObjectPersistenceRuntimeXMLProject method buildOneToManyMappingMappingDescriptor.
protected ClassDescriptor buildOneToManyMappingMappingDescriptor() {
XMLDescriptor descriptor = new XMLDescriptor();
descriptor.setJavaClass(OneToManyMapping.class);
descriptor.getInheritancePolicy().setParentClass(CollectionMapping.class);
XMLCompositeCollectionMapping sourceToTargetKeyFieldAssociationsMapping = new XMLCompositeCollectionMapping();
sourceToTargetKeyFieldAssociationsMapping.setReferenceClass(Association.class);
// Handle translation of foreign key associations to hashtables.
sourceToTargetKeyFieldAssociationsMapping.setAttributeAccessor(new AttributeAccessor() {
@Override
public Object getAttributeValueFromObject(Object object) {
List<DatabaseField> sourceFields = ((OneToManyMapping) object).getSourceKeyFields();
List<DatabaseField> targetFields = ((OneToManyMapping) object).getTargetForeignKeyFields();
List<Association> associations = new ArrayList<>(sourceFields.size());
for (int index = 0; index < sourceFields.size(); index++) {
associations.add(new Association(targetFields.get(index), sourceFields.get(index)));
}
return associations;
}
@Override
public void setAttributeValueInObject(Object object, Object value) {
OneToManyMapping mapping = (OneToManyMapping) object;
@SuppressWarnings({ "unchecked" }) List<Association> associations = (List<Association>) value;
mapping.setSourceKeyFields(NonSynchronizedVector.newInstance(associations.size()));
mapping.setTargetForeignKeyFields(NonSynchronizedVector.newInstance(associations.size()));
Iterator<Association> iterator = associations.iterator();
while (iterator.hasNext()) {
Association association = iterator.next();
mapping.getSourceKeyFields().add((DatabaseField) association.getValue());
mapping.getTargetForeignKeyFields().add((DatabaseField) association.getKey());
}
}
});
sourceToTargetKeyFieldAssociationsMapping.setAttributeName("sourceToTargetKeyFieldAssociations");
sourceToTargetKeyFieldAssociationsMapping.setXPath(getSecondaryNamespaceXPath() + "target-foreign-key/" + getSecondaryNamespaceXPath() + "field-reference");
descriptor.addMapping(sourceToTargetKeyFieldAssociationsMapping);
XMLDirectMapping relationshipPartnerAttributeNameMapping = new XMLDirectMapping();
relationshipPartnerAttributeNameMapping.setAttributeName("relationshipPartnerAttributeName");
relationshipPartnerAttributeNameMapping.setGetMethodName("getRelationshipPartnerAttributeName");
relationshipPartnerAttributeNameMapping.setSetMethodName("setRelationshipPartnerAttributeName");
relationshipPartnerAttributeNameMapping.setXPath(getPrimaryNamespaceXPath() + "bidirectional-target-attribute/text()");
descriptor.addMapping(relationshipPartnerAttributeNameMapping);
XMLDirectMapping usesBatchReadingMapping = new XMLDirectMapping();
usesBatchReadingMapping.setAttributeName("usesBatchReading");
usesBatchReadingMapping.setGetMethodName("shouldUseBatchReading");
usesBatchReadingMapping.setSetMethodName("setUsesBatchReading");
usesBatchReadingMapping.setXPath(getPrimaryNamespaceXPath() + "batch-reading/text()");
usesBatchReadingMapping.setNullValue(Boolean.FALSE);
descriptor.addMapping(usesBatchReadingMapping);
XMLCompositeObjectMapping containerPolicyMapping = new XMLCompositeObjectMapping();
containerPolicyMapping.setAttributeName("collectionPolicy");
containerPolicyMapping.setGetMethodName("getContainerPolicy");
containerPolicyMapping.setSetMethodName("setContainerPolicy");
containerPolicyMapping.setReferenceClass(ContainerPolicy.class);
containerPolicyMapping.setXPath(getPrimaryNamespaceXPath() + "container");
descriptor.addMapping(containerPolicyMapping);
XMLCompositeObjectMapping indirectionPolicyMapping = new XMLCompositeObjectMapping();
indirectionPolicyMapping.setReferenceClass(IndirectionPolicy.class);
// Handle translation of NoIndirectionPolicy -> null.
indirectionPolicyMapping.setAttributeAccessor(new AttributeAccessor() {
@Override
public Object getAttributeValueFromObject(Object object) {
IndirectionPolicy policy = ((ForeignReferenceMapping) object).getIndirectionPolicy();
if (policy instanceof NoIndirectionPolicy) {
return null;
}
return policy;
}
@Override
public void setAttributeValueInObject(Object object, Object value) {
IndirectionPolicy policy = (IndirectionPolicy) value;
if (value == null) {
policy = new NoIndirectionPolicy();
}
((ForeignReferenceMapping) object).setIndirectionPolicy(policy);
}
});
indirectionPolicyMapping.setAttributeName("indirectionPolicy");
indirectionPolicyMapping.setXPath(getPrimaryNamespaceXPath() + "indirection");
descriptor.addMapping(indirectionPolicyMapping);
XMLCompositeObjectMapping selectionQueryMapping = new XMLCompositeObjectMapping();
selectionQueryMapping.setAttributeName("selectionQuery");
selectionQueryMapping.setGetMethodName("getSelectionQuery");
selectionQueryMapping.setSetMethodName("setSelectionQuery");
selectionQueryMapping.setReferenceClass(ReadQuery.class);
selectionQueryMapping.setXPath(getPrimaryNamespaceXPath() + "selection-query");
descriptor.addMapping(selectionQueryMapping);
// delete-all query
return descriptor;
}
use of org.eclipse.persistence.mappings.OneToManyMapping in project eclipselink by eclipse-ee4j.
the class ReadAllQuery method conformResult.
/**
* INTERNAL:
* Conform the result if specified.
*/
protected Object conformResult(Object result, UnitOfWorkImpl unitOfWork, AbstractRecord arguments, boolean buildDirectlyFromRows) {
Expression selectionCriteria = getSelectionCriteria();
if (selectionCriteria != null) {
ExpressionBuilder builder = getSelectionCriteria().getBuilder();
builder.setSession(unitOfWork.getRootSession(null));
builder.setQueryClass(getReferenceClass());
if (getQueryMechanism().isExpressionQueryMechanism() && selectionCriteria.isLogicalExpression()) {
// bug #526546
if (builder.derivedExpressions != null) {
for (Expression e : builder.derivedExpressions) {
if (e.isQueryKeyExpression() && ((QueryKeyExpression) e).shouldQueryToManyRelationship()) {
DatabaseMapping mapping = ((QueryKeyExpression) e).getMapping();
if (mapping.isOneToManyMapping()) {
OneToManyMapping otm = (OneToManyMapping) mapping;
Expression join = otm.buildSelectionCriteria();
selectionCriteria = selectionCriteria.and(join);
}
}
}
}
}
}
// If the query is redirected then the collection returned might no longer
// correspond to the original container policy. CR#2342-S.M.
ContainerPolicy cp;
if (getRedirector() != null) {
cp = ContainerPolicy.buildPolicyFor(result.getClass());
} else {
cp = getContainerPolicy();
}
// This code is now a great deal different... For one, registration is done
// as part of conforming. Also, this should only be called if one actually
// is conforming.
// First scan the UnitOfWork for conforming instances.
// This will walk through the entire cache of registered objects.
// Let p be objects from result not in the cache.
// Let c be objects from cache.
// Presently p intersect c = empty set, but later p subset c.
// By checking cache now doesConform will be called p fewer times.
Map<Object, Object> indexedInterimResult = unitOfWork.scanForConformingInstances(selectionCriteria, getReferenceClass(), arguments, this);
Cursor cursor = null;
// In the case of cursors just conform/register the initially read collection.
if (cp.isCursorPolicy()) {
cursor = (Cursor) result;
cp = ContainerPolicy.buildPolicyFor(ClassConstants.Vector_class);
// In nested UnitOfWork session might have been session of the parent.
cursor.setSession(unitOfWork);
result = cursor.getObjectCollection();
// for later incremental conforming...
cursor.setInitiallyConformingIndex(indexedInterimResult);
cursor.setSelectionCriteriaClone(getSelectionCriteria());
cursor.setTranslationRow(arguments);
}
// Now conform the result from the database.
// Remove any deleted or changed objects that no longer conform.
// Deletes will only work for simple queries, queries with or's or anyof's may not return
// correct results when untriggered indirection is in the model.
List fromDatabase = null;
// result is just a vector, not a container of wrapped originals.
if (buildDirectlyFromRows) {
List<AbstractRecord> rows = (List<AbstractRecord>) result;
int size = rows.size();
fromDatabase = new ArrayList(size);
for (int index = 0; index < size; index++) {
AbstractRecord row = rows.get(index);
// null is placed in the row collection for 1-m joining to filter duplicate rows.
if (row != null) {
Object clone = conformIndividualResult(buildObject(row), unitOfWork, arguments, getSelectionCriteria(), indexedInterimResult);
if (clone != null) {
fromDatabase.add(clone);
}
}
}
} else {
fromDatabase = new ArrayList(cp.sizeFor(result));
AbstractSession sessionToUse = unitOfWork.getParent();
for (Object iter = cp.iteratorFor(result); cp.hasNext(iter); ) {
Object object = cp.next(iter, sessionToUse);
Object clone = conformIndividualResult(registerIndividualResult(object, null, unitOfWork, null, null), unitOfWork, arguments, getSelectionCriteria(), indexedInterimResult);
if (clone != null) {
fromDatabase.add(clone);
}
}
}
// Now add the unwrapped conforming instances into an appropriate container.
// Wrapping is done automatically.
// Make sure a vector of exactly the right size is returned.
Object conformedResult = cp.containerInstance(indexedInterimResult.size() + fromDatabase.size());
for (Iterator<Object> enumtr = indexedInterimResult.values().iterator(); enumtr.hasNext(); ) {
Object eachClone = enumtr.next();
cp.addInto(eachClone, conformedResult, unitOfWork);
}
int size = fromDatabase.size();
for (int index = 0; index < size; index++) {
Object eachClone = fromDatabase.get(index);
cp.addInto(eachClone, conformedResult, unitOfWork);
}
if (cursor != null) {
cursor.setObjectCollection((List) conformedResult);
// the parent UnitOfWork.
if (unitOfWork.isNestedUnitOfWork()) {
for (Object clone : cursor.getObjectCollection()) {
indexedInterimResult.put(clone, clone);
}
}
return cursor;
} else {
return conformedResult;
}
}
use of org.eclipse.persistence.mappings.OneToManyMapping in project eclipselink by eclipse-ee4j.
the class AddTargetCustomizer method customize.
@Override
public void customize(ClassDescriptor descriptor) {
OneToManyMapping dealers = (OneToManyMapping) descriptor.getMappingForAttributeName("dealers");
DataModifyQuery query = new DataModifyQuery();
query.setName("CustomAddTargetQuery");
SQLUpdateStatement statement = new SQLUpdateStatement();
statement.setTable(descriptor.getPrimaryKeyFields().get(0).getTable());
// Build where clause expression.
Expression whereClause = null;
Expression builder = new ExpressionBuilder();
int size = dealers.getSourceKeyFields().size();
for (int index = 0; index < size; index++) {
DatabaseField key = dealers.getSourceKeyFields().get(index);
Expression expression = builder.getField(key).equal(builder.getParameter(dealers.getTargetForeignKeyFields().get(index)));
whereClause = expression.and(whereClause);
}
statement.setWhereClause(whereClause);
AbstractRecord modifyRow = new DatabaseRecord();
modifyRow.add(descriptor.getMappingForAttributeName("firstName").getField(), null);
statement.setModifyRow(modifyRow);
query.setSQLStatement(statement);
dealers.setCustomAddTargetQuery(query);
}
use of org.eclipse.persistence.mappings.OneToManyMapping in project eclipselink by eclipse-ee4j.
the class StoredProcedureGenerator method generateMappingStoredProcedures.
/**
* INTERNAL: Generates the mapping stored procedures for this descriptor.
* currently only 1:1 and 1:M are supported
*/
protected Hashtable<String, Hashtable<String, StoredProcedureDefinition>> generateMappingStoredProcedures(ClassDescriptor descriptor) {
Vector<DatabaseMapping> mappings = descriptor.getMappings();
Hashtable<String, Hashtable<String, StoredProcedureDefinition>> mappingSP = new Hashtable<>();
Hashtable<String, StoredProcedureDefinition> mappingTable;
for (Enumeration<DatabaseMapping> enumtr = mappings.elements(); enumtr.hasMoreElements(); ) {
mappingTable = new Hashtable<>();
DatabaseMapping mapping = enumtr.nextElement();
if (mapping.isOneToManyMapping()) {
if (!getSession().getPlatform().isOracle()) {
// reads not supported in oracle
mappingTable.put("1MREAD", generateOneToManyMappingReadProcedure((OneToManyMapping) mapping));
}
if (mapping.isPrivateOwned()) {
// generate delete all for 1:M query
mappingTable.put("1MDALL", generateOneToManyMappingDeleteAllProcedure((OneToManyMapping) mapping));
}
mappingSP.put(mapping.getAttributeName(), mappingTable);
}
}
return mappingSP;
}
use of org.eclipse.persistence.mappings.OneToManyMapping in project eclipselink by eclipse-ee4j.
the class AdvancedJPAJunitTest method testValuePKListMissingElement.
public void testValuePKListMissingElement() {
if (isOnServer()) {
return;
}
EntityManager em = createEntityManager();
beginTransaction(em);
Jigsaw jigsaw = new Jigsaw();
for (int i = 1; i < 11; i++) {
jigsaw.addPiece(new JigsawPiece(i));
}
em.persist(jigsaw);
commitTransaction(em);
try {
AbstractSession session = (AbstractSession) JpaHelper.getEntityManager(em).getActiveSession();
ClassDescriptor descriptor = session.getDescriptorForAlias("Jigsaw");
Jigsaw foundJigsaw = em.find(Jigsaw.class, jigsaw.getId());
int expectedNumber = foundJigsaw.getPieces().size();
OneToManyMapping mapping = (OneToManyMapping) descriptor.getMappingForAttributeName("pieces");
Object[] pks = mapping.buildReferencesPKList(foundJigsaw, mapping.getAttributeValueFromObject(foundJigsaw), session);
assertEquals("PK list is of incorrect size", expectedNumber, pks.length);
session.getIdentityMapAccessor().invalidateObject(foundJigsaw.getPieces().get(2));
DatabaseRecord fks = new DatabaseRecord();
for (DatabaseField field : mapping.getSourceKeyFields()) {
fks.add(field, descriptor.getObjectBuilder().extractValueFromObjectForField(foundJigsaw, field, session));
}
mapping.writeFromObjectIntoRow(foundJigsaw, fks, session, DatabaseMapping.WriteType.UNDEFINED);
List<JigsawPiece> elements = (List<JigsawPiece>) mapping.valueFromPKList(pks, fks, session);
assertEquals("ValueFromPKList returned list of different size from actual entity.", expectedNumber, elements.size());
assertFalse("Collection contains unexpected null", elements.contains(null));
for (JigsawPiece element : elements) {
assertTrue("Entity id " + element.getId() + " not found in ValueFromPKList list", foundJigsaw.getPieces().contains(element));
}
em.refresh(foundJigsaw.getPieces().get(2));
session.getIdentityMapAccessor().invalidateObject(foundJigsaw.getPieces().get(5));
elements = (List<JigsawPiece>) mapping.valueFromPKList(pks, fks, session);
assertEquals("ValueFromPKList returned list of different size from actual entity.", expectedNumber, elements.size());
assertFalse("Collection contains unexpected null", elements.contains(null));
for (JigsawPiece element : elements) {
assertTrue("Entity id " + element.getId() + " not found in ValueFromPKList list", foundJigsaw.getPieces().contains(element));
}
} finally {
try {
beginTransaction(em);
em.remove(jigsaw);
commitTransaction(em);
} catch (Exception e) {
} finally {
closeEntityManager(em);
}
}
}
Aggregations