Spring Boot+PostgreSQL执行DDL报错:关键字order冲突问题
问题描述
我正在用Java Spring Boot开发API,完成POST接口后测试返回400 Bad Request错误,终端抛出如下异常:
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table restaurant_orders (id uuid not null, address varchar(25) not null, block varchar(5), customer_name varchar(11) not null, door_number varchar(10) not null, order varchar(30) not null, phone_number varchar(15) not null, price float4 not null, registration_date timestamp(6) not null, primary key (id))" via JDBC Statement at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlString(AbstractSchemaMigrator.java:587) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlStrings(AbstractSchemaMigrator.java:532) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.createTable(AbstractSchemaMigrator.java:307) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.performTablesMigration(GroupedSchemaMigratorImpl.java:79) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:225) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:126) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:284) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.lambda$process$5(SchemaManagementToolCoordinator.java:143) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] at java.base/java.util.HashMap.forEach(HashMap.java:1429) ~[na:na] at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:140) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:336) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:415) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1425) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:66) ~[spring-orm-6.0.4.jar:6.0.4] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376) ~[spring-orm-6.0.4.jar:6.0.4] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-6.0.4.jar:6.0.4] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-6.0.4.jar:6.0.4] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352) ~[spring-orm-6.0.4.jar:6.0.4] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1797) ~[spring-beans-6.0.4.jar:6.0.4] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1747) ~[spring-beans-6.0.4.jar:6.0.4] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[spring-beans-6.0.4.jar:6.0.4] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.4.jar:6.0.4] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.4.jar:6.0.4] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.4.jar:6.0.4] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.4.jar:6.0.4] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.4.jar:6.0.4] at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1130) ~[spring-context-6.0.4.jar:6.0.4] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:905) ~[spring-context-6.0.4.jar:6.0.4] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[spring-context-6.0.4.jar:6.0.4] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.0.2.jar:3.0.2] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-3.0.2.jar:3.0.2] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[spring-boot-3.0.2.jar:3.0.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-3.0.2.jar:3.0.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-3.0.2.jar:3.0.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[spring-boot-3.0.2.jar:3.0.2] at com.api.order_control.OrderControlApplication.main(OrderControlApplication.java:12) ~[classes/:na] Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "order" Position: 169 at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2676) ~[postgresql-42.5.1.jar:42.5.1] at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2366) ~[postgresql-42.5.1.jar:42.5.1] at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:356) ~[postgresql-42.5.1.jar:42.5.1] at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:496) ~[postgresql-42.5.1.jar:42.5.1] at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:413) ~[postgresql-42.5.1.jar:42.5.1] at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:333) ~[postgresql-42.5.1.jar:42.5.1] at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:319) ~[postgresql-42.5.1.jar:42.5.1] at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:295) ~[postgresql-42.5.1.jar:42.5.1] at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:290) ~[postgresql-42.5.1.jar:42.5.1] at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:94) ~[HikariCP-5.0.1.jar:na] at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java) ~[HikariCP-5.0.1.jar:na] at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final] ... 36 common frames omitted
我查资料后以为是表名涉及PostgreSQL关键字,于是把表名改成orders_restaurant,但问题依旧。相关Model和Controller代码如下:
Model代码
package com.api.order_control.models; import jakarta.persistence.*; import java.io.Serializable; import java.time.LocalDateTime; import java.util.UUID; @Entity @Table(name = "restaurant_orders") public class OrderModel implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private UUID id; @Column(nullable = false, length = 11) private String customerName; @Column(nullable = false, length = 15) private String phoneNumber; @Column(nullable = false, length = 25) private String address; @Column(nullable = false, length = 10) private String doorNumber; @Column(nullable = true, length = 5) private String block; @Column(nullable = false, length = 30) private String order; @Column(nullable = false) private Float price; @Column(nullable = false) private LocalDateTime registrationDate; public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } public String getCustomerName() { return customerName; } public void setCustomerName(String customerName) { this.customerName = customerName; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getDoorNumber() { return doorNumber; } public void setDoorNumber(String doorNumber) { this.doorNumber = doorNumber; } public String getBlock() { return block; } public void setBlock(String block) { this.block = block; } public String getOrder() { return order; } public void setOrder(String order) { this.order = order; } public Float getPrice() { return price; } public void setPrice(Float price) { this.price = price; } public LocalDateTime getRegistrationDate() { return registrationDate; } public void setRegistrationDate(LocalDateTime registrationDate) { this.registrationDate = registrationDate; } }
Controller代码
package com.api.order_control.controllers; import com.api.order_control.dtos.OrderDto; import com.api.order_control.models.OrderModel; import com.api.order_control.services.OrderService; import jakarta.validation.Valid; import org.springframework.beans.BeanUtils; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.time.ZoneId; @RestController @CrossOrigin(origins = "*", maxAge = 3600) @RequestMapping("/order") public class OrderController { final OrderService orderService; public OrderController(OrderService orderService) { this.orderService = orderService; } @PostMapping public ResponseEntity<Object> saveOrder(@RequestBody @Valid OrderDto orderDto) { var orderModel = new OrderModel(); BeanUtils.copyProperties(orderDto, orderModel); orderModel.setRegistrationDate(LocalDateTime.now(ZoneId.of("UTC"))); orderModel.setPrice(70.8f); return ResponseEntity.status(HttpStatus.CREATED).body(orderService.save(orderModel)); } }
解决方案
问题根源
异常信息明确指向syntax error at or near "order",核心问题是实体类中的order字段名是PostgreSQL的保留关键字,和表名无关,之前修改表名的操作没触碰到问题本质。
两种修复方式
1. 修改字段名(推荐)
直接将实体类中的order字段替换为非关键字名称,比如orderContent或orderItems,同步更新注解和getter/setter:
@Column(nullable = false, length = 30) private String orderContent; public String getOrderContent() { return orderContent; } public void setOrderContent(String orderContent) { this.orderContent = orderContent; }
同时更新OrderDto中的对应字段,确保BeanUtils.copyProperties能正确映射数据。
2. 转义关键字字段
如果不想修改字段名,可通过@Column注解指定转义后的数据库字段名,PostgreSQL中用双引号包裹关键字:
@Column(name = "\"order\"", nullable = false, length = 30) private String order;
这种方式会让Hibernate生成的DDL中字段名为"order",避免关键字冲突,但后续编写原生SQL时也需要用双引号引用该字段,维护成本较高。
后续操作
- 删除数据库中已生成的错误表(若存在)
- 重启应用,让Hibernate重新生成正确的表结构
- 测试POST接口,确认400错误消失
内容的提问来源于stack exchange,提问作者Routfin
相关产品推荐
相关产品推荐

