blob: 8431617eab258ccf0672dc8e29f5fb9ee2d20aaf [file] [log] [blame]
/*
* Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// 05/19/2010-2.1 ailitchev - Bug 244124 - Add Nested FetchGroup
package org.eclipse.persistence.testing.tests.jpa.fetchgroups;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Collection;
import java.util.Map;
import jakarta.persistence.EntityManagerFactory;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.VersionLockingPolicy;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.indirection.IndirectContainer;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.internal.queries.AttributeItem;
import org.eclipse.persistence.internal.queries.EntityFetchGroup;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.queries.FetchGroup;
import org.eclipse.persistence.queries.FetchGroupTracker;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.server.Server;
/**
* Test utility to verify the state of entities after they are loaded, copied,
* or detached with respect to a defined FetchGroup.
*
* @author dclarke
* @since EclipseLink 2.1.0
*/
public class FetchGroupAssert {
/**
* Verify that a FetchGroup is valid with respect to the mappings of the
* provided entity class.
*/
public static boolean isValid(FetchGroup fetchGroup, EntityManagerFactory emf, Class<?> entityClass) {
assertNotNull(fetchGroup);
Session session = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession();
ClassDescriptor descriptor = session.getDescriptor(entityClass);
try {
for (Map.Entry<String, AttributeItem> entry : fetchGroup.getItems().entrySet()) {
AttributeItem item = entry.getValue();
DatabaseMapping mapping = descriptor.getMappingForAttributeName(item.getAttributeName());
if (mapping.isForeignReferenceMapping()) {
if (item.getGroup() != null) {
if (!isValid((FetchGroup)item.getGroup(), emf, ((ForeignReferenceMapping) mapping).getReferenceClass())) {
return false;
}
}
} else {
return false;
}
}
} catch (QueryException qe) {
return false;
}
return true;
}
/**
* Verify that the attribute path specified is loaded in the provided entity
*/
public static void assertFetchedAttribute(EntityManagerFactory emf, Object entity, String... attribute) {
assertNotNull("EntityManagerFactory is null", emf);
assertNotNull("Entity is null", entity);
Server session = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession();
assertNotNull("No Server session found for: " + emf, session);
ClassDescriptor desc = session.getClassDescriptor(entity);
assertNotNull("No descriptor found for: " + entity, desc);
Object value = entity;
if (attribute.length > 1) {
String attrName = attribute[1];
if (desc.hasFetchGroupManager()) {
assertTrue("Attribute: '" + attrName + "' not fetched on: " + value, desc.getFetchGroupManager().isAttributeFetched(value, attrName));
}
DatabaseMapping mapping = desc.getMappingForAttributeName(attrName);
value = mapping.getAttributeValueFromObject(value);
if (value instanceof IndirectContainer) {
value = ((IndirectContainer) value).getValueHolder();
}
if (value instanceof ValueHolderInterface) {
ValueHolderInterface vhi = (ValueHolderInterface) value;
assertTrue("ValueHolder for: '" + attrName + "' not instantiated", vhi.isInstantiated());
value = vhi.getValue();
}
String[] tail = new String[attribute.length - 1];
System.arraycopy(attribute, 1, tail, 0, attribute.length - 1);
if (value instanceof Collection<?>) {
for (Object obj : ((Collection<?>) value)) {
assertFetchedAttribute(emf, value, tail);
}
} else {
assertFetchedAttribute(emf, value, tail);
}
} else {
// This is where the actual end attribute in the path is validated.
if (desc.hasFetchGroupManager()) {
assertTrue(desc.getFetchGroupManager().isAttributeFetched(value, attribute[0]));
}
}
}
/**
* Verify that the attribute path is loaded.
*/
public static void assertNotFetchedAttribute(EntityManagerFactory emf, Object entity, String... attribute) {
assertNotNull("EntityManagerFactory is null", emf);
assertNotNull("Entity is null", entity);
Server session = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession();
assertNotNull("No Server session found for: " + emf, session);
ClassDescriptor desc = session.getClassDescriptor(entity);
assertNotNull("No descriptor found for: " + entity, desc);
Object value = entity;
for (int index = 0; index < attribute.length - 1; index++) {
String attrName = attribute[index];
if (desc.hasFetchGroupManager()) {
assertTrue("Attribute: '" + attrName + "' not fetched on: " + value, desc.getFetchGroupManager().isAttributeFetched(value, attrName));
}
DatabaseMapping mapping = desc.getMappingForAttributeName(attrName);
value = mapping.getAttributeValueFromObject(value);
if (value instanceof IndirectContainer) {
value = ((IndirectContainer) value).getValueHolder();
}
if (value instanceof ValueHolderInterface) {
ValueHolderInterface vhi = (ValueHolderInterface) value;
assertTrue("ValueHolder for: '" + attrName + "' not instantiated", vhi.isInstantiated());
value = vhi.getValue();
}
}
}
/**
* Assert that the entity provided has the attributes defined in the
* FetchGroup loaded.
*
*/
public static void assertFetched(EntityManagerFactory emf, Object entity, FetchGroup fetchGroup) {
assertNotNull("Null entity", entity);
assertNotNull("No FetchGroup provided", fetchGroup);
if (!(entity instanceof FetchGroupTracker)) {
System.out.println();
}
assertTrue("Entity does not implement FetchGroupTracker: " + entity, entity instanceof FetchGroupTracker);
FetchGroupTracker tracker = (FetchGroupTracker) entity;
assertNotNull("FetchGroup on entity is null", tracker._persistence_getFetchGroup());
FetchGroup groupToCompare = fetchGroup;
if(!fetchGroup.isEntityFetchGroup()) {
groupToCompare = new EntityFetchGroup(fetchGroup);
}
assertTrue("FetchGroup on entity does not equal provided", tracker._persistence_getFetchGroup().equals(groupToCompare));
Server session = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession();
assertNotNull(session);
ClassDescriptor descriptor = session.getClassDescriptor(entity);
assertNotNull(descriptor);
assertTrue("", descriptor.getJavaClass().isAssignableFrom(entity.getClass()));
for (DatabaseMapping mapping : descriptor.getMappings()) {
if (descriptor.getObjectBuilder().getPrimaryKeyMappings().contains(mapping)) {
assertTrue("PrimaryKey mapping not fetched: " + entity, tracker._persistence_isAttributeFetched(mapping.getAttributeName()));
} else if (descriptor.usesOptimisticLocking() && descriptor.getOptimisticLockingPolicy() instanceof VersionLockingPolicy && ((VersionLockingPolicy) descriptor.getOptimisticLockingPolicy()).getVersionMapping() == mapping) {
assertTrue("Optimistic version mapping not fetched: " + entity, tracker._persistence_isAttributeFetched(mapping.getAttributeName()));
} else if (tracker._persistence_getFetchGroup().containsAttribute(mapping.getAttributeName())) {
assertTrue(tracker._persistence_isAttributeFetched(mapping.getAttributeName()));
// EntityFetchGroup never has nested fetch groups.
/* AttributeItem attrFI = tracker._persistence_getFetchGroup().getItem(mapping.getAttributeName());
if (attrFI.getGroup() != null) {
Object value = mapping.getAttributeValueFromObject(entity);
if (value instanceof IndirectContainer) {
assertTrue(((IndirectContainer) value).isInstantiated());
Collection<?> values = (Collection<?>) value;
for (Object val : values) {
assertFetched(emf, val, (FetchGroup)attrFI.getGroup());
}
return;
}
if (value instanceof ValueHolderInterface) {
assertTrue(((ValueHolderInterface) value).isInstantiated());
value = ((ValueHolderInterface) value).getValue();
}
if (value != null) {
assertFetched(emf, value, (FetchGroup)attrFI.getGroup());
}
}*/
} else { // Should not be fetched
assertFalse(tracker._persistence_isAttributeFetched(mapping.getAttributeName()));
}
}
}
public static void assertDefaultFetched(EntityManagerFactory emf, Object entity) {
assertNotNull("Null entity", entity);
ClassDescriptor descriptor = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession().getClassDescriptor(entity);
assertNotNull("No descriptor found for: " + entity, descriptor);
assertTrue("No FetchGroupManager on: " + descriptor, descriptor.hasFetchGroupManager());
FetchGroup defaultFG = descriptor.getFetchGroupManager().getDefaultFetchGroup();
assertNotNull("No default FetchGroup on: " + descriptor, defaultFG);
assertFetched(emf, entity, defaultFG);
}
public static void assertFetched(EntityManagerFactory emf, Object entity, String fetchGroupName) {
assertNotNull("Null entity", entity);
ClassDescriptor descriptor = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession().getClassDescriptor(entity);
assertNotNull("No descriptor found for: " + entity, descriptor);
assertTrue("No FetchGroupManager on: " + descriptor, descriptor.hasFetchGroupManager());
FetchGroup fg = descriptor.getFetchGroupManager().getFetchGroup(fetchGroupName);
assertNotNull("No FetchGroup named: " + fetchGroupName, fg);
assertFetched(emf, entity, fg);
}
/**
* Verify that the provided entity does not have a FetchGroup configured on
* it.
*/
public static void assertNoFetchGroup(EntityManagerFactory emf, Object entity) {
if (entity instanceof FetchGroupTracker) {
FetchGroupTracker tracker = (FetchGroupTracker) entity;
assertNull("Entity: " + entity + " has: " + tracker._persistence_getFetchGroup(), tracker._persistence_getFetchGroup());
}
}
public static void assertConfig(EntityManagerFactory emf, String entityName, FetchGroup defaultFetchGroup) {
assertConfig(emf, entityName, defaultFetchGroup, 0);
}
public static void assertConfig(EntityManagerFactory emf, String entityName, FetchGroup defaultFetchGroup, int numNamedFetchGroups) {
ClassDescriptor descriptor = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession().getClassDescriptorForAlias(entityName);
assertNotNull("Not descriptor found for: " + entityName, descriptor);
assertConfig(descriptor, defaultFetchGroup, numNamedFetchGroups);
}
public static void assertConfig(ClassDescriptor descriptor, FetchGroup defaultFetchGroup, int numNamedFetchGroups) {
String entityName = descriptor.getAlias();
assertTrue("FetchGroupTracker not implemented by: " + entityName, FetchGroupTracker.class.isAssignableFrom(descriptor.getJavaClass()));
if (defaultFetchGroup == null) {
assertNull("Default FetchGroup not null: " + entityName, descriptor.getFetchGroupManager().getDefaultFetchGroup());
} else {
// assertEquals("Default FetchGroup does not match", defaultFetchGroup, descriptor.getFetchGroupManager().getDefaultFetchGroup());
if(defaultFetchGroup != descriptor.getFetchGroupManager().getDefaultFetchGroup()) {
fail("Default FetchGroup does not match");
}
}
if(numNamedFetchGroups != descriptor.getFetchGroupManager().getFetchGroups().size()) {
fail("Incorrect number of Named FetchGroups: " + entityName);
}
}
public static void assertConfig(ClassDescriptor descriptor, FetchGroup defaultFetchGroup) {
assertConfig(descriptor, defaultFetchGroup, 0);
}
}