Spring 使用 Sybase 的数据 Jpa - UnimplementedOperationException
Spring Data Jpa with Sybase - UnimplementedOperationException
我发现将对象持久化到 Sybase 起诉 Spring Data JPA 存在问题。我看到的错误是
com.sybase.jdbc3.utils.UnimplementedOperationException:
The method com.sybase.jdbc3.jdbc.SybConnection.prepareStatement(String, int)
has not been completed and should not be called.
我已将其简化为带有 ID 和描述的实体对象,但仍然看到错误。
我的实体class是
@Entity
@Table(name = "tbl_bsc_region")
public class Region implements Serializable {
private static final long serialVersionUID = -7985499571755472582L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "bsc_region_id")
private Long id;
@Column(name = "region_name")
private String regionName;
protected Region() {
// for JPA only
}
public Region(final String regionName) {
this.regionName = regionName;
}
/**
* Accessor method for id.
*
* @return value of id
*/
public Long getId() {
return this.id;
}
/**
* Modifier method for id.
*
* @param id
* the id to set
*/
public void setId(final Long id) {
this.id = id;
}
/**
* Accessor method for regionName.
*
* @return value of regionName
*/
public String getRegionName() {
return this.regionName;
}
/**
* Modifier method for regionName.
*
* @param regionName
* the regionName to set
*/
public void setRegionName(final String regionName) {
this.regionName = regionName;
}
}
我的测试是
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring/application-test.xml")
public class RegionIntegrationTest {
@Autowired
RegionRepository repo;
/**
* Test save with only Generic Info details
*/
@Test
public void testSave() throws Exception {
final Region region = new Region("CG Region");
this.repo.save(region);
}
}
我的数据源
<bean id="bscDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.sybase.jdbc3.jdbc.SybDriver" />
<property name="url" value="jdbc:sybase:Tds:DUKMACA09.SYSTEMS.UK.CO:10010/bsc" />
<property name="username" value="obscuredusername" />
<property name="password" value="obscuredpwd" />
<property name="initialSize" value="10" />
<property name="maxActive" value="10" />
</bean>
我的实体管理器工厂设置为
<bean id="bscEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="bscDataSource"/>
<property name="packagesToScan" value="com.bsc.model"/>
<property name="persistenceUnitName" value="bscPersistenceUnit"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.SybaseASE15Dialect"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.connection.autocommit">false</prop>
</props>
</property>
</bean>
和我的 jconn 版本
<dependency>
<groupId>jconn3</groupId>
<artifactId>jconn3</artifactId>
<version>6.0</version>
</dependency>
我看不出问题所在
测试的完整控制台输出是
2016-10-11 18:49:19,636 DEBUG [main] support.TransactionalRepositoryProxyPostProcessor$AbstractFallbackTransactionAttributeSource - Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2016-10-11 18:49:19,640 DEBUG [main] support.AbstractPlatformTransactionManager - Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2016-10-11 18:49:19,642 DEBUG [main] jpa.JpaTransactionManager - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@2c5d529e] for JPA transaction
2016-10-11 18:49:19,783 DEBUG [main] jpa.JpaTransactionManager - Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@5e13fb15]
2016-10-11 18:49:28,642 DEBUG [main] spi.SqlStatementLogger - insert into tbl_bsc_region (region_name) values (?)
select @@identity
Hibernate: insert into tbl_bsc_region (region_name) values (?)
select @@identity
2016-10-11 18:49:28,650 DEBUG [main] support.AbstractPlatformTransactionManager - Initiating transaction rollback
2016-10-11 18:49:28,652 DEBUG [main] jpa.JpaTransactionManager - Rolling back JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@2c5d529e]
2016-10-11 18:49:28,749 DEBUG [main] jpa.JpaTransactionManager - Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@2c5d529e] after transaction
2016-10-11 18:49:28,750 DEBUG [main] jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
2016-10-11 18:49:28,896 DEBUG [main] support.DirtiesContextTestExecutionListener - After test method: context [[TestContext@a98ce7e testClass = RegionIntegrationTest, testInstance = com.bsc.repository.RegionIntegrationTest@361cb7a1, testMethod = testSave@RegionIntegrationTest, testException = com.sybase.jdbc3.utils.UnimplementedOperationException: The method com.sybase.jdbc3.jdbc.SybConnection.prepareStatement(String, int) has not been completed and should not be called., mergedContextConfiguration = [MergedContextConfiguration@175bc6c8 testClass = RegionIntegrationTest, locations = '{classpath:/spring/application-test.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader']]], class dirties context [false], class mode [null], method dirties context [false].
2016-10-11 18:49:28,905 DEBUG [main] support.DirtiesContextTestExecutionListener - After test class: context [[TestContext@a98ce7e testClass = RegionIntegrationTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@175bc6c8 testClass = RegionIntegrationTest, locations = '{classpath:/spring/application-test.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader']]], dirtiesContext [false].
2016-10-11 18:49:28,930 INFO [Thread-2] jpa.AbstractEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'bscPersistenceUnit'
调试时我看到错误发生在 Spring class
org.springframework.transaction.interceptor.TransactionInterceptor
在下面调用的方法中
return invocation.proceed();
@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
@Override
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();
}
});
}
试用 JTDS 驱动程序:
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.2.8</version>
Jconn3 的标识列有问题
我发现将对象持久化到 Sybase 起诉 Spring Data JPA 存在问题。我看到的错误是
com.sybase.jdbc3.utils.UnimplementedOperationException:
The method com.sybase.jdbc3.jdbc.SybConnection.prepareStatement(String, int)
has not been completed and should not be called.
我已将其简化为带有 ID 和描述的实体对象,但仍然看到错误。
我的实体class是
@Entity
@Table(name = "tbl_bsc_region")
public class Region implements Serializable {
private static final long serialVersionUID = -7985499571755472582L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "bsc_region_id")
private Long id;
@Column(name = "region_name")
private String regionName;
protected Region() {
// for JPA only
}
public Region(final String regionName) {
this.regionName = regionName;
}
/**
* Accessor method for id.
*
* @return value of id
*/
public Long getId() {
return this.id;
}
/**
* Modifier method for id.
*
* @param id
* the id to set
*/
public void setId(final Long id) {
this.id = id;
}
/**
* Accessor method for regionName.
*
* @return value of regionName
*/
public String getRegionName() {
return this.regionName;
}
/**
* Modifier method for regionName.
*
* @param regionName
* the regionName to set
*/
public void setRegionName(final String regionName) {
this.regionName = regionName;
}
}
我的测试是
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring/application-test.xml")
public class RegionIntegrationTest {
@Autowired
RegionRepository repo;
/**
* Test save with only Generic Info details
*/
@Test
public void testSave() throws Exception {
final Region region = new Region("CG Region");
this.repo.save(region);
}
}
我的数据源
<bean id="bscDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.sybase.jdbc3.jdbc.SybDriver" />
<property name="url" value="jdbc:sybase:Tds:DUKMACA09.SYSTEMS.UK.CO:10010/bsc" />
<property name="username" value="obscuredusername" />
<property name="password" value="obscuredpwd" />
<property name="initialSize" value="10" />
<property name="maxActive" value="10" />
</bean>
我的实体管理器工厂设置为
<bean id="bscEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="bscDataSource"/>
<property name="packagesToScan" value="com.bsc.model"/>
<property name="persistenceUnitName" value="bscPersistenceUnit"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.SybaseASE15Dialect"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.connection.autocommit">false</prop>
</props>
</property>
</bean>
和我的 jconn 版本
<dependency>
<groupId>jconn3</groupId>
<artifactId>jconn3</artifactId>
<version>6.0</version>
</dependency>
我看不出问题所在
测试的完整控制台输出是
2016-10-11 18:49:19,636 DEBUG [main] support.TransactionalRepositoryProxyPostProcessor$AbstractFallbackTransactionAttributeSource - Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2016-10-11 18:49:19,640 DEBUG [main] support.AbstractPlatformTransactionManager - Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2016-10-11 18:49:19,642 DEBUG [main] jpa.JpaTransactionManager - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@2c5d529e] for JPA transaction
2016-10-11 18:49:19,783 DEBUG [main] jpa.JpaTransactionManager - Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@5e13fb15]
2016-10-11 18:49:28,642 DEBUG [main] spi.SqlStatementLogger - insert into tbl_bsc_region (region_name) values (?)
select @@identity
Hibernate: insert into tbl_bsc_region (region_name) values (?)
select @@identity
2016-10-11 18:49:28,650 DEBUG [main] support.AbstractPlatformTransactionManager - Initiating transaction rollback
2016-10-11 18:49:28,652 DEBUG [main] jpa.JpaTransactionManager - Rolling back JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@2c5d529e]
2016-10-11 18:49:28,749 DEBUG [main] jpa.JpaTransactionManager - Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@2c5d529e] after transaction
2016-10-11 18:49:28,750 DEBUG [main] jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
2016-10-11 18:49:28,896 DEBUG [main] support.DirtiesContextTestExecutionListener - After test method: context [[TestContext@a98ce7e testClass = RegionIntegrationTest, testInstance = com.bsc.repository.RegionIntegrationTest@361cb7a1, testMethod = testSave@RegionIntegrationTest, testException = com.sybase.jdbc3.utils.UnimplementedOperationException: The method com.sybase.jdbc3.jdbc.SybConnection.prepareStatement(String, int) has not been completed and should not be called., mergedContextConfiguration = [MergedContextConfiguration@175bc6c8 testClass = RegionIntegrationTest, locations = '{classpath:/spring/application-test.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader']]], class dirties context [false], class mode [null], method dirties context [false].
2016-10-11 18:49:28,905 DEBUG [main] support.DirtiesContextTestExecutionListener - After test class: context [[TestContext@a98ce7e testClass = RegionIntegrationTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@175bc6c8 testClass = RegionIntegrationTest, locations = '{classpath:/spring/application-test.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader']]], dirtiesContext [false].
2016-10-11 18:49:28,930 INFO [Thread-2] jpa.AbstractEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'bscPersistenceUnit'
调试时我看到错误发生在 Spring class
org.springframework.transaction.interceptor.TransactionInterceptor
在下面调用的方法中
return invocation.proceed();
@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
@Override
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();
}
});
}
试用 JTDS 驱动程序:
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.2.8</version>
Jconn3 的标识列有问题