web-dev-qa-db-ja.com

JPAとHibernateを使用してJOINを持つエンティティを削除する方法

次のエンティティがあります。

enter image description here

JPAを使用しているユーザーのIDとユーザー名でワードセットを削除したい。

エンティティ宣言は次のとおりです。

ユーザー

@Entity
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
public class User extends AbstractModelClass {

    private String name;
    private String username;
    private String password;
    private String email;

    @ManyToMany(fetch = FetchType.EAGER)
    private Set<Role> roles;
}

UserDictionary

@Entity
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
public class UserDictionary extends AbstractModelClass {

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "userDictionary")
    private Set<WordSet> wordSets;

    @OneToOne(cascade = CascadeType.ALL)
    private User user;

    @PrePersist
    private void addDictionaryToWordSets() {
        wordSets.forEach(wordSet -> wordSet.setUserDictionary(this));
    }
}

WordSet

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true, exclude = {"studiedWords", "userDictionary"})
@ToString(callSuper = true, exclude = {"studiedWords", "userDictionary"})
public class WordSet extends AbstractModelClass {

    @NotBlank
    private String name;

    @NotBlank
    private String description;

    @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
    private List<StudiedWord> studiedWords;

    @ManyToOne(fetch = FetchType.EAGER)
    private UserDictionary userDictionary;

    public WordSet(String name, String description, List<StudiedWord> studiedWords) {
        this.name = name;
        this.description = description;
        this.studiedWords = studiedWords;
    }

    public WordSet(Long id, String name, String description, List<StudiedWord> studiedWords) {
        super(id);
        this.name = name;
        this.description = description;
        this.studiedWords = studiedWords;
    }

    @PreRemove
    private void removeFromUserDictionary() {
        userDictionary.getWordSets().removeIf(this::equals);
    }
}

これが私のWordSetDaoの一部です。

@Override
public Optional<WordSet> findByIdAndUsername(long id, String username) {
    return findOrEmpty(() -> entityManager.createQuery(
            "SELECT w FROM WordSet w " +
                    "WHERE w.userDictionary.user.username = :username AND w.id = :id", WordSet.class)
                                          .setParameter("id", id)
                                          .setParameter("username", username)
                                          .getSingleResult());
}

@Override
public void deleteByIdAndUsername(long id, String username) {
    entityManager.createQuery(
            "DELETE FROM WordSet w WHERE w.userDictionary.user.username = :username AND w.id = :id")
                 .setParameter("id", id)
                 .setParameter("username", username)
                 .executeUpdate();
}

findByIdAndUsernameは正常に動作しますが、削除は次の例外をスローします。

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [/* delete FKs in join table */ delete from Word_set_studied_words where (Word_set_id) in (select id from Word_set where username=? and id=?)]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement

    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:982)
    at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.Java:894)
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:654)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.Java:846)
    at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.Java:65)
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:729)
    at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.Java:167)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.Java:134)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:317)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.Java:127)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.Java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.Java:115)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.Java:137)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.Java:111)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.Java:169)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.Java:63)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331)
    at io.github.solomkinmv.glossary.web.security.auth.JwtTokenAuthenticationProcessingFilter.successfulAuthentication(JwtTokenAuthenticationProcessingFilter.Java:58)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.Java:240)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.Java:121)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.Java:66)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.Java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.Java:56)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.Java:214)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.Java:177)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.Java:134)
    at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.Java:155)
    at io.github.solomkinmv.glossary.web.controller.WordSetControllerTest.deleteWordSet(WordSetControllerTest.Java:236)
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.Java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.Java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.Java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.Java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.Java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.Java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.Java:86)
    at org.springframework.restdocs.JUnitRestDocumentation$1.evaluate(JUnitRestDocumentation.Java:55)
    at org.junit.rules.RunRules.evaluate(RunRules.Java:20)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.Java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.Java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.Java:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.Java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.Java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.Java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.Java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.Java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.Java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.Java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.Java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.Java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.Java:191)
    at org.junit.runner.JUnitCore.run(JUnitCore.Java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.Java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.Java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.Java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.Java:70)
Caused by: org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [/* delete FKs in join table */ delete from Word_set_studied_words where (Word_set_id) in (select id from Word_set where username=? and id=?)]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.Java:261)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.Java:244)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.Java:491)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.Java:59)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.Java:213)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.Java:147)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.Java:656)
    at io.github.solomkinmv.glossary.persistence.dao.impl.WordSetJpaDao$$EnhancerBySpringCGLIB$$48825a47.deleteByIdAndUsername(<generated>)
    at io.github.solomkinmv.glossary.service.domain.impl.WordSetServiceImpl.deleteByIdAndUsername(WordSetServiceImpl.Java:128)
    at io.github.solomkinmv.glossary.service.domain.impl.WordSetServiceImpl$$FastClassBySpringCGLIB$$c3da160a.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.Java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.Java:721)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.Java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.Java:282)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.Java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.Java:656)
    at io.github.solomkinmv.glossary.service.domain.impl.WordSetServiceImpl$$EnhancerBySpringCGLIB$$4b4a0f55.deleteByIdAndUsername(<generated>)
    at io.github.solomkinmv.glossary.web.controller.WordSetController.deleteWordSet(WordSetController.Java:79)
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.Java:220)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.Java:134)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.Java:116)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.Java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.Java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.Java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:970)
    ... 70 more
Caused by: org.hibernate.exception.SQLGrammarException: could not prepare statement
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.Java:106)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.Java:42)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.Java:109)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.Java:182)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareStatement(StatementPreparerImpl.Java:78)
    at org.hibernate.hql.internal.ast.exec.BasicExecutor.doExecute(BasicExecutor.Java:78)
    at org.hibernate.hql.internal.ast.exec.DeleteExecutor.execute(DeleteExecutor.Java:107)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.Java:429)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.Java:374)
    at org.hibernate.internal.SessionImpl.executeUpdate(SessionImpl.Java:1348)
    at org.hibernate.internal.QueryImpl.executeUpdate(QueryImpl.Java:102)
    at org.hibernate.jpa.internal.QueryImpl.internalExecuteUpdate(QueryImpl.Java:405)
    at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.Java:61)
    at io.github.solomkinmv.glossary.persistence.dao.impl.WordSetJpaDao.deleteByIdAndUsername(WordSetJpaDao.Java:50)
    at io.github.solomkinmv.glossary.persistence.dao.impl.WordSetJpaDao$$FastClassBySpringCGLIB$$3577673c.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.Java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.Java:721)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:157)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.Java:136)
    ... 98 more
Caused by: org.h2.jdbc.JdbcSQLException: Column "USERNAME" not found; SQL statement:
/* delete FKs in join table */ delete from Word_set_studied_words where (Word_set_id) in (select id from Word_set where username=? and id=?) [42122-193]
    at org.h2.message.DbException.getJdbcSQLException(DbException.Java:345)
    at org.h2.message.DbException.get(DbException.Java:179)
    at org.h2.message.DbException.get(DbException.Java:155)
    at org.h2.expression.ExpressionColumn.optimize(ExpressionColumn.Java:147)
    at org.h2.expression.Comparison.optimize(Comparison.Java:178)
    at org.h2.expression.ConditionAndOr.optimize(ConditionAndOr.Java:130)
    at org.h2.command.dml.Select.prepare(Select.Java:856)
    at org.h2.engine.Session.optimizeQueryExpression(Session.Java:233)
    at org.h2.expression.ConditionInSelect.optimize(ConditionInSelect.Java:117)
    at org.h2.command.dml.Delete.prepare(Delete.Java:131)
    at org.h2.command.Parser.prepareCommand(Parser.Java:259)
    at org.h2.engine.Session.prepareLocal(Session.Java:561)
    at org.h2.engine.Session.prepareCommand(Session.Java:502)
    at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.Java:1203)
    at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.Java:73)
    at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.Java:287)
    at Sun.reflect.GeneratedMethodAccessor93.invoke(Unknown Source)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:498)
    at org.Apache.Tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.Java:126)
    at org.Apache.Tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.Java:108)
    at org.Apache.Tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.Java:81)
    at com.Sun.proxy.$Proxy87.prepareStatement(Unknown Source)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$1.doPrepare(StatementPreparerImpl.Java:87)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.Java:172)
    ... 113 more

また、代わりに

DELETE FROM WordSet w WHERE w.userDictionary.user.username = :username AND w.id = :id

私は次のクエリを試しました:

DELETE FROM WordSet w 
WHERE w IN 
    (SELECT ws FROM UserDictionary u 
     JOIN u.wordSets ws 
     WHERE u.user.username = :username AND ws.id = :id)

そして、それは私のH2データベースで動作しますが、次の例外を除いてMySQLでは失敗します。

Java.sql.SQLException: You can't specify target table 'Word_set' for update in FROM clause
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.Java:964) ~[mysql-connector-Java-5.1.40.jar!/:5.1.40]
    ...

私はサブクエリとMySQL( onetwo )についてググったが、JPAでそのようなトリックを作る方法を見つけることができなかった。

では、ワードセットを削除するにはどうすればよいですか?エンティティマッピングに何か問題がありますか?

これが私のDBスキーマです。正しく見えます。

enter image description here

10
solomkinmv

このマッピングには、多くの誤りがあります。

  1. すべてのコレクションタイプにEAGERフェッチを使用することは、現在の問題よりもさらに問題です。実際には、任意のクエリでDB全体をフェッチしています。 この記事で説明されているようにLAZYに切り替えます
  2. あなたはそれがH2のために働くと言いました、しかしそれは真実ではありません:

    Caused by: org.h2.jdbc.JdbcSQLException: Column "USERNAME" not found; SQL statement:
    /* delete FKs in join table */ delete from Word_set_studied_words where (Word_set_id) in (select id from Word_set where username=? and id=?) [42122-193]
    at org.h2.message.DbException.getJdbcSQLException(DbException.Java:345)
    
  3. このタイプのクエリは、MySQLではサポートされていません。

    DELETE FROM WordSet w 
    WHERE w IN 
    (SELECT ws FROM UserDictionary u 
     JOIN u.wordSets ws 
     WHERE u.user.username = :username AND ws.id = :id)
    
  4. Hibernateユーザーガイド で説明されているように、結合は一括ステートメントで禁止されています。
  5. ここで、削除するエントリの数によっては、 バッチ更新の異常 を防ぐことができるため、 batch delete の方が適切なアプローチかもしれません。
  6. ここには相互接続されたエンティティのグラフがあるので、子の関連付けを先に削除しないと親レコードを削除できないため、一括削除が役に立たない場合があります。
12
Vlad Mihalcea

削除で通常の結合を試みましたか?同様の質問がここにあります: MySQLの結合で削除

... JPA経由ではありませんが、結合ベースの削除の例を示す承認済みの回答がありますが、MySQL固有のようです。

コツは、JOINを介して参照される他のテーブルがある場合、from句だけでなく、delete句自体に実際のテーブルを指定することです。

現在、mysqlに対してJPAをテストするように設定していません。 JQLはこれに対応できない可能性がありますが、ネイティブクエリを使用して実行できる可能性があります。

1
slambeth

Java.sql.SQLException:com.mysql.jdbc.SQLError.createSQLException(SQLError.Java:964)〜[mysql-connector-Java-5.1.40。 jar!/:5.1.40]

MySQLではSELECT部分​​で使用するのと同じテーブルを変更/削除できないため、この例外が発生します。ここでこの動作を文書化しました https://dev.mysql.com/doc/refman/5.6/en/update.html 。ソリューション1)サブクエリをfrom句に深くネストするか、2)テーブルをそれ自体に結合する

0
Alexey Semenyuk