首先,为可能出现的语法错误道歉。我的英语不太好。
我已经创建了一个动态表生成器。我使用该表生成器动态创建具有不同JSON属性的表。
我完美地创建了表,但是我想在创建表之前检查它是否已经存在。
我使用在pgAdmin上运行的sql sentence,但是,当我在方法上使用该语句时,则不起作用。
我正在使用错误启动(JPA +休眠)和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;
}
答案 0 :(得分:2)
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相同的原因。