已解决的问题:以下是问题说明及其解决方法。
问题说明
使用SOAP服务创建了Spring boot(v1.4.1 RELEASE)项目(可以避免解决此问题的SOAP服务)和Spring数据JPA CrudRepository来执行CRUD操作。 MYSQL的每一件事都可以正常工作,但是当我尝试使用Sybase连接它时,我找不到Table。 请帮助,因为这对我们来说是一个绝迹。
请帮助解决此问题。
application.properties
server.port=10000
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.databasePlatform=org.hibernate.dialect.SybaseDialect
# SQL dialect for generating optimized queries
spring.jpa.hibernate.ddl-auto=none
spring.jpa.database=SYBASE
spring.jpa.show-sql=true
# hikariCP
spring.datasource.dataSourceClassName=com.sybase.jdbc4.jdbc.SybDataSource
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.connectionTestQuery=SELECT 1
spring.datasource.username=dev
spring.datasource.password=developer
spring.datasource.databaseName=MTW
spring.datasource.serverName=localhost
spring.datasource.portNumber=5000
实体bean
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "wallettest")
public class wallet {
@Id
@Column(name = "orderId")
private long id;
@Column(name = "orderInternalId")
private int orderInternalId;
@Column(name = "orderStatus")
private int orderStatus;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getOrderInternalId() {
return orderInternalId;
}
public void setOrderInternalId(int orderInternalId) {
this.orderInternalId = orderInternalId;
}
public int getOrderStatus() {
return orderStatus;
}
public void setOrderStatus(int orderStatus) {
this.orderStatus = orderStatus;
}
}
WalletRespository
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
@Component
@Transactional
// Logically No need @Transactional if there is only one table involved
public interface WalletRepository extends CrudRepository<wallet, Long> {
@Modifying
@Query(value = "UPDATE wallet SET orderStatus = :orderStatus WHERE id = :orderId AND orderInternalId= :orderInternalId")
public int updateWalletStatus(@Param("orderId") long orderId, @Param("orderInternalId") int orderInternalId,
@Param("orderStatus") int orderStatus);
}
当发送SOAP请求时,已实现了一个Endpoint类,该类将请求委托给业务层类的适当输入,下面是业务层中的类,它被调用,此类没有任何错误,此处提供用于参考目的:
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component("WalletUpdatorServiceImpl")
public class WalletUpdatorServiceImpl implements WalletUpdatorService {
private WalletRepository walletRepository;
private WalletItemTransformer walletItemTransformer;
private ExtendedLogger logger = ExtendedLogger.create(WalletUpdatorServiceImpl.class);
List<OrderUpdateItem> walletUpdateItemsSucceded = null;
List<OrderUpdateItem> walletUpdateItemsFailed = null;
@Autowired
public WalletUpdatorServiceImpl(WalletRepository walletRepository, WalletItemTransformer walletItemTransformer) {
this.walletRepository = walletRepository;
this.walletItemTransformer = walletItemTransformer;
}
@Override
public List<OrderUpdateItem> updateWalletStatus(List<OrderUpdateItem> orderUpdateItems) {
walletUpdateItemsSucceded = new ArrayList<OrderUpdateItem>();
walletUpdateItemsFailed = new ArrayList<OrderUpdateItem>();
for (OrderUpdateItem orderUpdateItem : orderUpdateItems) {
wallet wallet = walletItemTransformer.transformToOrder(orderUpdateItem);
System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^^^");
System.out.println("wallet id:" + wallet.getId());
System.out.println("wallet id:" + wallet.getOrderInternalId());
System.out.println("wallet status:" + wallet.getOrderStatus());
System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^^^");
int count = walletRepository.updateWalletStatus(wallet.getId(), wallet.getOrderInternalId(),
wallet.getOrderStatus());
if (count == 1) {
logger.audit("%%%%%%%%%%%% SUCCESS %%%%%%%%%%%%%%%%%%%%");
logger.audit(wallet);
logger.audit("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
walletUpdateItemsSucceded.add(orderUpdateItem);
} else {
logger.audit("@@@@@@@@@@@@@@@@@@ FAILED @@@@@@@@@@@@@@@@@@@@@2");
logger.audit(wallet);
logger.audit("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2");
walletUpdateItemsFailed.add(orderUpdateItem);
}
}
return walletUpdateItemsSucceded;
}
public WalletRepository getWalletRepository() {
return walletRepository;
}
public void setWalletRepository(WalletRepository walletRepository) {
this.walletRepository = walletRepository;
}
public WalletItemTransformer getWalletItemTransformer() {
return walletItemTransformer;
}
public void setWalletItemTransformer(WalletItemTransformer walletItemTransformer) {
this.walletItemTransformer = walletItemTransformer;
}
public ExtendedLogger getLogger() {
return logger;
}
public void setLogger(ExtendedLogger logger) {
this.logger = logger;
}
}
这里我想根据orderId和orderInternalId更新订单状态。 因此,不是使用findOne从JPA获取wallettest对象,更新status属性然后执行save对象,而是直接使用@Query注释来更新所需的列。
这在MYSQL中有效,但是对于Sybase来说它是错误的说&#34;表未找到&#34;,Hibernate打印的查询是正确的,如下面的日志所示。
当我在application.propeties中输入spring.jpa.hibernate.ddl-auto = 更新时,它在使用mvn spring-boot执行项目之前,在使用soap服务之前会抱怨:运行并运行hibernate验证器,下面连接两个日志:
控制台日志在设置spring.jpa.hibernate.ddl-auto = update 之前
2016-10-07 20:57:28 [localhost-startStop-1] INFO FilterRegistrationBean:258 - Mapping filter: 'requestContextFilter' to: [/*]
2016-10-07 20:57:28 [main] INFO LocalContainerEntityManagerFactoryBean:349 - Building JPA container EntityManagerFactory for persistence unit 'default'
2016-10-07 20:57:28 [main] INFO LogHelper:31 - HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2016-10-07 20:57:28 [main] INFO Version:37 - HHH000412: Hibernate Core {5.0.11.Final}
2016-10-07 20:57:28 [main] INFO Environment:213 - HHH000206: hibernate.properties not found
2016-10-07 20:57:28 [main] INFO Environment:317 - HHH000021: Bytecode provider name : javassist
2016-10-07 20:57:28 [main] INFO Version:66 - HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2016-10-07 20:57:29 [main] INFO HikariDataSource:93 - HikariPool-1 - Started.
2016-10-07 20:57:29 [main] INFO Dialect:156 - HHH000400: Using dialect: org.hibernate.dialect.SybaseDialect
2016-10-07 20:57:29 [main] INFO LocalContainerEntityManagerFactoryBean:382 - Initialized JPA EntityManagerFactory for persistence unit 'default'
2016-10-07 20:57:30 [main] INFO QueryTranslatorFactoryInitiator:47 - HHH000397: Using ASTQueryTranslatorFactory
2016-10-07 20:57:30 [main] INFO OrderUpdateEndpoint:25 - Endpoint loaded
2016-10-07 20:57:31 [main] INFO RequestMappingHandlerAdapter:534 - Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@519753fd: startup date [Fri Oct 07 20:57:24
IST 2016]; root of context hierarchy
2016-10-07 20:57:31 [main] INFO RequestMappingHandlerMapping:543 - Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.
web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-10-07 20:57:31 [main] INFO RequestMappingHandlerMapping:543 - Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.
errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2016-10-07 20:57:31 [main] INFO SimpleUrlHandlerMapping:354 - Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-10-07 20:57:31 [main] INFO SimpleUrlHandlerMapping:354 - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-10-07 20:57:31 [main] INFO SimpleUrlHandlerMapping:354 - Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-10-07 20:57:31 [main] INFO AnnotationMBeanExporter:431 - Registering beans for JMX exposure on startup
2016-10-07 20:57:31 [main] INFO AnnotationMBeanExporter:912 - Bean with name 'dataSource' has been autodetected for JMX exposure
2016-10-07 20:57:31 [main] INFO AnnotationMBeanExporter:667 - Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
2016-10-07 20:57:31 [main] INFO Http11NioProtocol:179 - Initializing ProtocolHandler ["http-nio-10000"]
2016-10-07 20:57:31 [main] INFO Http11NioProtocol:179 - Starting ProtocolHandler [http-nio-10000]
2016-10-07 20:57:31 [main] INFO NioSelectorPool:179 - Using a shared selector for servlet write/read
2016-10-07 20:57:31 [main] INFO TomcatEmbeddedServletContainer:185 - Tomcat started on port(s): 10000 (http)
2016-10-07 20:57:31 [main] INFO Application:57 - Started Application in 7.788 seconds (JVM running for 12.563)
2016-10-07 20:57:40 [http-nio-10000-exec-1] INFO [/]:179 - Initializing Spring FrameworkServlet 'messageDispatcherServlet'
2016-10-07 20:57:40 [http-nio-10000-exec-1] INFO MessageDispatcherServlet:489 - FrameworkServlet 'messageDispatcherServlet': initialization started
2016-10-07 20:57:40 [http-nio-10000-exec-1] INFO SaajSoapMessageFactory:139 - Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol
2016-10-07 20:57:40 [http-nio-10000-exec-1] INFO MessageDispatcherServlet:508 - FrameworkServlet 'messageDispatcherServlet': initialization completed in 40 ms
^^^^^^^^^^^^^^^^^^^^^^^^^^
wallet id:1
wallet id:102
wallet status:9
^^^^^^^^^^^^^^^^^^^^^^^^^^
Hibernate: update wallettest set orderStatus=? where orderId=? and orderInternalId=?
2016-10-07 20:57:40 [http-nio-10000-exec-1] WARN SqlExceptionHelper:127 - SQL Error: 42102, SQLState: 42S02
2016-10-07 20:57:40 [http-nio-10000-exec-1] ERROR SqlExceptionHelper:129 - Table "WALLETTEST" not found; SQL statement:
update wallettest set orderStatus=? where orderId=? and orderInternalId=? [42102-192]
控制台日志设置spring.jpa.hibernate.ddl-auto = update
后2016-10-07 21:20:19 [main] INFO LocalContainerEntityManagerFactoryBean:349 - Building JPA container EntityManagerFactory for persistence unit 'default'
2016-10-07 21:20:19 [main] INFO LogHelper:31 - HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2016-10-07 21:20:19 [main] INFO Version:37 - HHH000412: Hibernate Core {5.0.11.Final}
2016-10-07 21:20:19 [main] INFO Environment:213 - HHH000206: hibernate.properties not found
2016-10-07 21:20:19 [main] INFO Environment:317 - HHH000021: Bytecode provider name : javassist
2016-10-07 21:20:19 [main] INFO Version:66 - HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2016-10-07 21:20:20 [main] INFO HikariDataSource:93 - HikariPool-1 - Started.
2016-10-07 21:20:20 [main] INFO Dialect:156 - HHH000400: Using dialect: org.hibernate.dialect.SybaseDialect
2016-10-07 21:20:21 [main] INFO SchemaUpdate:105 - HHH000228: Running hbm2ddl schema update
2016-10-07 21:20:21 [main] INFO InformationExtractorJdbcDatabaseMetaDataImpl:365 - HHH000262: Table not found: wallettest
2016-10-07 21:20:21 [main] INFO InformationExtractorJdbcDatabaseMetaDataImpl:365 - HHH000262: Table not found: wallettest
2016-10-07 21:20:21 [main] INFO LocalContainerEntityManagerFactoryBean:382 - Initialized JPA EntityManagerFactory for persistence unit 'default'
2016-10-07 21:20:21 [main] INFO QueryTranslatorFactoryInitiator:47 - HHH000397: Using ASTQueryTranslatorFactory
2016-10-07 21:20:21 [main] INFO OrderUpdateEndpoint:25 - Endpoint loaded
2016-10-07 21:20:22 [main] INFO RequestMappingHandlerAdapter:534 - Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@65cefb8b: startup date [Fri Oct 07 21:20:15
IST 2016]; root of context hierarchy
2016-10-07 21:20:22 [main] INFO RequestMappingHandlerMapping:543 - Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.
web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-10-07 21:20:22 [main] INFO RequestMappingHandlerMapping:543 - Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.
errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2016-10-07 21:20:22 [main] INFO SimpleUrlHandlerMapping:354 - Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-10-07 21:20:22 [main] INFO SimpleUrlHandlerMapping:354 - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-10-07 21:20:22 [main] INFO SimpleUrlHandlerMapping:354 - Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-10-07 21:20:23 [main] INFO AnnotationMBeanExporter:431 - Registering beans for JMX exposure on startup
2016-10-07 21:20:23 [main] INFO AnnotationMBeanExporter:912 - Bean with name 'dataSource' has been autodetected for JMX exposure
2016-10-07 21:20:23 [main] INFO AnnotationMBeanExporter:667 - Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
2016-10-07 21:20:23 [main] INFO Http11NioProtocol:179 - Initializing ProtocolHandler ["http-nio-10000"]
2016-10-07 21:20:23 [main] INFO Http11NioProtocol:179 - Starting ProtocolHandler [http-nio-10000]
2016-10-07 21:20:23 [main] INFO NioSelectorPool:179 - Using a shared selector for servlet write/read
2016-10-07 21:20:23 [main] INFO TomcatEmbeddedServletContainer:185 - Tomcat started on port(s): 10000 (http)
2016-10-07 21:20:23 [main] INFO Application:57 - Started Application in 8.57 seconds (JVM running for 13.413)
问题解决方案:
Spring boot忽略了application.properties文件中的以下属性:
spring.datasource.dataSourceClassName=com.sybase.jdbc4.jdbc.SybDataSource
spring.datasource.username=dev
spring.datasource.password=developer
spring.datasource.databaseName=MTW
spring.datasource.serverName=localhost
spring.datasource.portNumber=5000
更新了application.properties文件,如下所示:
server.port=10000
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.databasePlatform=org.hibernate.dialect.SybaseDialect
spring.jpa.show-sql=true
# hikariCP
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.url=jdbc:sybase:Tds:172.16.12.35:5000/MTW
spring.datasource.connectionTestQuery=SELECT 1
spring.datasource.username=mtw_dev
spring.datasource.password=developer
spring.datasource.poolName=SpringBootHikariCP
spring.datasource.maximumPoolSize=10
spring.datasource.connectionTimeout=60000
spring.datasource.driverClassName=com.sybase.jdbc4.jdbc.SybDriver
Imp point :而不是在eclipse中使用jconn4.jar作为外部jar,使用以下命令将其更改为maven依赖项:
mvn install:install-file -DgroupId=com.sybase -DartifactId=sybase-jconnect -Dversion=7.07 -Dpackaging=jar -DgeneratePom=true -Dfile=jconn4.jar
此命令将Sybase jar作为依赖项移动到本地maven repo
中然后在我的pom.xml中的相关部分中提到它。
这是因为没有提到jconn4作为maven依赖而不仅仅是构建路径中的外部jar,Spring boot + hikariCP抱怨说:无法加载sybase驱动程序类:
threw exception; nested exception is java.lang.IllegalStateException: Cannot load driver class: com.sybase.jdbc4.jdbc.SybDriver
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189)
看起来驱动程序也应该是Spring引导的pom.xml的一部分,以便自动选择它。