How to use custom row mapper with EntityManager

Solution Verified - Updated -

Environment

  • Red Hat JBoss Enterprise Application Platform(EAP)
    • 6.3.3
    • Hibernate/JPA

Issue

  • We are currently using JPA for persistence.
  • We would like to standardize on the EntityManager API but we are missing one piece of functionality.
  • We already have the ability to execute native queries, but we do not have any capability to completely take over the building of the object from a result set row.From what we have understood, within our code we can define a new entity mapping, however we would like to code this mapping as a row mapper in order to perform more complex logic as the results are being translated to the objects to save on iterating over results twice.

  • We would like to know if there is the equivalent to the following API or a workaround to achieve the same pattern:


entityManager.createNativeQuery("select ... from X", new MyRowMapper() { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { MyObject o = new MyObject(); o.setX( rs.getInt(1) ); .... return o; } } );
  • Is there an equivalent to RowMapper within the JPA API so that we don't have to use spring. We need the same ability within Entity Manager when using the queryNative API on EM. Is there any equivalent API exists under the global JPA/JEE standard APIs?

Resolution

  • There is no such standard API exists under the global JPA/JEE standard APIs for custom Row Mapping.

  • To implement custom mapping through JPA EntityManager developer need to write their own custom code.

  • RowMapper: RowMapper Interface is used by the JdbcTemplate to map a resultset row.The implementation of this interface maps a resultset row to a result object.

  • Its like as a custom-mapping tooling feature implemented through only Spring JDBC Template. It's just focusing on the object mapping from the resultSet, and can easily be used as a RowMapper for spring jdbc i.e. (org.springframework.jdbc.core.RowMapper package)

  • Please refer the document Interface RowMapper

  • Hibernate and JPA standard is responsible for persistence operation with the respect to Database. It is not take part in such custom tooling feature.

  • There is a method shown of org.springframework.jdbc.core.JdbcTemplate has the following signature:
    List<T> query(String sql, RowMapper rowMapper).

  • This method executes an SQL query and maps each row of the ResultSet to a Java object via a RowMapper.

  • RowMapper interface has a method: T mapRow(ResultSet resultSet, int arg1) throws SQLException that must be implemented. It has to map each row of data in the ResultSet into an Entity of the application domain.

  • Workaround of RowMapper:

  • EmployeeDao.java

public class EmployeeDao {

    private JdbcTemplate template;

    public void setTemplate(JdbcTemplate template) {
        this.template = template;
    }

    public List<Employee> getAllEmployeesRowMapper() {

        return (List<Employee>) template.query("SELECT * FROM EMPLOYEE", new EmployeeRowMapper());
    }

}
  • Custom Row Mapper(EmployeeRowMapper.java)
import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;

public class EmployeeRowMapper implements RowMapper {

    @Override
    public Object mapRow(ResultSet rs, int rowNum) throws SQLException {

        Employee e = new Employee();

        e.setId(rs.getInt(1));

        e.setName(rs.getString(2));

        e.setSalary(rs.getInt(3));

        return e;
    }
}

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Comments