我在使用 Hibernate 时遇到问题。
我正在通过 Flyway 迁移创建表。
下面显示了部分初始迁移脚本的片段。
脚本确实运行了(我可以在 Debug模式下看到它)。
在脚本运行之后,Hibernate 的 validator 似乎没有使用我通过 javax.persistence
提供的实体的表名。 .
为了清楚起见,这里有一些遗漏的实体:
import javax.persistence.*;
@Entity
@Table(name = "IngredientCategories")
public class IngredientCategory implements IEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(nullable = false, length = 128)
private String name;
...
}
CREATE TABLE `IngredientCategories` (
`id` bigint NOT NULL AUTO_INCREMENT,
`description` varchar(255) DEFAULT NULL,
`name` varchar(128) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
查看日志,运行 Flyway 迁移,然后 之后 我收到 hibernate 验证错误。2020-10-24 11:22:11.952 DEBUG 91583 --- [ main] o.f.core.internal.command.DbMigrate : Successfully completed migration of schema `test` to version 1 - init
2020-10-24 11:22:11.961 DEBUG 91583 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Schema History table `test`.`flyway_schema_history` successfully updated to reflect changes
2020-10-24 11:22:11.970 INFO 91583 --- [ main] o.f.core.internal.command.DbMigrate : Successfully applied 1 migration to schema `test` (execution time 00:00.107s)
2020-10-24 11:22:11.972 DEBUG 91583 --- [ main] org.flywaydb.core.Flyway : Memory usage: 82 of 354M
2020-10-24 11:22:12.088 INFO 91583 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2020-10-24 11:22:12.125 INFO 91583 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.20.Final
2020-10-24 11:22:12.237 INFO 91583 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
2020-10-24 11:22:12.350 INFO 91583 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect
2020-10-24 11:22:12.998 WARN 91583 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [ingredient_categories]
2020-10-24 11:22:12.998 INFO 91583 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2020-10-24 11:22:13.420 INFO 91583 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
2020-10-24 11:22:13.428 INFO 91583 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-10-24 11:22:13.434 ERROR 91583 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [ingredient_categories]
我无法确定这是 hibernate 问题、Flyway 问题还是测试问题。这只是“启动”应用程序的测试:
@SpringBootTest
@Testcontainers
class DataApplicationTests {
@Test
void contextLoads() {
}
}
我环顾四周,可以看到很多人在 Spring 2x 之前遇到了一个问题,即在 Flyway 生成模式之前验证表... .我认为问题显示 Hibernate 期望表名的行
Schema-validation: missing table [ingredient_categories]
所以它似乎没有使用 javax.containt.Table @Table(name="IngredientCategories")
运行和构建上下文/bean 时的注释。应用程序属性并不过分令人兴奋...我正在使用 TestContainers:
#=========INTEGRATION TESTS========#
## Using TestContainers
spring.datasource.url=jdbc:tc:mysql:8.0.22:///
# Validate Schema
spring.jpa.hibernate.ddl-auto = validate
logging.level.org.flywaydb=DEBUG
最佳答案
来自官方 doc
By default, Spring Boot configures the physical naming strategy with SpringPhysicalNamingStrategy. This implementation provides the same table structure as Hibernate 4: all dots are replaced by underscores and camel casing is replaced by underscores as well. By default, all table names are generated in lower case, but it is possible to override that flag if your schema requires it.
For example, a TelephoneNumber entity is mapped to the telephone_number table.
所以
IngredientCategories
变成了ingredient_categories
.对于数据库表名一般约定使用蛇形大小写。您可以在蛇案例中创建带有名称的表CREATE TABLE `ingredient_categories`
或者,如果您更喜欢使用 Hibernate 5 的默认值,请设置以下属性:spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
那么你的表名仍然是 IngredientCategories
如 @Table
中所述注解。详情 Hibernate 5 Naming Strategy Configuration
关于java - 在启动时进行 DDL 验证时,Hibernate 不使用 @Table。使用 Flyway 和 TestContainers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64512485/