如何使用本机SQL获取现有表

时间:2019-07-18 08:11:20

标签: java hibernate spring-boot jpa

首先,为可能出现的语法错误道歉。我的英语不太好。

我已经创建了一个动态表生成器。我使用该表生成器动态创建具有不同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;
    }

1 个答案:

答案 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相同的原因。