如何在 JPA 中构造插入查询

Posted

技术标签:

【中文标题】如何在 JPA 中构造插入查询【英文标题】:How to construct an insert query in JPA 【发布时间】:2017-09-06 22:32:58 【问题描述】:

我正在尝试将数据插入到具有列 (NAME, VALUE)

的表中
Query query = em.createQuery("INSERT INTO TestDataEntity (NAME, VALUE) VALUES (:name, :value)");
query.setParameter("name", name);
query.setParameter("value", value);
query.executeUpdate();

并得到以下异常:

ERROR org.hibernate.hql.internal.ast.ErrorCounter - line 1:42: unexpected token: VALUES 

另外,我也无法使用本机查询插入记录:

Query query = em.createNativeQuery("INSERT INTO TEST_DATA (NAME, VALUE) VALUES (:name, :value);");
query.setParameter("name", name);
query.setParameter("value", value);
query.executeUpdate();

正在抛出另一个异常:

javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute statement

问题是:

查询字符串有什么问题?

非常感谢。

【问题讨论】:

在 JPA 中设置对象并使用 entitymanagers persist 方法来保存它们 @Jens:如果我像上面那样选择或更新或删除,一切都按原样执行,那么这个查询有什么问题? 也许this 会回答您的问题(Google jpa 插入) @Jens:感谢您的链接。我在想,也许休眠中没有插入,但我也无法通过本机查询插入记录:(。 如果你使用em.createNativeQuery就可以 【参考方案1】:

我解决了这个问题。

根据this,

JPA 中没有 INSERT 语句。

但是我可以用原生查询来解决这个问题:我错误地放了一个多余的 ;在查询结束时,因此通过删除它解决了问题。

【讨论】:

【参考方案2】:

我发现了两个作者在本机查询中使用插入的示例(first 和second)。那么,您的查询可能是:

Query query = em.createQuery("INSERT INTO TestDataEntity (NAME, VALUE) VALUES (?, ?)");
query.setParameter(1, name);
query.setParameter(2, value);
query.executeUpdate();

试试这个。

【讨论】:

正如我在回答中提到的,我能够使用本机查询将数据插入到表中。还有另一个问题:多余的“;”是在查询的末尾,这导致了问题。删除它后,本机查询按预期工作。无论如何,非常感谢您的回答。【参考方案3】:

我可以使用下面的方法做到这一点 - 我只有一个表名 Bike ,其中包含 2 个字段 id 和 name 。我使用以下将其插入数据库。

Query query = em.createNativeQuery("INSERT INTO Bike (id, name) VALUES (:id , :name);");
em.getTransaction().begin();
query.setParameter("id", "5");
query.setParameter("name", "Harley");
query.executeUpdate();
em.getTransaction().commit();

【讨论】:

我怀疑你是否真的可以毫无例外地运行在你的情况下编写的代码,因为有多余的分号 - ';'这会阻止成功运行。 引起:java.lang.IllegalStateException:不允许在共享EntityManager 上创建事务- 改用Spring 事务或EJB CMT。开始使用 begin() 和 commit() 时出现上述异常。 第一个分号 - 查询结束,下一个是结束语句。这实际上对我有用。【参考方案4】:

对于手动创建的查询,我们可以使用 EntityManager#createNativeQuery 方法。它允许我们创建任何类型的 SQL 查询,而不仅仅是 JPA 支持的那些。让我们向我们的存储库类添加一个新方法:

@Transactional
public void insertWithQuery(Person person) 
    entityManager.createNativeQuery("INSERT INTO person (id, first_name, last_name) VALUES (?,?,?)")
      .setParameter(1, person.getId())
      .setParameter(2, person.getFirstName())
      .setParameter(3, person.getLastName())
      .executeUpdate();

使用这种方法,我们需要定义一个包含列名的文字查询并设置它们的对应值。

【讨论】:

以上是关于如何在 JPA 中构造插入查询的主要内容,如果未能解决你的问题,请参考以下文章

在基于查询构造的对象构造中插入数组

如何使用 JPA 1.0 构建一个 JPQL 查询,从多个表中获取数据以克服延迟初始化?

如果属性对 JPA 无效,我如何在数据库中插入默认值

JPA 2.0:如何通过 JPA 提高批量插入的性能

如何使用 JPA 从多列构造模型实例

如何在单个 JDBC 连接中执行多个 JPA 查询