Question

There is a little problem in replying on ajax requests. Initially, I have simplest restful service, based on spring boot MVC.

model:

import javax.persistence.*; 
import java.util.*;

@Entity 
@Table(name = "testmodel")
public class TestModel 
{
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY)//Postgresql sequence generator 
    private long id;

    @Column(name = "name")
    private String name;

    @Column(name = "content")
    private String content;


    //Constructor
    public TestModel()
    {   
    }

    //Id getter
    public long getId()
    {
        return this.id;
    }

    //Name getter-setter
    public String getName()
    {
        return this.name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    //Content getter-setter
    public String getContent()
    {
        return this.content;
    }

    public void setContent(String content)
    {
        this.content = content;
    }
}

DAO for model:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.*;

public interface TetsModelDAO extends JpaRepository<Samples, Long> 
{
    @Query("SELECT s FROM TestModel s WHERE LOWER(s.name) LIKE LOWER(:entry) ORDER BY s.name")
    List<TestModel> fetchByNameEntry(@Param("entry") String entry);
}

Controller:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
@RequestMapping("/")
public class TestController 
{
    @Autowired
    private TetsModelDAO testmodel;

    @RequestMapping("/name")
    public List<TestModel> getDatasetsByNameEntry(@RequestParam("entry") String entry) 
    {
        return testmodel.fetchByNameEntry("%"+entry+"%");
    }
}

Client-side ajax request:

$.ajax(
{ 
  url : "/name?entry=", //get all records
  method: "GET"
})

This example works perfectly - stringified reply looks like standart json structure:

{"id":"1", "name":"John", "content":"blablabla1"}
{"id":"2", "name":"Sam", "content":"blablabla2"}
{"id":"3", "name":"Ken", "content":"blablabla3"}

However, when I tried to define fileds in JPQL query explicitly (fetch, say, only id and name fields), I get wrong result in reply.

DAO with modified query (other code without changes):

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.*;

public interface TetsModelDAO extends JpaRepository<Samples, Long> 
{
   @Query("SELECT s.id, s.name FROM TestModel s WHERE LOWER(s.name) LIKE LOWER(:entry) ORDER BY s.name")
   List<TestModel> fetchByNameEntry(@Param("entry") String entry);
}

In this case reply looks like this:

1, John, 2, Sam, 3, Ken

How to resolve this problem gracefully (without creating "helper classes")?

Was it helpful?

Solution

You can return DTO directly from Repository:

public interface TetsModelDAO extends JpaRepository<Samples, Long> 
{
   @Query("SELECT new mypackage.TestDto(s.id, s.name) FROM TestModel s WHERE LOWER(s.name) LIKE LOWER(:entry) ORDER BY s.name")
   List<TestDto> fetchByNameEntry(@Param("entry") String entry);
}

where TestDto contains only required fields:

package mypackage;

public class TestDto {
  private final long id;
  private final String name;

  public TestDto(long id, String name) {
    this.id = id;
    this.name = name;
  }

  public long getId() {
    return id;
  }

  public String getName() {
    return name;
  }
}

OTHER TIPS

Your query doesn't return instances of TestModel. It returns arrays of objects (i.e. a List<Object[]>), each array containing the ID and the name of a found TestModel. The correct query is

SELECT s FROM TestModel s WHERE LOWER(s.name) LIKE LOWER(:entry) ORDER BY s.name

You'd better implement automated tests to check that your DAO queries return what they should.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top