Spring boot + JPA + Sybase"找不到表"

时间:2016-10-07 15:58:04

标签: java spring-boot spring-data-jpa sybase

已解决的问题:以下是问题说明及其解决方法。

问题说明

使用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的一部分,以便自动选择它。

0 个答案:

没有答案