New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullPointerException after upgrading JDBC-driver from 6.4 to 7.0 #788

Closed
christophs78 opened this Issue Aug 28, 2018 · 8 comments

Comments

4 participants
@christophs78

christophs78 commented Aug 28, 2018

Driver version or jar name

mssql-jdbc-7.0.0.jre8.jar

SQL Server version

13.0.4001.0

Client operating system

Windows 10 1709
(But i think it does not matter.)

Java/JVM version

Java HotSpot(TM) 64-Bit Server VM, Version 1.8.0_171-b1 (Oracle)
(But i think it does not matter.)

Table schema

Sorting: Latin1_general_CI_AS
Compatibility: SQL Server 2012 (110)

Problem description

Caused by: java.lang.NullPointerException
at com.microsoft.sqlserver.jdbc.SQLServerClobBase.length(SQLServerClob.java:388)
at com.microsoft.sqlserver.jdbc.SQLServerClob.length(SQLServerClob.java:97)
at org.hibernate.type.descriptor.java.DataHelper.determineLengthForBufferSizing(DataHelper.java:285)
at org.hibernate.type.descriptor.java.DataHelper.extractString(DataHelper.java:264)
...
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1445)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414)
at org.hibernate.query.Query.getResultList(Query.java:146)
at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:72)
...
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy146.findAllByOrderByServiceNameAsc(Unknown Source)
at iete.view.RecordIssueView.init(RecordIssueView.java:45)

There was a change in SQLServerClobBase.length with Version 7.0.
b60068c

Expected behavior and actual behavior

NullPointerException should not be thrown.

Repro code

Database-View:
grafik

JPA-Model-Class:

package iete.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;

import lombok.Getter;
import lombok.Setter;

/**
 * The persistent class for the lrg_services_extern_v database table.
 * 
 */
@Entity
@Table(name = "lrg_services_extern_v")
@Getter
@Setter
public class IetServicesExtern implements Serializable {

	private static final long serialVersionUID = 1L;

	@Column(name = "service")
	private String serviceName;

	@Column(name = "service_id")
	@Id
	private int serviceId;

	@Lob
	@Column(name = "service_txt")
	private String serviceTxt;
}

SpringData-Repository:

/**
 * Spring Data JPA Repository für {@link iete.model.IetServicesExtern}.
 */
public interface IetServicesExternRepository
		extends PagingAndSortingRepository<IetServicesExtern, Integer>, JpaRepository<IetServicesExtern, Integer> {

	public List<IetServicesExtern> findAllByOrderByServiceNameAsc();
}
@rene-ye

This comment has been minimized.

Member

rene-ye commented Aug 29, 2018

Hi @christophs78, I wasn't able to create an exact repro described in the issue, but I was able to reproduce the error. I believe the underlying cause for both the errors are the same, and have made a fix to the driver. Can you test these new jars and see if it solves the problem?
Fixed Jars.zip

@christophs78

This comment has been minimized.

christophs78 commented Aug 30, 2018

Hi @rene-ye!

Thank´s for your update!
I´m sorry, the fixed Driver JAR creates an other exception.

Caused by: org.springframework.orm.jpa.JpaSystemException: IOException occurred reading text; nested exception is org.hibernate.HibernateException: IOException occurred reading text
...
Caused by: java.io.IOException: The stream is closed.

(Full Stacktrace further down.)

I´ll try to build a sandbox-eclipse-project for this issue. (Hibernate without Spring) Would this help?

Kind regards,

Christoph


Caused by: org.springframework.orm.jpa.JpaSystemException: IOException occurred reading text; nested exception is org.hibernate.HibernateException: IOException occurred reading text
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:314)
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:225)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:527)
	at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
	at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	at com.sun.proxy.$Proxy111.findAllByOrderByServiceNameAsc(Unknown Source)
	at iete.view.RecordIssueView.init(RecordIssueView.java:45)
	at sun.reflect.GeneratedMethodAccessor950.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:365)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:308)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:135)
	... 140 more
Caused by: org.hibernate.HibernateException: IOException occurred reading text
	at org.hibernate.type.descriptor.java.DataHelper.extractString(DataHelper.java:79)
	at org.hibernate.type.descriptor.java.DataHelper.extractString(DataHelper.java:267)
	at org.hibernate.type.descriptor.java.StringTypeDescriptor.wrap(StringTypeDescriptor.java:75)
	at org.hibernate.type.descriptor.java.StringTypeDescriptor.wrap(StringTypeDescriptor.java:22)
	at org.hibernate.type.descriptor.sql.ClobTypeDescriptor$1.doExtract(ClobTypeDescriptor.java:44)
	at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47)
	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:261)
	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:257)
	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:247)
	at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:333)
	at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2868)
	at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1747)
	at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1673)
	at org.hibernate.loader.Loader.getRow(Loader.java:1562)
	at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:732)
	at org.hibernate.loader.Loader.processResultSet(Loader.java:991)
	at org.hibernate.loader.Loader.doQuery(Loader.java:949)
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
	at org.hibernate.loader.Loader.doList(Loader.java:2692)
	at org.hibernate.loader.Loader.doList(Loader.java:2675)
	at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507)
	at org.hibernate.loader.Loader.list(Loader.java:2502)
	at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:502)
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:392)
	at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216)
	at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1490)
	at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1445)
	at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414)
	at org.hibernate.query.Query.getResultList(Query.java:146)
	at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:72)
	at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:129)
	at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:91)
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:136)
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:125)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:590)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:578)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
	... 155 more
Caused by: java.io.IOException: The stream is closed.
	at com.microsoft.sqlserver.jdbc.BaseInputStream.checkClosed(SimpleInputStream.java:95)
	at com.microsoft.sqlserver.jdbc.SimpleInputStream.read(SimpleInputStream.java:284)
	at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
	at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
	at sun.nio.cs.StreamDecoder.read(Unknown Source)
	at java.io.InputStreamReader.read(Unknown Source)
	at java.io.BufferedReader.fill(Unknown Source)
	at java.io.BufferedReader.read1(Unknown Source)
	at java.io.BufferedReader.read(Unknown Source)
	at org.hibernate.type.descriptor.java.DataHelper.extractString(DataHelper.java:71)
	... 197 more
@christophs78

This comment has been minimized.

christophs78 commented Aug 30, 2018

Eclipse-Sandbox-Projekt:
IssueReproSqlServerJdbcClob.zip

It uses gradle (build.gradle) to load dependencies. (hibernate and mssql-jdbc) Remove the mssql-jdbc-dependency to test against your own version of the jdbc-driver. Adapt persistence.xml to connect to your database.
Hope this project is straight-forward and easy to understand.

@cheenamalhotra cheenamalhotra added this to In progress in MSSQL JDBC Aug 30, 2018

@rene-ye

This comment has been minimized.

Member

rene-ye commented Aug 30, 2018

Hi @christophs78, the sandbox reproduction you provided works and I can confirm the error on my end. I've updated the change and provided an initial version of the fix below. Please see if it resolves the issue.
Fixed Jars.zip

@christophs78

This comment has been minimized.

christophs78 commented Aug 31, 2018

Yes, it resolves the issue. :-)

@hittor

This comment has been minimized.

hittor commented Sep 7, 2018

I have encountered the same problem, thanks to @rene-ye , can you tell us the release date of the final version of 7.1.1?

@rene-ye

This comment has been minimized.

Member

rene-ye commented Sep 10, 2018

7.1.1-preview will be released when all its milestones are completed, which is currently targeted for end-of-month.

@cheenamalhotra cheenamalhotra removed this from the 7.1.1 milestone Sep 17, 2018

rene-ye added a commit that referenced this issue Sep 25, 2018

Fixed a bug where calling length() after obtaining a stream would clo…
…se the stream for Clobs/NClobs (#799)

Addresses #788. Also addressed an issue where varchar(max)/Clob objects were always being encoded to UTF-16LE instead of using the Collation specified in the Clob object.

List of Changes (the following applies to NClob as well):

1. calling Clob.length() no longer attempts to load the stream into a string. This fixes a null pointer issue as well as length() closing user streams.
2. added streaming capabilities for Clob.getAsciiStream(). NClobs will always have a non-streaming implementation for getAsciiStream().
3. Clobs no longer default to UTF-16LE. Clobs now respect the collation from the SQL Server. NClobs remain unchanged, will always be UTF-16LE encoding.
@rene-ye

This comment has been minimized.

Member

rene-ye commented Sep 25, 2018

#799 has been merged and will be available starting from the next preview release. Closing the issue.

@rene-ye rene-ye closed this Sep 25, 2018

MSSQL JDBC automation moved this from In progress to Closed Issues Sep 25, 2018

rene-ye added a commit to rene-ye/mssql-jdbc that referenced this issue Nov 30, 2018

Fixed a bug where calling length() after obtaining a stream would clo…
…se the stream for Clobs/NClobs (Microsoft#799)

Addresses Microsoft#788. Also addressed an issue where varchar(max)/Clob objects were always being encoded to UTF-16LE instead of using the Collation specified in the Clob object.

List of Changes (the following applies to NClob as well):

1. calling Clob.length() no longer attempts to load the stream into a string. This fixes a null pointer issue as well as length() closing user streams.
2. added streaming capabilities for Clob.getAsciiStream(). NClobs will always have a non-streaming implementation for getAsciiStream().
3. Clobs no longer default to UTF-16LE. Clobs now respect the collation from the SQL Server. NClobs remain unchanged, will always be UTF-16LE encoding.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment