Sua solução de trabalho é boa (e semelhante ao que já usei antes ). Se você deseja vincular apenas uma vez, pode usar uma visualização CTE ou inline para fornecer o valor à consulta real:
WITH CTE AS (
SELECT ? AS REAL_VALUE FROM DUAL
)
SELECT C.* -- but not * really, list all the columns
FROM CTE
JOIN CUSTOMERS C
ON (CTE.REAL_VALUE IS NULL AND C.CUSTOMER_ID IS NULL)
OR C.CUSTOMER_ID = CTE.REAL_VALUE
Portanto, há apenas um espaço reservado para vincular.
Eu realmente não vejo um problema com uma ramificação no lado Java, a menos que sua consulta real seja muito mais complicada e leve a uma duplicação significativa.