QueryDSL Update错误:具有根本原因的[执行更新/删除查询]

时间:2018-12-27 15:59:19

标签: java jpa querydsl

我收到此错误:

  

javax.persistence.TransactionRequiredException:执行更新/删除查询

我没有找到解决方法。似乎与我的代码中的@Transactional批注有关:

@Service
@Transactional(rollbackFor = Exception.class, value = "transactionManager")
public class WxLoginServiceImpl implements WxService {

...但是我不知道该如何修改。

修改初始化创建后我遇到了这个问题,所以我认为这个问题是由于初始化之后的时间造成的。

完整错误是:

2018-12-27 23:35:59.959 ERROR 18525 --- [nio-8888-exec-2] o.a.c.c.C.[.[.[.[dispatcherServlet]      : 
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception 
[Request processing failed; 
   nested exception is javax.persistence.TransactionRequiredException: 
   Executing an update/delete query] with root cause

javax.persistence.TransactionRequiredException: Executing an update/delete query
    at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1586) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at com.querydsl.jpa.impl.JPAUpdateClause.execute(JPAUpdateClause.java:77) ~[querydsl-jpa-4.1.4.jar:?]
    at com.genius.martial.service.impl.WxLoginServiceImpl.updateUserGroupByOpenId(WxLoginServiceImpl.java:87) ~[classes/:?]
    at com.genius.martial.service.impl.WxLoginServiceImpl$$FastClassBySpringCGLIB$$7b7d6928.invoke(<generated>) ~[classes/:?]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) ~[spring-tx-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at com.genius.martial.service.impl.WxLoginServiceImpl$$EnhancerBySpringCGLIB$$63521827.updateUserGroupByOpenId(<generated>) ~[classes/:?]
    at com.genius.martial.controller.WxController.updateUserGroupByOpenId(WxController.java:63) ~[classes/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_131]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_131]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.13.jar:9.0.13]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_131]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_131]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131]

这是数据库Java代码:

DBDataSourceConfig.java

package com.genius.martial.config;

import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.pool.DruidDataSource;
import lombok.extern.log4j.Log4j2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jndi.JndiObjectFactoryBean;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.sql.Connection;


@Configuration
@Log4j2
public class DBDataSourceConfig {
@Value("${spring.datasource.jndi-name:}")
private String jndiUrl;
@Value("${spring.datasource.jdbc-url:aaa}")
private String dbUrl;
@Value("${spring.datasource.username:ick_rcb}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.driver-class-name:oracle.jdbc.driver.OracleDriver}")
private String driverClassName;
@Value("${spring.datasource.initialSize:1}")
private int initialSize;
@Value("${spring.datasource.minIdle:5}")
private int minIdle;
@Value("${spring.datasource.maxActive:30}")
private int maxActive;
@Value("${spring.datasource.maxWait:3000}")
private int maxWait;
@Value("${spring.datasource.validationQuery:select 'x' from dual}")
protected String validationQuery;
@Value("${spring.datasource.testOnBorrow:true}")
private boolean testOnBorrow;
@Value("${spring.datasource.testOnReturn:true}")
private boolean testOnReturn;
@Value("${spring.datasource.queryTimeout:0}")
private int queryTimeout;

@Bean(name = "dbDataSource")
@Primary
public DataSource dbDataSource() throws Exception {
    return createDataSource();
}

@Primary
@Bean(name = "transactionManager")
public DataSourceTransactionManager dbTransactionManager() throws Exception {
    return new DataSourceTransactionManager(dbDataSource());
}


@Bean(name = "JdbcTemplate")
public JdbcTemplate JdbcTemplate(
        @Qualifier("dbDataSource") DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

@Primary
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean
entityManagerFactory() throws Exception {
    HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
    jpaVendorAdapter.setGenerateDdl(true);

    LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
    factoryBean.setDataSource(dbDataSource());
    factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
    factoryBean.setPackagesToScan("com.genius.martial.entity.DO");

    return factoryBean;
}

@Primary
@Bean(name = "entityManager")
public EntityManager entityManager() throws Exception {
    return entityManagerFactory().getObject().createEntityManager();
}

@Bean(name = "transactionManager")
PlatformTransactionManager transactionManagerSecondary() throws Exception {
    return new JpaTransactionManager(entityManagerFactory().getObject());
}


/**
 * 创建数据源
 *
 * @return
 * @throws NamingException
 * @throws IllegalArgumentException
 */
protected DataSource createDataSource() throws IllegalArgumentException, NamingException {
    DataSource dataSource ;
    log.info("[datasource] 初始化数据库连接池...");
    if (StrUtil.isBlank(jndiUrl)) {
        log.info("[datasource] 使用连接配置属性");
        Object[] params = {getDbUrl(), getUsername(), getPassword(), getDriverClassName(), initialSize, minIdle, maxActive, maxWait, testOnReturn, getValidationQuery(), testOnBorrow};
        log.info("[datasource] url: {}, username: {}, password: {}, driver: {}, initialSize: {}, minIdle: {}, maxActive: {}, maxWait: {}, testOnReturn: {}" +
                " validationQuery: {}, testOnBorrow: {}", params);
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(getDbUrl());
        datasource.setUsername(getUsername());
        datasource.setPassword(getPassword());
        datasource.setDriverClassName(getDriverClassName());
        datasource.setQueryTimeout(queryTimeout);

        //configuration
        datasource.setInitialSize(initialSize);
        datasource.setMinIdle(minIdle);
        datasource.setMaxActive(maxActive);
        datasource.setMaxWait(maxWait);
        datasource.setTestOnReturn(testOnReturn);
        datasource.setValidationQuery(getValidationQuery());
        datasource.setTestOnBorrow(testOnBorrow);
        dataSource = datasource;
    } else {
        log.info("[datasource] 连接到jndi({})...", jndiUrl);
        //连接jndi
        JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
        bean.setJndiName(jndiUrl);
        bean.setProxyInterface(DataSource.class);
        bean.setLookupOnStartup(false);
        bean.afterPropertiesSet();
        dataSource = (DataSource) bean.getObject();
    }
    try(Connection connection = dataSource.getConnection()) {
    } catch (Exception e) {enter code here
        log.error("[datasource] 连接失败!", e);
    }

    return dataSource;
}

public String getDbUrl() {
    return dbUrl;
}

public String getUsername() {
    return username;
}

public String getPassword() {
    return password;
}

public String getDriverClassName() {
    return driverClassName;
}

public String getValidationQuery() {
    return validationQuery;
}

}

这是我的服务代码:

WxLoginServiceImpl.java

package com.genius.martial.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.genius.martial.dao.WxRepository;
import com.genius.martial.entity.DO.QWxUserInfoPOJO;
import com.genius.martial.entity.DO.WxUserInfoPOJO;
import com.genius.martial.exception.BusinessException;
import com.genius.martial.service.WxService;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import javax.persistence.EntityManager;

import javax.annotation.PostConstruct;
import javax.persistence.Transient;



/**
 * @description:
 * @author: Jihaotian
 * @create: 2018-12-09 21:07
 **/

@Service
@Transactional(rollbackFor = Exception.class, value = "transactionManager")
public class WxLoginServiceImpl implements WxService {

    @Autowired
    private WxRepository wxRepository;

    //实体管理
    @Autowired
    private EntityManager entityManager;

    //查询工厂
    private JPAQueryFactory queryFactory;

    //初始化查询工厂
    @PostConstruct
    public void init()
    {
        queryFactory = new JPAQueryFactory(entityManager);
    }


    @Value("${wx.AppID}")
    private String appId;

    @Value("${wx.AppSecret}")
    private String appSecret;


    @Override
    public JSONObject getWxUnique(String code) {
        RestTemplate restTemplate = new RestTemplate();
        String wxUserInfo = restTemplate.getForObject("https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code", String.class);
        JSONObject wxUserInfoJson = JSON.parseObject(wxUserInfo);
        return wxUserInfoJson;
    }

    @Override
    public void updateWxUserInfo(WxUserInfoPOJO userInfo) {
        wxRepository.save(userInfo);
    }

    @Override
    @Modifying
    public void updateUserGroupByOpenId(String group, String openid) {
        if (StrUtil.isEmpty(group)||StrUtil.isEmpty(openid)){
            throw new BusinessException("数据不能为空,请刷新后重试");
        }
        if (ObjectUtil.isNull(wxRepository.findByOpenId(openid))){
            throw new BusinessException("没有该用户,请重试!");
        }
        QWxUserInfoPOJO qWxUserInfoPOJO = QWxUserInfoPOJO.wxUserInfoPOJO;
        queryFactory.update(qWxUserInfoPOJO).where(qWxUserInfoPOJO.openId.eq(openid))
                .set(qWxUserInfoPOJO.groupName,group)
                .execute();
    }
}

0 个答案:

没有答案