SQL语法中的JPA错误

时间:2012-12-19 20:45:43

标签: mysql sql spring-data

我使用Spring Data并创建了以下查询:

public interface UserRepository extends JpaRepository<User, Long>, QueryDslPredicateExecutor<User> {

    @Modifying
    @Query("DELETE FROM User u WHERE u.userDetails.userName = :username")
    public void deleteByUserName(@Param("username") String userName);
}

在运行时我继续得到:

ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'cross join UserDetails userdetail1_ where User_Name='rb2x5yv7'' at line 1

我使用MySql和MySQL5Dialect。

我的查询有什么问题?

**

UPDATE:

**

关注this帖子后,我更改了代码:

public interface UserRepository extends JpaRepository<User, Long>, QueryDslPredicateExecutor<User> {

    @Modifying
    @Query("DELETE FROM User u WHERE u.id in (SELECT u1.id FROM User WHERE u1.userDetails.userName = :username)")
    public void deleteByUserName(@Param("username") String userName);
}

但现在我得到了:

org.hibernate.QueryException: Unable to resolve path [u1.id], unexpected token [u1] [DELETE FROM com.bs.dal.domain.User u WHERE u.id in (SELECT u1.id FROM com.bs.dal.domain.User WHERE u1.userDetails.userName = :username)]

**

更新2:

**

看来我失踪了&#34; u1&#34;在子查询中。将查询更改为:

 @Query("DELETE FROM User u WHERE u.id in (SELECT u1.id FROM User u1 WHERE u1.userDetails.userName = :username)")

现在我得到了:

org.hibernate.exception.GenericJDBCException: You can't specify target table 'Users' for update in FROM clause.

我知道它发生了,因为您无法修改在SELECT部分​​中使用的同一个表。此行为记录在:dev.mysql.com/doc/refman/5.6/en/update.html。

我该如何解决?有什么建议吗?

2 个答案:

答案 0 :(得分:1)

为了使它成功,我必须做两件事:

第一个,使用此查询:

public interface UserRepository extends JpaRepository<User, Long>, QueryDslPredicateExecutor<User> {

    @Modifying
    @Query(name = "Delete User by UserName", value = "DELETE FROM User u WHERE u.id IN (SELECT ud.id FROM UserDetails ud WHERE ud.userName = :username)")
    public void deleteByUserName(@Param("username") String userName);
}

第二个:

我必须确保在数据库中很好地实现了删除级联。出于某种原因,它不是自动生成的。您可以看到与此相关的my new thread

答案 1 :(得分:0)

DELETE statement中分配表别名的正确方法是:

DELETE u FROM User u WHERE u.userName = :username
       ^

当然,如果只涉及一个表,你可以简单地省略别名:

DELETE FROM User WHERE userName = :username