@Override
	protected boolean isEquivalent(DataType dataType, DataTypeConflictHandler handler) {
		if (dataType == this) {
			return true;
		}
		if (!(dataType instanceof UnionInternal union)) {
			return false;
		}

		validate(lock);
		if (resolving) { // actively resolving children
			if (dataType.getUniversalID().equals(getUniversalID())) {
				return true;
			}
			return DataTypeUtilities.equalsIgnoreConflict(getPathName(), dataType.getPathName());
		}

		Boolean isEquivalent = dataMgr.getCachedEquivalence(this, dataType);
		if (isEquivalent != null) {
			return isEquivalent;
		}

		try {
			isEquivalent = false;

			if (handler != null &&
				ConflictResult.USE_EXISTING == handler.resolveConflict(union, this)) {
				// treat this type as equivalent if existing type will be used
				isEquivalent = true;
				return true;
			}

			if (getStoredPackingValue() != union.getStoredPackingValue() ||
				getStoredMinimumAlignment() != union.getStoredMinimumAlignment()) {
				// rely on component match instead of checking length 
				// since dynamic component sizes could affect length
				return false;
			}
			DataTypeComponent[] myComps = getComponents();
			DataTypeComponent[] otherComps = union.getComponents();
			if (myComps.length != otherComps.length) {
				return false;
			}
			if (handler != null) {
				handler = handler.getSubsequentHandler();
			}
			for (int i = 0; i < myComps.length; i++) {
				if (!DataTypeComponentDB.isEquivalent(myComps[i], otherComps[i], handler)) {
					return false;
				}
			}
			isEquivalent = true;
		}
		finally {
			dataMgr.putCachedEquivalence(this, dataType, isEquivalent);
		}
		return true;
	}
Perform union member repack.
Perform lazy update of stored alignment introduced with v5 adapter.
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/UnionDB.java