我有一个使用 JPA/Hibernate 映射实体的 Spring webapp,它可以很好地完成所有正常任务,例如CRUD 操作。
我还能够检测模型中的字段何时不存在于数据库中( hibernate 抛出“无效列名”)。
我的问题是,我现在需要在数据库中有模型未表示的新列时检测并提醒用户。
这样做的原因是应用程序应该始终允许用户设置/查看数据库中存在的所有字段,而不是在没有通知的情况下透明地忽略可用字段。
有没有一种简单的方法可以使用 JPA/Hibernate 来实现这两个目标
- 如果数据库中有新的未映射列则抛出错误,或者
- 手动检查所有列是否都已计算在内?
如果没有简单的方法,我想我可以查询 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/