尝试在我的spring-boot应用程序上运行测试时,我得到以下异常:
org.hibernate.tool.schema.spi.SchemaManagementException: 模式验证:缺少表[T_ANSWER]
中的列[值]
我的配置如下:
@Bean(destroyMethod = "shutdown")
@Profile("!" + Constants.SPRING_PROFILE_CLOUD)
public DataSource dataSource() {
log.debug("Configuring Datasource");
if (propertyResolver.getProperty("url") == null && propertyResolver.getProperty("databaseName") == null) {
log.error("Your database connection pool configuration is incorrect! The application" +
"cannot start. Please check your Spring profile, current profiles are: {}",
Arrays.toString(env.getActiveProfiles()));
throw new ApplicationContextException("Database connection pool is not configured correctly");
}
HikariConfig config = new HikariConfig();
config.setDataSourceClassName(propertyResolver.getProperty("dataSourceClassName"));
if (propertyResolver.getProperty("url") == null || "".equals(propertyResolver.getProperty("url"))) {
config.addDataSourceProperty("databaseName", propertyResolver.getProperty("databaseName"));
config.addDataSourceProperty("serverName", propertyResolver.getProperty("serverName"));
} else {
config.addDataSourceProperty("url", propertyResolver.getProperty("url"));
}
config.addDataSourceProperty("user", propertyResolver.getProperty("username"));
config.addDataSourceProperty("password", propertyResolver.getProperty("password"));
//MySQL optimizations, see https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration
if ("com.mysql.jdbc.jdbc2.optional.MysqlDataSource".equals(propertyResolver.getProperty("dataSourceClassName"))) {
config.addDataSourceProperty("cachePrepStmts", propertyResolver.getProperty("cachePrepStmts", "true"));
config.addDataSourceProperty("prepStmtCacheSize", propertyResolver.getProperty("prepStmtCacheSize", "250"));
config.addDataSourceProperty("prepStmtCacheSqlLimit", propertyResolver.getProperty("prepStmtCacheSqlLimit", "2048"));
config.addDataSourceProperty("useServerPrepStmts", propertyResolver.getProperty("useServerPrepStmts", "true"));
}
return new HikariDataSource(config);
}
@Bean
public SpringLiquibase liquibase(DataSource dataSource) {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog("classpath:config/liquibase/master.xml");
liquibase.setContexts("development, production");
if (env.acceptsProfiles(Constants.SPRING_PROFILE_FAST)) {
if ("org.h2.jdbcx.JdbcDataSource".equals(propertyResolver.getProperty("dataSourceClassName"))) {
liquibase.setShouldRun(true);
log.warn("Using '{}' profile with H2 database in memory is not optimal, you should consider switching to" +
" MySQL or Postgresql to avoid rebuilding your database upon each start.", Constants.SPRING_PROFILE_FAST);
} else {
liquibase.setShouldRun(false);
}
} else {
log.debug("Configuring Liquibase");
}
return liquibase;
}
@Bean
public Hibernate4Module hibernate4Module() {
return new Hibernate4Module();
}
我的配置文件如下所示:
spring:
profiles:
active: dev
datasource:
dataSourceClassName: org.h2.jdbcx.JdbcDataSource
url: jdbc:h2:mem:questionnaires;DB_CLOSE_DELAY=-1
databaseName:
serverName:
username:
password:
jpa:
database-platform: org.hibernate.dialect.H2Dialect
database: H2
openInView: false
show_sql: true
properties:
hibernate.cache.use_second_level_cache: true
hibernate.cache.use_query_cache: false
hibernate.generate_statistics: true
hibernate.hbm2ddl.auto: update
hibernate.cache.region.factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
导致问题的实体称为Answer,它没有value属性,但它的一些子代有,这里是实体和相关子代的实现。
答案:
@Entity
@Table(name = "T_ANSWER")
public abstract class Answer {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private long id;
private String innerID;
public Answer(){
innerID = UUID.randomUUID().toString();
}
@ManyToOne
private AnswerTab parentTab;
public String getInnerID() {
return innerID;
}
public void setInnerID(String innerID) {
this.innerID = innerID;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public AnswerTab getParentTab() {
return parentTab;
}
public void setParentTab(AnswerTab parentTab) {
this.parentTab = parentTab;
}
}
以及具有value属性的子项:
@Entity
@Table(name = "T_SINGLEANSWER")
public class SingleAnswer extends Answer{
private String value = "";
@ManyToOne
private AnswerRow parentRow;
public SingleAnswer(){
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public AnswerRow getParentRow() {
return parentRow;
}
public void setParentRow(AnswerRow parentRow) {
this.parentRow = parentRow;
}
@Override
public Answer copy() {
SingleAnswer copy = new SingleAnswer();
copy.setInnerID(getInnerID());
copy.setValue(value);
return copy;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof SingleAnswer){
return value.compareTo(((SingleAnswer)obj).getValue()) == 0;
}
return super.equals(obj);
}
}
我检查了生成的数据库,我可以清楚地看到表T_ANSWER有一个值属性。
这是创建表的liquibase变更集:
<createTable tableName="t_answer">
<column name="DTYPE" type="VARCHAR(31)">
<constraints nullable="false"/>
</column>
<column autoIncrement="true" name="id" type="BIGINT(19)">
<constraints primaryKey="true"/>
</column>
<column name="innerID" type="VARCHAR(255)"/>
<column name="value" type="VARCHAR(255)"/>
<column name="dynamic" type="BIT(1)"/>
<column name="size" type="INT(10)"/>
<column name="parentTab_id" type="BIGINT(19)"/>
<column name="parentRow_id" type="BIGINT(19)"/>
<column name="parentGroup_id" type="BIGINT(19)"/>
</createTable>
答案 0 :(得分:2)
我也面临同样的问题。这是由于表属性名称的驼峰情况。对我来说,通过替换下面的代码消失了。我在db-config.properties文件中更改了它。
spring.jpa.hibernate.ddl-auto:validate
到
spring.jpa.hibernate.ddl-auto:update
注意:无论您使用的是弹簧启动还是弹簧元数据配置文件(xml),都可以使用。