V HQL používáte názvy tříd a polí a v SQL názvy tabulek a sloupců. Takže byste neměli vidět podtržítka (alespoň ne mnoho) v dotazech HQL. Je také nepravděpodobné, že by to byl faktor, ale dotazy HQL se spouštějí z findAll a ty běží z executeQuery může být mírně odlišná. Nepamatuji si, jaký je v tom rozdíl, ale executeQuery je ten správný bez ohledu na to, o kterou doménovou třídu jde.
Je těžké to zjistit, aniž byste viděli třídy domén, ale vypadá to jako artifact_id by měl být artifact.id a document_id by měl být document.id . A protože máte instanci dokumentu, je vhodnější porovnávat objekty a ne jejich ID. Nakonec předpokládám, že active je booleovská vlastnost, takže potřebuje booleovskou hodnotu a ne 1 nebo 0. Takže když to dáme dohromady, můj nejlepší odhad je, že to je to, co chcete:
def artifacts = Artifact.executeQuery(
"FROM Artifact WHERE id NOT IN ( " +
"SELECT artifact.id FROM Classification " +
"WHERE active = :active) AND document =:doc",
[active: true, doc:document],
[max:limit, offset:startIndex])
Všimněte si, že musíte oddělit hodnoty parametrů z ovládacích prvků stránkování do dvou map.