2

我正在尝试使用 QueryDSL 为名为“模块”的表实现https://stackoverflow.com/a/16392399/14731。这是我的查询:

String newName = "MyModule";
QModules modules = QModules.modules;
BooleanExpression moduleNotExists = session.subQuery().
    from(modules).where(modules.name.eq(newName)).notExists();
SimpleSubQuery<String> setModuleName = session.subQuery().
    where(moduleNotExists).unique(Expressions.constant(newName));
long moduleId = session.insert(modules).set(modules.name, setModuleName).
    executeWithKey(modules.id);

我希望这会转化为:

insert into modules(name)
select 'MyModule'
where not exists
(select 1 from modules where modules.name = 'MyModule')

相反,我得到:

NULL not allowed for column "NAME"; SQL statement:
   insert into MODULES (NAME)
   values ((select ?
   from dual
   where not exists (select 1
   from MODULES MODULES
   where MODULES.NAME = ?)))

其中?等于MyModule

  1. 为什么 QueryDSL 插入from dual?我希望它from完全省略。
  2. 如何修复此查询?
4

1 回答 1

3

对于插入选择表单使用

columns(...).select(...)

但是您的错误表明 INSERT 子句是有效的,但在语义上不是您想要的。

使用InsertClause.set(...)你没有得到你想要的条件插入。

换句话说

columns(...).select(...)

您将完整的结果集映射到一个 INSERT 模板中,并且不会为空结果集插入任何行,但是使用

set(...)

您将查询结果映射到 INSERT 模板的单个列,空值将用于空结果。

于 2013-09-17T19:41:28.960 回答