跳过特定 table [Spring] [Hibernate] 的创建

Skipping creation of a specific table [Spring] [Hibernate]

我正在创建一些简单的 spring 项目(spring 安全性),其中的配置文件确定一些简单的值,例如 table 名称等。我在那里定义了一个布尔字段 REQUIRED_ACTIVATION 用于确定新用户是否必须通过例如通过邮件发送的激活 link 来激活他的帐户。

public static final boolean REQUIRED_ACTIVATION = true;

如果我将 REQUIRED_ACTIVATION 值设置为 false 用户在注册后立即处于活动状态。我已经定义了包含激活数据的实体 links:

@Entity
@Table(name = 'user_activation_link')
public class UserActivationLink {
   [...]
}

当 REQUIRED_ACTIVATION 设置为 false 时,我不会在任何地方使用此 class,而是在数据库中创建 table。是否有任何解决方案来确定是否将根据 REQUIRED_ACTIVATION 的值创建 table?

如果您将 Hibernate 与 spring.jpa.hibernate.ddl-auto = create / create-drop 一起使用,那么它会尝试创建一个 table 如果在每次启动时不存在,如果如果不存在,则使用更新创建一次,并且在每次启动时只更新 table。

作为替代尝试在 Spring:

中使用 Application Listener
@Value("${required.activation}")
private Boolean isActivationRequired;

@PersistenceContext   
private EntityManager em;

@EventListener
public void handleContextRefreshEvent(ContextRefreshedEvent ctxRefreshedEvent) {
    if (!isActivationRequired) {
        em.createNativeQuery("drop table user_activation_link").executeUpdate();
    }
}

注意这里使用的是@Value而不是publicstatic final字段,你可以在application.properties中添加名为required.activation的字段。会自动注入私有域

您需要执行类似 this 的操作来排除您不想在数据库中创建的表。

  • Implement the SchemaFilterProvider and the SchemaFilter interfaces
  • In the SchemaFilter implementation, add an if condition to includeTable so that it returns false for the table that you don’t want to create
  • Add hibernate.properties to the classpath and define hibernate.hbm2ddl.schema_filter_provider to point to the SchemaFilterProvider implementation
hibernate.hbm2ddl.schema_filter_provider=com.your.package.Provider

还有:

package com.your.package;

import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.model.relational.Sequence;
import org.hibernate.mapping.Table;
import org.hibernate.tool.schema.spi.SchemaFilter;
import org.hibernate.tool.schema.spi.SchemaFilterProvider;

public class Provider implements SchemaFilterProvider {

    @Override
    public SchemaFilter getCreateFilter() {
        return MySchemaFilter.INSTANCE;
    }

    @Override
    public SchemaFilter getDropFilter() {
        return MySchemaFilter.INSTANCE;
    }

    @Override
    public SchemaFilter getMigrateFilter() {
        return MySchemaFilter.INSTANCE;
    }

    @Override
    public SchemaFilter getValidateFilter() {
        return MySchemaFilter.INSTANCE;
    }
}

class MySchemaFilter implements SchemaFilter {

    public static final MySchemaFilter INSTANCE = new MySchemaFilter();

    @Override
    public boolean includeNamespace(Namespace namespace) {
        return true;
    }

    @Override
    public boolean includeTable(Table table) {
        if (//REQUIRED_ACTIVATION==true && table.getName() is the table you want to exclude){
            return false;
        }
        return true;
    }

    @Override
    public boolean includeSequence(Sequence sequence) {
        return true;
    }
}