简体   繁体   中英

How get EntityManager to execute native sql

First of all, apologize for the grammatical errors that you can make. My English is not very good.

I'm creating a Table constructor to create dinamically tables. My problem is that EntityManager is null and I dont know why.

I was reading that you can create an entityManager with an entityManagerFactory and passing parameter that already I have in my application.properties.

Or I can inject PersistenceContext but when I try to execute a sql sentence, EntityManager is null.

How can I solve it?

EDIT: I did all that you said and show next:

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...

Sorry I Edit and add edited code to sort all code and editions: Here is my code:

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

}

@UtilityClass

Im guessing this is your problem. Taken from lombok documentation.

A utility class cannot be instantiated . By marking your class with @UtilityClass, lombok will automatically generate a private constructor that throws an exception, flags as error any explicit constructors you add, and marks the class final. If the class is an inner class, the class is also marked static.

My guess here is the following. Spring can only inject beans into spring managed objects. Your class TableGeoJsonGenerator is not a managed bean because spring can't instantiate it.

You need to remove @UtilityClass and add one of the managed bean annotations, like @Service @Controller etc. etc.

When defining jpa properties in application.properties spring boot will automatically create a EntityManager for you with the properties defined.

This can then be @Autowired into any spring managed bean . You need to make your class managed first.

where is your methode entityManagerFactory() ?

I think : + First, create the EntityManagerFactory

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

  • then, create entityManager :

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

then :

     ...
     EntityManager entityManager = getEntityManager();

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM