带有 SQL Server 的 Java JPA/Hibernate - 如何检测数据库中的列何时未被实体模型映射?

标签 java sql-server spring hibernate jpa

我有一个使用 JPA/Hibernate 映射实体的 Spring webapp,它可以很好地完成所有正常任务,例如CRUD 操作。

我还能够检测模型中的字段何时不存在于数据库中( hibernate 抛出“无效列名”)。

我的问题是,我现在需要在数据库中有模型未表示的新列时检测并提醒用户。

这样做的原因是应用程序应该始终允许用户设置/查看数据库中存在的所有字段,而不是在没有通知的情况下透明地忽略可用字段。

有没有一种简单的方法可以使用 JPA/Hibernate 来实现这两个目标

  1. 如果数据库中有新的未映射列则抛出错误,或者
  2. 手动检查所有列是否都已计算在内?

如果没有简单的方法,我想我可以查询 information_schema,但我想尽可能避免这种情况。

提前致谢!

最佳答案

没有这样的 hbm2ddl.auto 选项,如果您正在搜索类似的东西。例如 update 将只检查映射的列并忽略其他列 - 至少它不会删除它们。

所以你将不得不走艰难的路并手工检查:

SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) ((Session) this.em.getDelegate()).getSessionFactory();

// Find all mapped tables with all mapped columns
final Map<String, Set<String>> tableColumns = new HashMap<>();

for (ClassMetadata metadata : sessionFactory.getAllClassMetadata().values()) {
  AbstractEntityPersister persister = (AbstractEntityPersister) metadata;
  Set<String> columns = new HashSet<>();
  tableColumns.put(persister.getTableName(), columns);
  for (String propertyName : persister.getPropertyNames()) {
    for (String propertyColumnName : persister.getPropertyColumnNames(propertyName)) {
      columns.add(propertyColumnName);
    }
  }
}

for (CollectionMetadata metadata : sessionFactory.getAllCollectionMetadata().values()) {
  AbstractCollectionPersister persister = (AbstractCollectionPersister) metadata;
  // ... extract key, index and element columns from persister, similar to AbstractEntityPersister
}

// Compare columns with existing metadata
sessionFactory.getCurrentSession().doWork(new Work() {
  public void execute(Connection connection) throws SQLException {
    for (Map.Entry<String, Set<String>> entry : tableColumns.entrySet()) {
      String tableName = entry.getKey();
      ResultSet rs = connection.getMetaData().getColumns(null, null, tableName, null);
      try {
        while (rs.next()) {
          String columnName = resultSet.getString("COLUMN_NAME");
          if (!entry.getValue().remove(columnName)) {
            log.error("Column not mapped: {}.{}", tableName, columnName));
          }
        }
        if (!entry.getValue().isEmpty()) {
          log.error("Columns not defined: {}.{}", tableName, entry.getValue()));
        }
      } finally {
        rs.close();
      }
    }
  }
});

关于带有 SQL Server 的 Java JPA/Hibernate - 如何检测数据库中的列何时未被实体模型映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33992376/

相关文章:

java - java另一种字符串转换URL utf8

java - Linux 中的 TimeZone.getDefault() 因用户而异

sql-server - 不在 SQL Server 中使用链接服务器的原因?

c# - VIsual Studio WinForm 连接到 SQL Server 数据库 : C# syntax to transfer the data

java - Spring ldap 身份验证失败错误代码

java - 使用ANTLR4获得完整的功能内容与C语言的空间

java - maven发布插件-操作项目发布版本

c# - 调用存储过程返回 30 个字符中的 1 个

java - REST 客户端 restTemplate 无法获取对象集合

spring - 如何在 Spring 为测试类 Autowiring ?