[英]Spring Boot H2 db for testing throws "Table not found" and "SQL syntax error"
我使用 Spring Boot 开发简单的 Store 应用程序。 我的应用程序使用部署在 docker 容器中的 MySQL 数据库,并且运行良好。 现在我想测试我的应用程序,我得出的结论是H2 in-memory db
足以进行测试。 由于我刚开始测试 Spring 应用程序,我遇到了与在 H2 测试数据库中创建表相关的错误。 这些是我遇到的错误
第一个错误:
alter table store_order_items
drop
foreign key FKikqpbj6xmmyoblsolyhk250tq" via JDBC Statement
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlString(SchemaDropperImpl.java
[...]
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "STORE_ORDER_ITEMS" not found (this database is empty); SQL statement:
第二个错误:
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "
create table store_order_items (
Id bigint not null auto_increment,
quantity bigint,
order_Id bigint,
product_Id bigint,
primary key (Id)
) engine=InnoDB" via JDBC Statement
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.applySqlString(SchemaCreatorImpl.java:458) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
[...]
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "\000a create table store_order_items (\000a Id bigint not null auto_increment,\000a quantity bigint,\000a order_Id bigint,\000a product_Id bigint,\000a primary key (Id)\000a ) engine[*]=InnoDB"; expected "identifier"; SQL statement:
src/test/resources/ application.properties :
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.h2.console.enabled=true
logging.level.org.hibernate.SQL=DEBUG
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto=create
spring.jpa.generate-ddl=true
spring.jpa.defer-datasource-initialization=true
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
测试类:
@ExtendWith(SpringExtension.class)
@SpringBootTest
@Transactional
public class UserRepositoryTests {
private static final Logger LOGGER = Logger.getLogger(UserRepositoryTests.class.getName());
@Autowired
private UserRepositoryImpl userRepository;
@Autowired
private PasswordEncoder encoder;
@Test
void contextLoads() {
System.out.println(encoder.encode("123"));
// dummy test just to test if tables are built properly
}
模型/OrderItem.java:
@Entity
@Table(name = "store_order_items")
@NamedQueries({
@NamedQuery(name=OrderItem.ORDER_ITEM_FIND_ALL, query=OrderItem.ORDER_ITEM_FIND_ALL_JPQL)
})
public class OrderItem {
// get list of all orders
public static final String ORDER_ITEM_FIND_ALL = "orderItemAll";
public static final String ORDER_ITEM_FIND_ALL_JPQL = "SELECT oi FROM OrderItem oi";
// id will be replaced with two foreign keys
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Id;
private Long quantity;
@JsonBackReference
@ManyToOne
private Order order;
@JsonBackReference
@ManyToOne
private Product product;
// getters and setters omitted
}
模型/Order.java:
@Entity
@Table(name = "store_orders")
@NamedQueries({
@NamedQuery(name=Order.ORDER_FIND_ALL, query=Order.ORDER_FIND_ALL_JPQL),
@NamedQuery(name=Order.ORDER_SUMMARIES, query=Order.ORDER_SUMMARIES_JPQL)
})
public class Order {
// named queries omitted
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Id;
private String orderDate;
@JsonBackReference
@ManyToOne
private User user;
@JsonManagedReference
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<OrderItem> orderItems = new ArrayList<>();
// getters and setters omitted
}
我尝试更改列名或使用不同的spring.datasource.url
但 id 不起作用。 如果需要,我可以上传更多源代码。
根据我们对评论的对话,使用参数 MODE 对 OP 有效。 所以解决方案是从以下位置更改此配置:
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;
至
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL
注意MODE=MySQL
添加到末尾。 这将使 H2 数据库实现忽略某些 MySQL 保留字或将其替换为 (H2) 等效保留字。
Op 还必须更改另一种配置以解决所有问题,另一种是设置ddl-auto
设置:
spring.jpa.hibernate.ddl-auto=create
至
spring.jpa.hibernate.ddl-auto=update
另请注意Evgenij Ryazanov的评论,因此请检查您所在的版本并进行相应的更正:
DATABASE_TO_UPPER=FALSE
只能用于 H2 1.4.197 和旧版本,对于 H2 1.4.198 Beta 和更新版本DATABASE_TO_LOWER=TRUE
应该使用 MySQL 兼容模式指定,否则所有未加引号的标识符将区分大小写。 经过
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.