spring-boot - 交叉加入 Spring Boot 2.1.4.RELEASE 应用程序

标签 spring-boot spring-mvc jpa spring-data-jpa spring-data

我有一个 SpringBoot 2.1.4.RELEASE RESTful Web 服务应用程序,使用 Spring Initializer、嵌入式 Tomcat、Thymeleaf 模板引擎,并打包为可执行 JAR 文件。我正在使用 inMemoryDatabase: H2 数据库引擎

 <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>

我有这些对象:
@Entity
@Table(name="t_menu_alert_notification")
public class MenuAlertNotification implements Serializable {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonProperty("id")
    private Long id;    



    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
    @JoinColumn(name = "menu_alert_id")
    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="name")
    @JsonIdentityReference(alwaysAsId=true)
    protected MenuAlert menuAlert;
...
}



@Entity
@Table(name="t_menu_alert")
public class MenuAlert implements Serializable {


    public MenuAlert() {
    }



    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "menu_id")
    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="name")
    @JsonIdentityReference(alwaysAsId=true)
    Menu menu;

..

}





@Entity
@Table(name = "t_menu")
@JsonPropertyOrder({ "id", "name", "address", "description" })
public class Menu implements Serializable {





    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonProperty("id")
    private Long id;



    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false)
    @JsonIgnore
    private User user;

..

}

我在从 CrudRepository 扩展的存储库类中有这个方法
@Transactional
    @Modifying
    @Query("update MenuAlertNotification n set n.read = :status where n.id in :notificationIdList and n.menuAlert.menu.user.id = :userId")
    void changeMenuNotificationListReadStatus(  @Param("notificationIdList") List<Long> notificationIdList, 
                                                    @Param("userId") long userId, 
                                                    @Param("status") boolean status);
}

但是当我运行这个方法时,我有这个错误:
org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [update t_menu_alert_notification cross join  set is_read=? where (id in (?)) and user_id=?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:279)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:253)

    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Caused by: org.hibernate.exception.SQLGrammarException: could not prepare statement
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
    ... 51 more
Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "UPDATE T_MENU_ALERT_NOTIFICATION CROSS[*] JOIN  SET IS_READ=? WHERE (ID IN (?)) AND USER_ID=? "; expected "., AS, SET"; SQL statement:
update t_menu_alert_notification cross join  set is_read=? where (id in (?)) and user_id=? [42001-197]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
    at org.h2.message.DbException.getSyntaxError(DbException.java:217)
    at org.h2.command.Parser.getSyntaxError(Parser.java:555)
    at org.h2.command.Parser.read(Parser.java:3518)
    at org.h2.command.Parser.parseUpdateSetClause(Parser.java:785)
    at org.h2.command.Parser.parseUpdate(Parser.java:780)
    at org.h2.command.Parser.parsePrepared(Parser.java:485)
    at org.h2.command.Parser.parse(Parser.java:335)
    at org.h2.command.Parser.parse(Parser.java:311)
    at org.h2.command.Parser.prepareCommand(Parser.java:278)
    at org.h2.engine.Session.prepareLocal(Session.java:611)
    at org.h2.engine.Session.prepareCommand(Session.java:549)
    at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1247)
    at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:76)
    at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:304)
    at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:311)
    at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$1.doPrepare(StatementPreparerImpl.java:87)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172)
    ... 73 more

最佳答案

据官方documentation :

No joins, either implicit or explicit, can be specified in a bulk HQL query.



所以你需要找到n.menuAlert首先,然后作为参数传递以更新查询或使用 native 查询。

关于spring-boot - 交叉加入 Spring Boot 2.1.4.RELEASE 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55807376/

相关文章:

java - 无法从异步方法获取应用程序属性

Spring自定义AuthenticationFailureHandler

java - Hibernate - 每个操作的 ThreadLocal<EntityManager> 与 EntityManager

spring-boot - Spring Boot 单元测试端点 NullPointerException - 以及如何达到 100% 的覆盖率

java - Springboot @ServerEndPoint "Failed to find the root WebApplicationContext."

spring-boot - heroku 中的 Java 版本错误

Java,Spring 测试,如何配置通常在 web.xml 中定义的日志记录?

java - 从 postman 点击 REST API 时出现 406 Not Acceptacle 错误

java - 在 Oracle 上使用 Hibernate 的死锁事务

java - 按不在分组依据中或封装在聚合中的列排序