I need to use raw SQL within a Spring Data Repository, is this possible? Everything I see around @Query
is always entity based.
-
Would SqlQuery do? http://static.springsource.org/spring/docs/2.5.x/api/ – Chetter Hummin Apr 11 '13 at 12:34
-
How could I use that within a repository? Or would I not use a repo and just use that object within my service? – Ben Apr 11 '13 at 12:34
-
Do you use spring-data-jpa? – zagyi Apr 11 '13 at 12:35
-
@Webnet I'm a bit new to Spring myself, but it looks to me that you could use that as an object – Chetter Hummin Apr 11 '13 at 12:35
-
have you tried Spring JDBCTemplate ? – BlackJoker Apr 11 '13 at 12:41
6 Answers
The @Query annotation allows to execute native queries by setting the nativeQuery flag to true.
Quote from Spring Data JPA reference docs.
Also, see this section on how to do it with a named native query.

- 56,620
- 24
- 188
- 240

- 17,223
- 4
- 51
- 48
-
22@user454322, parameters start with 1, so it's: `@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)` – Jacob van Lingen Jan 06 '17 at 09:20
-
1. By CrudRepository (Projection)
Spring Data Repositories usually return the domain model when using query methods. However, sometimes, you may need to alter the view of that model for various reasons. —Source
Suppose your entity is like this :
import javax.persistence.*;
import java.math.BigDecimal;
@Entity
@Table(name = "USER_INFO_TEST")
public class UserInfoTest {
private int id;
private String name;
private String rollNo;
public UserInfoTest() {
}
public UserInfoTest(int id, String name) {
this.id = id;
this.name = name;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false, precision = 0)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Basic
@Column(name = "name", nullable = true)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Basic
@Column(name = "roll_no", nullable = true)
public String getRollNo() {
return rollNo;
}
public void setRollNo(String rollNo) {
this.rollNo = rollNo;
}
}
Now your Projection class is like below. It can those fields that you needed.
public interface IUserProjection {
int getId();
String getName();
String getRollNo();
}
And Your Data Access Object(Dao) is like bellow
:
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import java.util.ArrayList;
public interface UserInfoTestDao extends CrudRepository<UserInfoTest,Integer> {
@Query(value = "select id,name,roll_no from USER_INFO_TEST where rollNo = ?1", nativeQuery = true)
ArrayList<IUserProjection> findUserUsingRollNo(String rollNo);
}
Now ArrayList<IUserProjection> findUserUsingRollNo(String rollNo)
will give you the list of user.
2. Using EntityManager
Suppose your query is "select id,name from users where roll_no = 1001".
Here query will return an object with id and name column. Your Response class is like bellow:
Your Response class is like this:
public class UserObject{
int id;
String name;
String rollNo;
public UserObject(Object[] columns) {
this.id = (columns[0] != null)?((BigDecimal)columns[0]).intValue():0;
this.name = (String) columns[1];
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRollNo() {
return rollNo;
}
public void setRollNo(String rollNo) {
this.rollNo = rollNo;
}
}
here UserObject constructor will get an Object Array and set data with the object.
public UserObject(Object[] columns) {
this.id = (columns[0] != null)?((BigDecimal)columns[0]).intValue():0;
this.name = (String) columns[1];
}
Your query executing function is like bellow :
public UserObject getUserByRoll(EntityManager entityManager,String rollNo) {
String queryStr = "select id,name from users where roll_no = ?1";
try {
Query query = entityManager.createNativeQuery(queryStr);
query.setParameter(1, rollNo);
return new UserObject((Object[]) query.getSingleResult());
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
Here you have to import bellow packages:
import javax.persistence.Query;
import javax.persistence.EntityManager;
Now your main class, you have to call this function. First get EntityManager and call this getUserByRoll(EntityManager entityManager,String rollNo)
function. The calling procedure is given below:
Here is the Imports
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
get EntityManager
from this way:
@PersistenceContext
private EntityManager entityManager;
UserObject userObject = getUserByRoll(entityManager,"1001");
Now you have data in this userObject.
Note:
query.getSingleResult() return a object array. You have to maintain the column position and data type with the query column position.
select id,name from users where roll_no = 1001
query return a array and it's [0] --> id and [1] -> name
.
More info visit this thread and this Thread
Thanks :)

- 42,008
- 16
- 111
- 154

- 6,749
- 3
- 61
- 87
we can use createNativeQuery("Here Native SQL Query ");
for Example :
Query q = em.createNativeQuery("SELECT a.firstname, a.lastname FROM Author a");
List<Object[]> authors = q.getResultList();

- 22,346
- 14
- 99
- 142

- 2,994
- 1
- 30
- 33
-
28Would be useful/complete if you also showed how to create the `em` variable. – ETL Jun 25 '19 at 22:32
-
1em is "javax.persistence.EntityManager" .in my case I just @Autowired it. – Yasitha Bandara Mar 21 '21 at 13:29
-
1
It is possible to use raw query within a Spring Repository.
@Query(value = "SELECT A.IS_MUTUAL_AID FROM planex AS A
INNER JOIN planex_rel AS B ON A.PLANEX_ID=B.PLANEX_ID
WHERE B.GOOD_ID = :goodId",nativeQuery = true)
Boolean mutualAidFlag(@Param("goodId")Integer goodId);

- 1,420
- 1
- 21
- 32
This is how you can use in simple form
@RestController
public class PlaceAPIController {
@Autowired
private EntityManager entityManager;
@RequestMapping(value = "/api/places", method = RequestMethod.GET)
public List<Place> getPlaces() {
List<Place> results = entityManager.createNativeQuery("SELECT * FROM places p limit 10").getResultList();
return results;
}
}
-
This is an easy solution, worked for me! Wondering if it has some disadvantages because here we do not use Service and Repository layers. – Phaki Jan 06 '22 at 15:02
It is also possible to use Spring Data JDBC, which is a fully supported Spring project built on top of Spring Data Commons to access to databases with raw SQL, without using JPA.
It is less powerful than Spring Data JPA, but if you want lightweight solution for simple projects without using a an ORM like Hibernate, that a solution worth to try.

- 5,950
- 5
- 37
- 38
-
The most recent commit to the Spring Data JDBC repository was in 2016. – Mass Dot Net Apr 04 '22 at 02:32
-
1Good catch, I have updated the recommandation to use https://spring.io/projects/spring-data-jdbc instead which is fully supported by Spring. – Sébastien Deleuze Apr 05 '22 at 05:13
-
Another item to consider for your list (that I just happened across): [JDBI](http://jdbi.org). Not an ORM, but a layer sitting on top of JDBC that lets you write queries a bit more tersely, plus quality-of-life features like SQL injection protection when adding parameters. – Mass Dot Net May 02 '22 at 20:06