我使用Spring JPA,Hibernate 5.2创建了一个Spring Boot 1.5项目。我创建了架构设置:
spring.jpa.hibernate.ddl-auto: create
然后我停止了我的应用程序,并重新启动了应用程序,其值为:
spring.jpa.hibernate.ddl-auto: validate
我是这样的豆子:
@Entity
@Table(uniqueConstraints = { @UniqueConstraint(name = "account_username", columnNames = { "username" }) })
public class Account extends AbstractEntity implements CustomUserDetail {
@NotBlank
@Username
@Column(nullable = false/* , unique = true */)
private String username;
private String password;
private Instant lastPasswordUpdate;
@NotNull
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private AccountType type = AccountType.USER;
@NotNull
@Column(nullable = false, columnDefinition = "BOOLEAN default true")
private boolean enabled = true;
@Audited
@Size(min = 1)
@Type(type = "json")
@Column(columnDefinition = "json")
private Roles[] roles = new Roles[] {};
生成的表格如下:
CREATE TABLE `account` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`createdBy` varchar(255) DEFAULT NULL,
`createdDate` datetime DEFAULT NULL,
`lastModifiedBy` varchar(255) DEFAULT NULL,
`lastModifiedDate` datetime DEFAULT NULL,
`sid` varchar(36) NOT NULL,
`version` bigint(20) NOT NULL,
`enabled` tinyint(1) NOT NULL DEFAULT '1',
`lastPasswordUpdate` datetime DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`roles` json DEFAULT NULL,
`type` varchar(255) NOT NULL,
`username` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `account_username` (`username`),
UNIQUE KEY `UK_5fs2lcge9gnvs1seea2fwnwv5` (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
当我使用valitate
选项启动应用程序时,出现此错误:
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: wrong column type encountered in column [enabled] in table [`Account`]; found [bit (Types#BIT)], but expecting [boolean default true (Types#BOOLEAN)]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateColumnType(AbstractSchemaValidator.java:159) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable(AbstractSchemaValidator.java:143) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.tool.schema.internal.GroupedSchemaValidatorImpl.validateTables(GroupedSchemaValidatorImpl.java:42) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:89) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:68) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:191) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:313) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:452) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:889) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
这很奇怪,因为原始模式是使用完全相同的配置创建的。
我使用了这些连接属性,并且我在Windows上使用MariaDB 10.2.13:
spring.datasource.url=jdbc:mysql://localhost:3310/rebus?useLegacyDatetimeCode=false&serverTimezone=UTC&tinyInt1isBit=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect (with MariaDB53Dialect it's the same)
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
我尝试了相同的配置(使用选项transformedBitIsBoolean
)和Mysql 5.7的驱动程序和方言,我没有任何问题。
我做错了吗?如何解决问题而不使我的模型与自定义类型一起变脏并保持原样干净?
=======更新============
调查和调试Hibernate的AbstractSchemaValidator
,这就是产生问题的路线:
boolean typesMatch = column.getSqlTypeCode( metadata ) == columnInformation.getTypeCode()
|| column.getSqlType( dialect, metadata ).toLowerCase(Locale.ROOT).startsWith( columnInformation.getTypeName().toLowerCase(Locale.ROOT) );
从column.getSqlTypeCode( metadata )
检测到的类型为16,而columnInformation.getTypeCode()
的类型为-7。当我使用Mysql时,两边的类型都是16。