Is a native request in springboot - spring-data-jpa

I have this error when I execute my following native request:
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'limit 5' at line 1.
I don't see any problems please help me.
My code:
#Repository
public interface AdherentRepository extends JpaRepository<Adherent, Long> {
public Iterable<Adherent> findByEmpruntsIdemprunt(Long Id);
#Query(value = "SELECT * FROM adherent WHERE nom LIKE :x OR email LIKE :x OR matricule LIKE :x ;", nativeQuery = true)
public Page<Adherent> findAdherent(#Param("x") String x, Pageable pageable);
}

Related

PSQLException: ERROR: column "classification" is of type classification but expression is of type character varying

I have the following JPA repo with insert query method:
public interface CMRepository extends JpaRepository <CMark, String> {
#Transactional
#Modifying
#Query(value = "INSERT INTO c_mark(class_fk, s_con_fk, dis_con_fk, rto_fk, version, classification) " +
"values(:class_fk, :s_con_fk, :dis_con_fk, :rto_fk, :version, :classification)", nativeQuery = true)
int insertCMark(#Param("class_fk") String class_fk, #Param("s_con_fk") String s_con_fk, #Param("dis_con_fk") String dis_con_fk,
#Param("rto_fk") String rto_fk, #Param("version") int version, #Param("classification") String classification);
}
When executed, I get the following error:
PSQLException: ERROR: column "classification" is of type classification but expression is of type character varying
The database has that field defined as USER-DEFINED. I believe from similar posts I am supposed to cast the classification field? If so, I am not sure how to do it. Thanks for any help!
ok, figured this out. I had to cast like this:
public interface CMRepository extends JpaRepository <CMark, String> {
#Transactional
#Modifying
#Query(value = "INSERT INTO c_mark(class_fk, s_con_fk, dis_con_fk, rto_fk, version, classification) " +
"values(:class_fk, :s_con_fk, :dis_con_fk, :rto_fk, :version, :classification\\:\\:classification)", nativeQuery = true)
int insertCMark(#Param("class_fk") String class_fk, #Param("s_con_fk") String s_con_fk, #Param("dis_con_fk") String dis_con_fk,
#Param("rto_fk") String rto_fk, #Param("version") int version, #Param("classification") String classification);
}
(notice the required escapes)

Spring JPA #Param of filename for postgres COPY

I have the following interface which is connected to a PostgreSQL database:
public interface ExampleDAO extends JpaRepository<Example, Integer>
{
#Modifying
#Query(value="COPY my_table FROM :filename CSV HEADER", nativeQuery=true)
public int copyMyTable(#Param("filename") String filename);
}
But when I run it I get
org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement
I remove the #Param and hardcode the filename in and it works fine. The filename passed is:
copyMyTable("C:\\path\\to\\my\\file.csv");
I am totally at a loss on this one!
Judging from this thread Postgres doesn't support bind parameters in this kind of statement.

MyBatis Error: Invalid bound statement (not found)

Here is the stack trace when I try to execute a simple query using MyBatis:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.ppcredit.gypsophila.mapper.GypsophilaVarsStatisticsMapper.selectBySql
at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:225)
at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:48)
at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:65)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:58)
at com.sun.proxy.$Proxy110.selectBySql(Unknown Source)
Here is a method from my class:
/**
* use the sql to query result
*
* #param sql
* #return
*/
List<LinkedHashMap<String, Object>> selectBySql(String sql, Map<String, Object> parms);
In this case, need want to execute SQL statement directly, the sql as below:
SELECT VELOCITY_VARS FROM PPC_GYPSOPHILA_VARS_STATISTICS WHERE SCENARIO_ID=#{scenarioId} and TACTIC_ID=#{flowId} and CREATE_USER=#{userId}
all parameters of sql can be found in Map<String, Object> parms
I've done some research, but none of the solutions have worked for me. My Mapper class seems have some problems, but i dont know what's wrong.
Does anyone have an idea what's wrong here?
Thanks in advance
I am going to suppose that public interface GypsophilaVarsStatisticsMapper implements selectBySQL, in a correct way. I assumed you are import annotations if you are using it by:
import com.ppcredit.gypsophila.mapper.entity.GypsophilaVarsStatisti‌​cs;
import org.apache.ibatis.annotations.*;
public interface GypsophilaVarsStatisticsMapper {
List<GypsophilaVarsStatistics> selectBySQL(String sql,Map parameters);
/**your code**/
I am going to suppose likewise, that you have a class (let's call it test) whose scope allows to call GypsophilaVarsStatisticsMapper Interface (in other case import). That would i do is the folloging:
import com.ppcredit.gypsophila.mapper.entity.GypsophilaVarsStatisti‌​cs;
public class Test {
public static void main(String args[]) throws IOException{
Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sqlSessionFactory.openSession();
session.getConfiguration().addMapper(GypsophilaVarsStatisticsMapper.class);
GypsophilaVarsStatisticsMapper mapper = session.getMapper(GypsophilaVarsStatisticsMapper.class);
sql_string = 'SELECT VELOCITY_VARS FROM PPC_GYPSOPHILA_VARS_STATISTICS WHERE SCENARIO_ID=#{scenarioId} and TACTIC_ID=#{flowId} and CREATE_USER=#{userId}'
Map<String,Object) params = getParams() /* Your params */
List<GypsophilaVarsStatistics> result = mapper.selectBySQL(sql_string, params)
I suppose than you not are using MyBatis with a dependency injection framework like Spring. In this case SqlSessionFactory is supplied by this framework.

Exposing a paginated search link and its arguments

I'm using the latest of Spring REST and HATEOAS trying to expose a link to a search endpoint.
Here is the resource assembler:
#Component
public class AdminResourceAssembler extends ResourceAssemblerSupport<Admin, AdminResource> {
public AdminResourceAssembler() {
super(AdminController.class, AdminResource.class);
}
public AdminResource toResource(Admin admin) {
AdminResource adminResource = createResourceWithId(admin.getId(), admin);
BeanUtils.copyProperties(admin, adminResource);
adminResource.add(linkTo(AdminController.class).slash(admin.getId()).slash("module").withRel("module"));
return adminResource;
}
}
Here is the end point controller:
#RequestMapping(value = UriMappingConstants.PATH_SEPARATOR + UriMappingConstants.SEARCH, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity<PagedResources<AdminResource>> search(#RequestParam(value = "searchTerm", required = true) String searchTerm, #PageableDefault Pageable pageable, PagedResourcesAssembler<Admin> pagedResourcesAssembler, UriComponentsBuilder builder) {
HttpHeaders responseHeaders = new HttpHeaders();
Pageable pageRequest = buildPageRequest(pageable.getPageNumber(), pageable.getPageSize());
Page<Admin> searchedAdmins = adminService.search(searchTerm, pageRequest);
responseHeaders.setLocation(builder.path(UriMappingConstants.PATH_SEPARATOR + UriMappingConstants.ADMINS + UriMappingConstants.PATH_SEPARATOR + "search").queryParam("searchTerm", searchTerm).queryParam("page", pageable.getPageNumber()).queryParam("size", pageable.getPageSize()).buildAndExpand(searchTerm).toUri());
PagedResources<AdminResource> adminPagedResources = pagedResourcesAssembler.toResource(searchedAdmins, adminResourceAssembler);
return new ResponseEntity<PagedResources<AdminResource>>(adminPagedResources, responseHeaders, HttpStatus.OK);
}
private Pageable buildPageRequest(int pageIndex, int pageSize) {
Sort sort = new Sort(new Sort.Order(Sort.Direction.ASC, "lastname"), new Sort.Order(Sort.Direction.ASC, "firstname"));
return new PageRequest(pageIndex, pageSize, sort);
}
First, I'm not sure if I should call in the buildPageRequest method and simply pass in the original pageable to the search service.
The problem I have is two fold:
The published link in the response is missing the searchTerm parameter:
{"rel":"self","href":"http://localhost:8080/nitro-project-rest/admins/search{?page,size,sort}
I would expect it to be like:
{"rel":"self","href":"http://localhost:8080/nitro-project-rest/admins/search{?searchTerm,page,size,sort}
But again, as a newbie I don't know for sure.
And the controller always fetches the first page of the 10 items, ignoring the page number and size arguments I give in the request:
curl -H "Accept:application/json" --user joethebouncer:mignet http://localhost:8080/nitro-project-rest/admins/search?searchTerm=irstna&page=3&size=5
I guess I'm not too far from a asolution, but I don't even know exactly what the exposed link should look like.
Any directions would be very nice :-)
EDIT: Added information
The pageable configuration:
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
argumentResolvers.add(resolver);
super.addArgumentResolvers(argumentResolvers);
}
The service is simply a wrap around the repository:
public Page<Admin> search(String searchTerm, Pageable page) {
return adminRepository.search(searchTerm, page);
}
which is an interface:
#Query("SELECT a FROM Admin a WHERE LOWER(a.firstname) LIKE LOWER(CONCAT('%', :searchTerm, '%')) OR LOWER(a.lastname) LIKE LOWER(CONCAT('%', :searchTerm, '%')) OR LOWER(a.email) LIKE LOWER(CONCAT('%', :searchTerm, '%')) OR LOWER(a.login) LIKE LOWER(CONCAT('%', :searchTerm, '%')) ORDER BY a.lastname ASC, a.firstname ASC") public
Page search(#Param("searchTerm") String searchTerm, Pageable page);
The database is H2 fronted by JPA and the console shows:
One can see that the offset is missing...
select admin0_.id as id1_1_, admin0_.version as version2_1_, admin0_.email as email3_1_, admin0_.firstname as firstnam4_1_, admin0_.lastname as lastname5_1_, admin0_.login as login6_1_, admin0_.password as password7_1_, admin0_.password_salt as password8_1_, admin0_.post_login_url as post_log9_1_ from admin admin0_ where lower(admin0_.firstname) like lower(('%'||'irstn'||'%')) order by admin0_.lastname ASC, admin0_.firstname ASC, admin0_.lastname asc, admin0_.firstname asc limit 10
Kind Regards,
Stephane Eybert
no idea what buildPageRequest is doing...but i would bet you don't need it and it's the source of your paging problems
Regarding the self link. PagedResourceAssembler creates a very simple default one...but you can build a more complicated one and pass it in as a third parameter of the toResource method. So just build your own link in any of the many ways. I'd suggest something like:
linkTo(methodOn(SomeController.class).search(searchTerm, pageable, null, null))
another thing to note that a self link should never be templated so this is a bug in spring-hateoas (really a dependency) see https://jira.spring.io/browse/DATACMNS-515
Stupid me. I could not see curl needed double quotes around the url to allow for multiple parameters. curl -H "Accept:application/json" --user joethebouncer:mignet "localhost:8080/nitro-project-rest/admins/… now works fine.

playframework selecting from h2 database

I am trying downloading all records from table in h2 buildin database in playframework.
I am facing an error:
[IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: * near line 1, column 8 [SELECT * FROM TABLE]]
Method CODE i class Table:
#Transactional(readOnly=true)
public static Result view() {
Query query = JPA.em().createQuery("SELECT * FROM TABLE");
List<Table> downloaded_from_db = query.getResultList();
System.out.println(downloaded_from_db.getClass());
return ok(view.render("none"));
}
Please help me. I would like to see downloaded records in console in simple view.
Please give me some tips or good tutorial.
After changing my class loooks like this:
#Transactional(readOnly=true)
public static Result view() {
List<MedicalIncidents> data = JPA.em()
.createNativeQuery("SELECT * FROM MedicalIncident")
//.createQuery("Select m from MedicalIncident m")
.getResultList();
System.out.println(data);
AND I think it works, cause I have 2 entries in that table in database:
But System.out.println(data) return in plaay console:
[[Ljava.lang.Object;#70a0c9be, [Ljava.lang.Object;#4c1d12b6]
But it should return this object by model name like in example: computer-database-jpa:
[models.Computer#214c6fde, models.Computer#63728eb3, models.Computer#75f6bcc6, models.Computer#19e3a7ab, models.Computer#3114d8d4, models.Computer#4fa75f78, models.Computer#756ce822, models.Computer#40fc4c68, models.Computer#73fc612c, models.Computer#3e4fcb31]
So I think that there is something wrong with it. Please help
You mxied SQL queries with JPQL query. The method you used createQuery needs an JPQL query:
SELECT e FROM Entity e
Also please note in JPQL there is no SELECT *. If you want to write a SQL query, use the method em.createNtiveQuery().