我开发了带有Spring引导的简单商店应用程序。我的应用程序使用部署在码头容器中的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
}
model/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
}
model/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不起作用。如果需要,我可以上传更多的源代码。
发布于 2022-07-13 00:03:56
基于我们对评论的对话,使用参数模式对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兼容性模式指定,否则所有未引用的标识符都将区分大小写。由
https://stackoverflow.com/questions/72959168
复制相似问题