[rent] 2019-02-22 18:09:41,751 ERROR [DubboServerHandler-172.20.30.57:20880-thread-18] com.company.rent.platform.service.dubbo.RentDubboExceptionHandler.aroudMethod(63) | dubbo service has a rentDubboException that is The given id must not be null!; nested exception is java.lang.IllegalArgumentException: The given id must not be null!.java
上面這段錯誤是dubbo的接口的service在save時總數報錯,而一樣的接口在通常rest接口的service的save保存能夠成功。spring
Connection is read-only. Queries leading to data modification are not allowedsql
當我解決dubbo的事務沒有辦法提交時,發現通常的rest的service的save保存一致提示上面的錯誤。api
到此刻:一頭兩個大;tomcat
緣由就是事務配置這塊有問題,怎麼搞呢?springboot
爲了調試dubbo接口順便查找了dubbo如何本地調試,在reference中加入:url="dubbo://localhost:20881"
,就能解決。本來的dubbo2.5.3被我升級到了2.6.0。session
搞了3天終於解決這兩塊問題,必定要記錄一下這次踩的坑;mvc
把一個傳統tomcat方式運行的項目改形成了springboot方式運行,須要從新配置數據源、事務、dubbo、spring、springmvc等等工做。app
項目最終運行環境:springboot1.5.2\dubbo2.6.0\spring4.3.5\springdatajpa1.10.5。ide
SpringApplication配置
@SpringBootApplication @Import(SpringContextHolder.class) @ComponentScan(basePackages = {"com.company"},excludeFilters = { @ComponentScan.Filter(value = Controller.class)}) @ServletComponentScan({"com.company.rent.platform"}) @PropertySource(value = "classpath:application.properties",ignoreResourceNotFound = true) @ImportResource({"classpath:dubbo-consumer.xml","classpath:dubbo-producer.xml"}) @EnableTransactionManagement public class RentApplication extends SpringBootServletInitializer { static ConfigurableApplicationContext cac; @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(RentApplication.class); } public static void main(String[] args){ SpringApplication app = new SpringApplicationBuilder(RentApplication.class).build(); cac = app.run(args); } }
Dubbo消費者配置
<dubbo:application name="rent"/> <dubbo:registry address="${dubbo.zookeeperAddress}" register="true"/> <!-- 掃描註解包路徑,多個包用逗號分隔,不填pacakge表示掃描當前ApplicationContext中全部的類 --> <dubbo:annotation package="com.isesol"/> <dubbo:protocol name="dubbo" port="20881"></dubbo:protocol> <!-- Rent引入平臺基礎服務 --> <dubbo:reference id="jpushDubboService" interface="com.company.service.JpushDubboService"/> <dubbo:reference id="jpushMsgService" interface="com.company.membercenter.dubbo.v2.service.JpushMsgService"/> <dubbo:reference id="rentApplyService" interface="com.smtcl.iplatform.machinearchive.rentservices.IRentApplyService"/> <dubbo:reference id="rentPlatformService" interface="com.company.factorycloud.dubbo.rent.IRentPaltformService"/> <dubbo:reference id="memberCenterService" interface="com.company.service.MemberCenterService"/> <dubbo:reference id="memberServiceV2" interface="com.company.membercenter.dubbo.v2.service.MemberService"/> <dubbo:reference id="memberInfoServiceV2" interface="com.company.membercenter.dubbo.v2.service.MemberInfoService"/> <dubbo:reference id="memberManagerService" interface="com.company.membercenter.dubbo.v2.service.MemberManagerService"/> <dubbo:reference id="verifyCodeService" interface="com.company.membercenter.dubbo.v2.service.VerifyCodeService"/> <dubbo:reference id="userOperateMemberService" interface="com.company.membercenter.dubbo.v2.service.UserOperateMemberService"/> <dubbo:reference id="phoneNumRuleService" interface="com.company.membercenter.dubbo.v2.service.PhoneNumRuleService"/> <dubbo:reference id="userCenterService" interface="com.company.service.UserCenterService"/> <dubbo:reference id="iAuthService" interface="com.company.authority.api.service.IAuthService"/> <dubbo:reference id="iButtonService" interface="com.company.authority.api.service.IButtonService"/> <dubbo:reference id="iModuleService" interface="com.company.authority.api.service.IModuleService"/> <dubbo:reference id="iOrgGroupService" interface="com.company.authority.api.service.IOrgGroupService"/> <dubbo:reference id="iPageService" interface="com.company.authority.api.service.IPageService"/> <dubbo:reference id="iRoleService" interface="com.company.authority.api.service.IRoleService"/> <dubbo:reference id="iUserService" interface="com.company.authority.api.service.IUserService"/> <dubbo:reference id="uploadTokenService" interface="com.company.support.service.UploadTokenService"/> <dubbo:reference id="factoryService" interface="com.company.cngl.service.dubbo.IFactoryService"/> <dubbo:reference id="tokenVerifyService" interface="com.company.service.lgn.TokenVerifyService"/> <dubbo:reference interface="com.company.rent.service.IDemoService" url="dubbo://localhost:20881" check="false"></dubbo:reference>
Dubbo生產者配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd "> <!-- Rent 提供的服務 --> <dubbo:service interface="com.company.rent.service.IRentMtService" ref="iRentMtService"/> <dubbo:service interface="com.company.rent.service.IDemoService" ref="iDemoService"/> <dubbo:service interface="com.company.rent.service.IRentCustomerService" ref="iRentCustomerService"/> <dubbo:service interface="com.company.rent.service.IRentOrderService" ref="iRentOrderService"/> <dubbo:service interface="com.company.rent.service.IRentCompanyService" ref="iRentCompanyService"/> <dubbo:service interface="com.company.rent.service.IRentBillService" ref="iRentBillService"/> <dubbo:service interface="com.company.rent.service.IRentContractService" ref="iRentContractService"/> <dubbo:service interface="com.company.rent.service.IRentMtDataService" ref="iRentMtDataService"/> </beans>
數據源及事務配置
/** * 自定義數據源配置 * @author: Owen Jia * @time: 2018/12/20 13:49 */ @Configuration @EnableJpaAuditing @EnableJpaRepositories(basePackages = "com.isesol") @EnableAspectJAutoProxy public class DataSourceConfig { @Value("${jdbc.driver}") String driverClassName; @Value("${jdbc.url}") String url; @Value("${jdbc.username}") String username; @Value("${jdbc.password}") String password; @Value("${jdbc.pool.maxActive}") int maxActive; @Value("${jdbc.pool.initialSize}") int initialSize; @Value("${jdbc.pool.maxWait}") int maxWait; @Value("${jdbc.pool.minIdle}") int minIdle; @Bean(name = "dataSource",autowire = Autowire.BY_TYPE) public DataSource initDurid() { DruidDataSource druid = new DruidDataSource(); druid.setUrl(url); druid.setDriverClassName(driverClassName); druid.setUsername(username); druid.setPassword(password); try { druid.setFilters("stat"); } catch (SQLException e) { e.printStackTrace(); } druid.setMaxActive(maxActive); druid.setInitialSize(initialSize); druid.setMaxWait(maxWait); druid.setMinIdle(minIdle); druid.setValidationQuery("select user()"); druid.setTimeBetweenEvictionRunsMillis(180000); druid.setMinEvictableIdleTimeMillis(300000); druid.setTestWhileIdle(true); druid.setTestOnBorrow(true); druid.setTestOnReturn(false); //配置druid鏈接超時佔用強制回收,owen jia at 20190211 druid.setRemoveAbandoned(true); druid.setRemoveAbandonedTimeout(600); druid.setLogAbandoned(true); druid.setPoolPreparedStatements(true); druid.setMaxOpenPreparedStatements(200); druid.setProxyFilters(Lists.newArrayList(initLogFilter(),initStatFilter())); return druid; } @Bean(name = "jdbcTemplate") public JdbcTemplate initJdbcTemplate(){ return new JdbcTemplate(initDurid()); } @Bean(name = "log-filter") public Slf4jLogFilter initLogFilter(){ Slf4jLogFilter filter = new Slf4jLogFilter(); filter.setDataSourceLogEnabled(true); filter.setConnectionLogEnabled(true); filter.setResultSetLogEnabled(true); filter.setStatementExecutableSqlLogEnable(true); filter.setStatementLogEnabled(true); return filter; } @Bean(name = "stat-filter") public StatFilter initStatFilter(){ StatFilter statFilter = new StatFilter(); statFilter.setSlowSqlMillis(180000); statFilter.setLogSlowSql(true); statFilter.setMergeSql(true); statFilter.setConnectionStackTraceEnable(true); return statFilter; } @Value("${hibernate.hbm2ddl.auto}") String hbm2ddlAuto; @Value("${hibernate.show_sql}") String showSql; @Value("${hibernate.format_sql}") String formatSql; @Bean(name = "entityManagerFactory") public LocalContainerEntityManagerFactoryBean initFactoryBean() { LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); factoryBean.setDataSource(initDurid()); factoryBean.setJpaVendorAdapter(initHibernateJpaVendorAdapter()); factoryBean.setPersistenceUnitName("default"); factoryBean.setPackagesToScan("com.company.rent"); Properties jpaProp = new Properties(); jpaProp.setProperty("hibernate.hbm2ddl.auto",hbm2ddlAuto); jpaProp.setProperty("hibernate.show_sql",showSql); jpaProp.setProperty("hibernate.format_sql",formatSql); jpaProp.setProperty("hibernate.physical_naming_strategy", ImprovedNamingStrategy.class.getName()); // Owen Jia at 20190211 //配置鏈接釋放模式:after_statement 請求執行後釋放,after_transaction 事務提交後釋放,on_close session主動關閉釋放 jpaProp.setProperty("hibernate.connection.release_mode","after_transaction");//"on_close" factoryBean.setJpaProperties(jpaProp); return factoryBean; } @Bean(name = "hibernateJpaVendorAdapter") public HibernateJpaVendorAdapter initHibernateJpaVendorAdapter(){ HibernateJpaVendorAdapter jpaVendor = new HibernateJpaVendorAdapter(); jpaVendor.setDatabasePlatform(Hibernates.getDialect(initDurid())); return jpaVendor; } @Bean(name = "transactionManager") public JpaTransactionManager initJapTransactionM(){ JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(); jpaTransactionManager.setEntityManagerFactory(initFactoryBean().getNativeEntityManagerFactory()); return jpaTransactionManager; } @Bean(name = "transactionTemplate") public TransactionTemplate initTransactionTemplate(){ TransactionTemplate transactionTemplate = new TransactionTemplate(); transactionTemplate.setTransactionManager(initJapTransactionM()); return transactionTemplate; } }
Yaml文件配置,只給出相關特別配置,其餘都是常規
debug=true logging.config=classpath:log4j2.xml spring.profiles.active=${ENV:dev} spring.http.encoding.charset=UTF-8 spring.http.encoding.enabled=true spring.http.encoding.force=true spring.datasource.type=com.alibaba.druid.pool.DruidDataSource server.context-path=/ server.port=8080 server.session.timeout=20 server.tomcat.uri-encoding=utf-8
做者:Owen Jia
推薦關注他的博客:Owen Blog,裏面大量優質博文。