使用 Spring JPA 从序列中获取 nextval 的查询

Posted

技术标签:

【中文标题】使用 Spring JPA 从序列中获取 nextval 的查询【英文标题】:Query to get nextval from sequence with Spring JPA 【发布时间】:2019-07-27 02:56:26 【问题描述】:

我有一个存储库,我正在尝试从序列中获取下一个值。我需要参数化的序列名称。

存储库查询看起来像:

@Query(value = "SELECT ?1.NEXTVAL from dual;", nativeQuery = true) String getSeqID(@Param("seqName") String seqName);

但是,我遇到了以下异常:

org.hibernate.QueryException: JPA-style positional param was not an integral ordinal
    at org.hibernate.engine.query.spi.ParameterParser.parse(ParameterParser.java:187) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.ParamLocationRecognizer.parseLocations(ParamLocationRecognizer.java:59) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.internal.NativeQueryInterpreterStandardImpl.getParameterMetadata(NativeQueryInterpreterStandardImpl.java:34) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.QueryPlanCache.getSQLParameterMetadata(QueryPlanCache.java:125) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]

【问题讨论】:

为什么需要序列中的 nextval? 这是功能需求,需要检索序列中的 nextval,以便将其用作员工代码。 【参考方案1】:
package br.com.mypackage.projectname.repository;

import java.math.BigDecimal;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

@Repository
public interface MyRepository extends JpaRepository<Myentity, Long> 

    @Query(value = "SELECT SCHEMA.SEQUENCE_NAME.nextval FROM dual", nativeQuery = true)
    public BigDecimal getNextValMySequence();


【讨论】:

与此类似的本机查询对我有用select nextval('sequence_name') 有没有办法在不使用原生查询的情况下获取序列号?【参考方案2】:
@Entity
@Table(name = "tabelName")
public class yourEntity
    @Id
    @SequenceGenerator(name = "yourName", sequenceName = "yourSeqName", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "yourName")
    @Column(name = "id", updatable = false)
    protected Long id;


@Query(value = "SELECT yourSeqName.nextval FROM tableName", nativeQuery = true)
Long getNextSeriesId();

编辑:

Query q = em.createNativeQuery("SELECT yourSeqName.NEXTVAL FROM DUAL");
return (java.math.BigDecimal)q.getSingleResult();

【讨论】:

我们不能在不定义实体的情况下使用它吗?无论如何,我们可以在存储库中使用 dual 来调用它? @AshishChauhan 是的,你可以使用双重 我需要用 em 调用它吗? 是的,em 是实体管理器 @AshishChauhan 请接受答案并投票,以便其他人了解正确的解决方案。【参考方案3】:

在 PostgreSQL 中是:

Long value = Long.parseLong(entityManager
            .createNativeQuery("select nextval('sequence_name')")
            .getSingleResult().toString());

【讨论】:

【参考方案4】:

你可以使用EntityManager:

entityManager.createNativeQuery("select seqname.nextval ...").getSingleResult();

【讨论】:

我使用的数据库是oracle,实体管理器已经在另一个配置类中配置为bean。 nextval(seqname) 给出错误表示未知值。我不能在 JPA 存储库中使用上述方法吗? 我已经用oracle方言编辑了问题,我不确定,你可以试试把它放在@Query【参考方案5】:

我使用以下代码解决了这个问题:

@Query(value = "SELECT NEXT VALUE FOR code_sequence", nativeQuery = true)
public BigDecimal getNextValCodeSequence();

注意:你应该用你的序列名称替换code_sequence

【讨论】:

以上是关于使用 Spring JPA 从序列中获取 nextval 的查询的主要内容,如果未能解决你的问题,请参考以下文章

触发额外查询以获取序列下一个值-spring JPA

在 postgreSQL 中使用 jpa 存储库从序列中获取下一个值

使用 Spring Jpa 从两个或多个表中获取选定的列

如何使用 @ID 和 @GeneratedValue 从 Hibernate + JPA 中的序列中获取 Oracle 生成的值

Spring Data JPA:查询ManyToMany,如何从映射类中获取数据?

从数据库获取数据时,Jpa Repository 出错无法序列化