首先,为可能出现的语法错误道歉。我的英文不是很好。
我创建了一个动态表生成器。我使用该表生成器动态创建具有不同JSON属性的表。
我可以完美地创建表,但是我想在创建表之前进行检查(如果已经存在)。
我使用在pgAdmin上有效的sql sentence,但是当我在方法上使用该语句时不起作用。
我正在使用sprong boot(JPA + hibernate)和Postgresql。
返回下一个错误:
造成原因:org.hibernate.hql.internal.ast.QuerySyntaxException:
information_schema.tables未映射
如何获得所有已经存在的表?
这是我的代码:
@Service
@Transactional
public class TableGeoJsonGenerator {
private static final Logger LOGGER = LogManager.getLogger(SchemeService.class);
@Autowired
private EntityManager em;
public String initTable(String name, List<String> columns, List<String> typeColumns, ArrayList<Object> rows) {
String nameTableFinal = "";
if (!chekifExistTable(name)) {
nameTableFinal = name;
createTableWithColumns(name, columns, typeColumns);
} else {
UUID uuid = UUID.randomUUID();
nameTableFinal = name + "-" + uuid.toString();
createTableWithColumns(name, columns, typeColumns);
}
return nameTableFinal;
}
private void createTableWithColumns(String name, List<String> columns, List<String> typeColumns) {
String SQL = "CREATE TABLE IF NOT EXISTS " + name + "( name_id varchar(255) ,table_id SERIAL, " + generateSqlColumns(columns, typeColumns) +" primary key (name_id));";
executeSQL(SQL);
}
private String generateSqlColumns(List<String> columns, List<String> typeColumns) {
String DINAMIC_COLUMNS = "";
for (int i=0; i<columns.size(); i++) {
DINAMIC_COLUMNS += columns.get(i).toString() + " " + getPostgresqlValue(typeColumns.get(i).toString()) + ", ";
}
return DINAMIC_COLUMNS;
}
private void executeSQL(String SQL) {
try {
Query query = em.createNativeQuery(SQL);
query.executeUpdate();
} catch(Throwable e) {
LOGGER.error(e.getMessage());
throw e;
} finally {
em.close();
}
}
private boolean executeSQLWithResults(String SQL, String nameTable) {
boolean found = false;
try {
TypedQuery<?> lQuery = (TypedQuery<?>) em.createQuery(SQL);
List<?> list = lQuery.getResultList();
for (Object result : list) {
LOGGER.debug(result.toString());
}
found = true;
} catch(Throwable e) {
LOGGER.error(e.getMessage());
throw e;
} finally {
em.close();
}
return found;
}
private boolean chekifExistTable(String name) {
String SQL = "select table_name from information_schema.tables where table_schema = 'public'";
return executeSQLWithResults(SQL, name);
}
private String getPostgresqlValue(String value) {
if (value.equals(Integer.class.toString())) {
return "int8";
}
else if (value.equals(Double.class.toString())) {
return "float8";
}
else if (value.equals(String.class.toString())) {
return "varchar(255)";
}
else if (value.equals(Long.class.toString())) {
return "bigint";
}
else if (value.equals(Boolean.class.toString())) {
return "boolean";
}
else if (value.equals(Date.class.toString())) {
return "timestamp";
}
else {
return "numeric";
}
}
}
Amer Qarabsa解决的解决方案:
private boolean executeSQLWithResults(String SQL, String nameTable) {
boolean found = false;
try {
Query query = em.createNativeQuery(SQL);
List<?> list = query.getResultList();
for (Object result : list) {
LOGGER.debug(result.toString());
}
found = true;
} catch(Throwable e) {
LOGGER.error(e.getMessage());
throw e;
} finally {
em.close();
}
return found;
}
最佳答案
Hibernate抱怨,因为您尝试访问information_schema.tables的对象未映射到实体。
问题是这种方法
private boolean chekifExistTable(String name) {
String SQL = "select table_name from information_schema.tables where table_schema = 'public'";
return executeSQLWithResults(SQL, name);
}
在executeSQLWithResults中,您正在调用em.createQuery,createQuery期望使用JQL而不是SQL,因此这就是为什么hibernate尝试将其映射到实体,检查link,而在其他方法executeSQL中使用em.createNativeQuery相同的原因