如何获取EntityManager执行本机SQL

时间:2019-07-17 12:00:44

标签: java hibernate spring-boot jpa

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

我正在创建一个Table构造函数以创建动态表。 我的问题是EntityManager为null,我不知道为什么。

我正在阅读,您可以使用entityManagerFactory创建一个EntityManager,并传递我在application.properties中已经拥有的参数。

或者我可以注入PersistenceContext,但是当我尝试执行sql语句时,EntityManager为null。

我该如何解决?

编辑: 我做了你所说的一切,然后显示:

LOGGER.DEBUG:

CREATE TABLE countries( table_id SERIAL, tsunami int8, mag float8, felt numeric, id varchar(255), time bigint,  primary key (table_id));

ERROR:

java.lang.NullPointerException: null
    at com.project.maps.util.TableGeoJsonGenerator.executeSQL...

对不起,我编辑并添加编辑后的代码以对所有代码和版本进行排序: 这是我的代码:

@Service
public class TableGeoJsonGenerator {

    private static final Logger LOGGER = LogManager.getLogger(SchemeService.class);

    @Autowired
    private EntityManager em;

    public TableGeoJsonGenerator() {
        super();
    }

    public void initTable(String name, List<String> columns, List<String> typeColumns, ArrayList<Object> rows) {
        createTableWithColumns(name, columns, typeColumns);
        addRowsInTable(rows);       
    }

    private void createTableWithColumns(String name, List<String> columns, List<String> typeColumns) {
        String SQL = "CREATE TABLE " + name + "( table_id int8 NOT NULL AUTO_INCREMENT, " + generateSqlColumns(columns, typeColumns) +" primary key (table_id));";
        LOGGER.debug(SQL);
        executeSQL(SQL);
    }

    private void addRowsInTable(ArrayList<Object> rows) {

    }

    public 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 {
            em.getTransaction().begin();
            em.createNativeQuery(SQL).executeUpdate();
            em.getTransaction().commit();
        } catch(Throwable e) {
            LOGGER.error(e.getMessage());
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();             
            }
            throw e;
        } finally {
            em.close();
        }
    }

    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";
        }       
    }

}

2 个答案:

答案 0 :(得分:3)

@UtilityClass

我猜这是您的问题。取自龙目岛文档。

  

无法实例化实用程序类。通过使用@UtilityClass标记您的类,lombok将自动生成一个引发异常的私有构造函数,将您添加的所有显式构造函数标记为错误,并将该类标记为final。如果该类是内部类,则该类也将标记为静态。

我的猜测如下。 Spring只能将bean注入spring管理的对象中。您的类TableGeoJsonGenerator不是托管bean,因为spring无法实例化它。

您需要删除@UtilityClass并添加一个托管bean注释,例如@Service @Controller等。

application.properties中定义jpa属性时,Spring Boot会自动为您创建一个EntityManager,并带有已定义的属性。

然后可以将其@Autowired插入任何spring managed bean中。您需要首先管理班级。

答案 1 :(得分:-3)

您的方法entityManagerFactory()在哪里?

我认为:  +首先,创建EntityManagerFactory

EntityManagerFactory entitymanagerfactory = Persistence.createEntityManagerFactory("your.package");

  • 然后,创建entityManager:

    public static EntityManager getEntityManager() { return entitymanagerfactory .createEntityManager(); }

然后:

     ...
     EntityManager entityManager = getEntityManager();

     em.getTransaction().begin();
     ....