Oracle 数据库上的本机查询执行抛出 java.lang.NegativeArraySizeException:-1
Native query execution on Oracle database throws java.lang.NegativeArraySizeException: -1
在我的 spring-boot 项目中,我使用 spring-data、Hibernate 和 Oracle 作为数据库。
我有实体 Message
、User
和 SeenMessage
。
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 与 messageId
和 userId
当然还有它的时间。
我通过调用存储库中的方法在我的服务层执行第二个操作(插入 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)
放在服务层中调用我的存储库方法的方法上。
在我的 spring-boot 项目中,我使用 spring-data、Hibernate 和 Oracle 作为数据库。
我有实体 Message
、User
和 SeenMessage
。
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 与 messageId
和 userId
当然还有它的时间。
我通过调用存储库中的方法在我的服务层执行第二个操作(插入 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)
放在服务层中调用我的存储库方法的方法上。