Oracle 数据库上的本机查询执行抛出 java.lang.NegativeArraySizeException:-1

Native query execution on Oracle database throws java.lang.NegativeArraySizeException: -1

在我的 spring-boot 项目中,我使用 spring-data、Hibernate 和 Oracle 作为数据库。

我有实体 MessageUserSeenMessage

Messaage 看起来像:

    @Entity
    @Table(name = "MESSAGES")
    public class Messages {
    
        @Id
        @Column(name = "ID")
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MARKET_MESSAGE_GENERATOR")
        @SequenceGenerator(name = "MARKET_MESSAGE_GENERATOR", sequenceName = "MARKET_MESSAGE_SEQ", allocationSize = 1)
        private Long id;
    
        @Basic
        @Column(name = "PUBLISH_DATE")
        private Timestamp dateTime;
    
        @Basic
        @Column(name = "TITLE")
        private String title;
    
        @Lob
        @Nationalized
        @Column(name = "MESSAGE", columnDefinition="NCLOB NOT NULL")
        private String message;
 }

User 看起来像:

@Entity
@Table(name = "Users")
public class User {

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_GENERATOR")
    @SequenceGenerator(name = "USER_GENERATOR", sequenceName = "USERS_SEQ", allocationSize = 1)
    private Long id;

    @Basic
    @Column(name = "USER_NAME")
    private String userName;
}

SeenMessage看起来像:

@Entity
@Table(name = "SEEN_MESSAGE")
public class SeenMessage {

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEEN_MESSAGE_GENERATOR")
    @SequenceGenerator(name = "SEEN_MESSAGE_GENERATOR", sequenceName = "SEEN_MESSAGE_SEQ", allocationSize = 1)
    private Long id;

    @Basic
    @Column(name = "SEEN_DATE")
    private Timestamp seenDate;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "MESSAGE_ID")
    private Messages message;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "USER_ID")
    private User user; 
}

同样在这个 table (SEEN_MESSAGE) 上我有一对 (Message_Id, User_Id)

的唯一约束条件

现在的问题是:

我有一个简单的 REST API 用于获取带有其 ID 的消息,当任何人调用此服务时我将 return 请求的消息并且我将在 seenMessage 中插入一条记录table 与 messageIduserId 当然还有它的时间。

我通过调用存储库中的方法在我的服务层执行第二个操作(插入 SeenMessage):

@Repository
public interface SeenMessageRepository extends JpaRepository<SeenMessage, Long> {

    @Query(value = "begin " +
            "insert into SEEN_MESSAGE(ID, MESSAGE_ID, USER_ID, SEEN_DATE) " +
            "values(seen_message_seq.nextval, :MId , :UId , CURRENT_TIMESTAMP ); " +
            "exception " +
            "when dup_val_on_index THEN " +
            "RETURN; " +
            "end;", nativeQuery = true)
    void insertAndForget(Long MId, Long UId);
}

如您所见,我已经编写了一个本机查询,当我在 DBMS 上执行它时,它会成功执行,但是当我使用 Postman 调用我的 API 时,查询将按我预期的方式执行和执行,但是它还抛出一个异常:

2021-10-26 11:12:50.385 ERROR 4848 --- [nio-1201-exec-2] c.a.b.o.exceptions.ExceptionTranslator   : -1

java.lang.NegativeArraySizeException: -1
    at org.hibernate.loader.custom.ResultRowProcessor.prepareForAutoDiscovery(ResultRowProcessor.java:36)
    at org.hibernate.loader.custom.CustomLoader.autoDiscoverTypes(CustomLoader.java:489)
    at org.hibernate.loader.Loader.preprocessResultSet(Loader.java:2343)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:2299)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2050)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2012)
    at org.hibernate.loader.Loader.doQuery(Loader.java:948)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349)
    at org.hibernate.loader.Loader.doList(Loader.java:2843)
    at org.hibernate.loader.Loader.doList(Loader.java:2825)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2657)
    at org.hibernate.loader.Loader.list(Loader.java:2652)
    at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:338)
    at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2141)
    at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:1169)
    at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:176)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1604)
    at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1652)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:196)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:88)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:155)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:143)
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:159)
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.transaction.interceptor.TransactionInterceptor.proceedWithInvocation(TransactionInterceptor.java:123)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:145)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
    at com.sun.proxy.$Proxy125.insertAndForget(Unknown Source)

也许说我写了这个查询并没有使用简单的插入查询是件好事,因为在那种情况下我需要自己检查重复项(如果我不检查重复项我可能会面临UniqueconstraintViolationException) 与另一个数据库调用,我认为这是额外的,所以我写了这个。

有人能告诉我这个错误的原因吗??

为什么它在 DBMS 上执行没有错误,但在我的应用程序中却导致错误??

如有任何帮助,我们将不胜感激!!

我需要在我的存储库方法上添加 @Modifying 注释,如下所示:

@Modifying
@Query(value = "BEGIN " +
        "INSERT INTO SEEN_MESSAGE(ID, MESSAGE_ID, USER_ID, SEEN_DATE) " +
        "VALUES(seen_message_seq.nextval, :MId , :UId , CURRENT_TIMESTAMP ); " +
        "EXCEPTION " +
        "WHEN dup_val_on_index THEN " +
        "RETURN;" +
        "END;", nativeQuery = true)
void insertAndForget(Long MId, Long UId);

我还需要在我的服务层中打开一个 TRANSACTION,为此我将 @Transactional(rollbackFor = Exception.class) 放在服务层中调用我的存储库方法的方法上。