I am developing application using Spring and Hibernate with MySQL. I am new to Hibernate and did basic tasks...
Now I need to apply joins in select query to get data from multiple table using annotations. I have searched for it but still I didn't get any idea...
Here my database tables and bean classes :
Table 1: 'employee_info' ( id, empid, empname, doj and jobtitle )
Table 2: 'employee_login' ( username, password, status and empid )
And my bean classes are:
EmployeeInfoForm.java
#Entity()
#Table(name = "employee_info")
public class EmployeeInfoForm {
#Id
#GeneratedValue
#Column(name = "id", unique = true, nullable = true)
private int id;
#Column(name = "empId")
private int empId;
#Column(name = "empname")
private String empName;
#Column(name = "doj")
private Date empDoj;
#Column(name = "jobtitle")
private String empJobTitle;
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public void setEmpDoj(Date empDoj) {
this.empDoj = empDoj;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Date getEmpDoj() {
return empDoj;
}
public void setEmp_Doj(Date empDoj) {
this.empDoj = empDoj;
}
public String getEmpJobTitle() {
return empJobTitle;
}
public void setEmpJobTitle(String empJobTitle) {
this.empJobTitle = empJobTitle;
}
}
EmployeeLoginForm.java
#Entity()
#Table(name = "employee_login")
public class EmployeeLoginForm {
#Id
#Column(name = "username")
private String empUserName;
#Column(name = "password")
private String empPassword;
#Column(name = "status")
private String empStatus;
#Column(name = "empid")
private int empId;
public String getEmpUserName() {
return empUserName;
}
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public void setEmpUserName(String empUserName) {
this.empUserName = empUserName;
}
public String getEmpPassword() {
return empPassword;
}
public void setEmpPassword(String empPassword) {
this.empPassword = empPassword;
}
public String getEmpStatus() {
return empStatus;
}
public void setEmpStatus(String empStatus) {
this.empStatus = empStatus;
}
}
Requirement:
I want to select fields empid, empname, jobtitle from employee_info and field status from employee_login table when the empid matches on both table...
Please help me to complete my work...
Any suggestions and guidance are appreciated...
There is an association between EmployeeInfoForm and EmployeeLoginForm that I am not seeing in your code. Maybe there is an Employee class there? If that is the case then you need to add that. So let us assume that each employee has many forms. Then you will code the Employee side of the relationship like this:
public class Employee{
#OneToMany(cascade = CascadeType.ALL, mappedBy = "employee")
private Set<EmployeeLoginForm> loginForms = new HashSet<EmployeeLoginForm>();
...
}
And the Many side of the relationship in the EmployeeLoginForm class:
#ManyToOne
Employee employee;
This will create the table structure such that:
emploee = (id, etc ...)
employeelogin = (id, employee, ....)
Now, any time you need a list of the Logins of an Employee you get it from the Employee object without needing a Query.
Set<EmployeeLoginForm> logins = e.getLoginForms(); //where e is an employee object.
If you did want to query you can do
select o from EmployeeLoginForm o join o.employee
But that is unnecessary in this case.
You are thinking in database / pure SQL terms when you talk about performing joins with select statements. The power (and danger) of Hibernate is that it abstracts this away from you and lets you think in Object terms. What you need is a relationship between the 2 objects and then let Hibernate handle this relationship.
I recommend you spend some time reading this:
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/associations.html
to get a better understanding of how Hibernate can help.
You can do the following using the Hibernate criteria projection:
public List extractEmployeeAttributes() {
log.debug("extractEmployeeAttributes");
try {
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Criteria c1 = session.createCriteria(employee_info.class,emp_info);
Criteria c2 = session.createCriteria(employee_login.class,emp_log);
c1.setProjection(Projections.projectionList()
.add(Projections.property("empid"))
.add(Projections.property("empname"))
.add(Projections.property("jobtitle"))
.add(Projections.property("employee_info "))
.add(Restrictions.and(Property.eqName(emp_info.empId,emp_log.empId))
return c1.list();
} catch (RuntimeException re) {
log.error("extractEmployeeAttributes failed", re);
throw re;
}
}
Related
This will take some explaining. So, I have an entity called Invoice and a related table called Errors, which is used to store some processing errors.
In a DAO class, I have a query for fetch the errors with some specific criteria:
public Errors loadLastError(Invoice i) {
try (Session session = factory.openSession()) {
Query query = session.createQuery("select er from Errors er" +
" inner join er.invoice i" +
" where er.invoice = :invoice" +
" and i.status <> :code" +
" and i.proccessStatus = :status" +
" order by er.id desc");
query.setParameter("invoice", invoice);
query.setParameter("code", "001");
query.setParameter("status", "form_error");
var result = query.getSingleResult();
return (Errors) result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
This works fine: will only get results when the conditions match. When they don't, I get the expected null result where this method is called:
this.invoice.setError(loadLastError(this.invoice);
When inspecting the code, I can see that the this.invoice object was updated correctly with a null result.
But, as soon as I pass this object invoice to another class in order to do some proccessing (send notifications basically by JSON), it gets there with a Errors object loaded, as if my original query had actually found something, which it didn't.
The following are a shortened example of my entity classes:
The Invoice:
#Entity
#DynamicUpdate
#Table(name = "data.invoice")
#TypeDef(
name = "pgsql_enum",
typeClass = PostgreSQLEnumType.class
)
public class Invoice implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#JsonIgnore
#Column(name = "proccessStatus")
private String proccessStatus;
#JsonIgnore
#Column(name = "status")
private String status;
#JsonIgnore
#OneToOne(mappedBy = "invoice", fetch = FetchType.LAZY)
private Errors errors;
public Integer getId() {
return id;
}
public String getProccessStatus() {
return proccessStatus;
}
public void setProccessStatus(String proccessStatus) {
this.proccessStatus= proccessStatus;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status= status;
}
public Errors getErrosr() {
return errors;
}
public void setErrors(Errorserrors) {
this.errors= errors;
}
The Errors entity:
#Entity
#Table(name = "data.invoice_errors")
public class Errors implements Serializable {
public Errors() {
}
public Errors(Invoice invoice, String error) {
this.invoice= invoice;
this.error = error;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#OneToOne
#JoinColumn(name = "id_invoice")
private Invoice invoice;
private String error;
#Column(name = "created_at")
private LocalDateTime createdAt;
public Integer getId() {
return id;
}
public Invoice getInvoice() {
return invoice;
}
public void setInvoice(Invoice invoice) {
this.invoice = invoice;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
This behaviour seems very strange and I don't know how to diagnose it and what may be wrong. Any input would be very appreciated.
What I'm expecting is that the entity don't get updated out of nowhere with a result that wasn't found initially because it simply didn't match the search criteria in the first place.
I'm a colossal idiot. The issue was that the notification class was refreshing the model. Changed the database search to go after the refresh and fixed the problem.
I am trying to use JPA to fetch records from database. However I am able to insert records indatabse and even get all the records using createQuery method of class EntityManager.
But in below case I am not getting why the condition in where clause is not working.
Please help me figure it out.
POJO class :
#Entity
#Table(name = "frameworks_filter")
public class FilteredFrameworksDbStructure {
#Id
#Column(name="id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "regular_name")
private String regularName;
#Column(name = "component_name")
private String componentName;
#Column(name = "component_owner")
private String componentOwner;
#Column(name = "frameworks")
private String frameworks;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRegularName() {
return regularName;
}
public void setRegularName(String regularName) {
this.regularName = regularName;
}
public String getComponentName() {
return componentName;
}
public void setComponentName(String componentName) {
this.componentName = componentName;
}
public String getComponentOwner() {
return componentOwner;
}
public void setComponentOwner(String componentOwner) {
this.componentOwner = componentOwner;
}
public String getFrameworks() {
return frameworks;
}
public void setFrameworks(String frameworks) {
this.frameworks = frameworks;
}
}
DAO class method:
public List<FilteredFrameworksDbStructure> getFilteredFrameworks(String regularName) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
List<FilteredFrameworksDbStructure> filteredFrameworksDbStructureList = entityManager
.createQuery("from FilteredFrameworksDbStructure F where F.regularName = :regular", FilteredFrameworksDbStructure.class)
.setParameter("regular", regularName)
.getResultList();
return filteredFrameworksDbStructureList;
}
Issue : Condition in where clause does not work. It simply fetch all the records irrespective of the regularName provided.
Regards,
Parag Vinchurkar
Why don't you use the JpaRepository or CrudRepository to fetch your results? Check out this tutorial here and here on how to use them.
And you can use your where clause. Please see below the example repository you can use to obtain the same results as the entityManager
public interface FilteredFrameworksDbStructureRepo extends JpaRepository<FilteredFrameworksDbStructure , Integer>{
List<FilteredFrameworksDbStructure> findAllByRegularName(String regularName)
}
Please note that you will have to change your id member variable from int to Integer
I'm currently working on a project where I'm trying to get a list of enities from table which does not have a primary key (dk_systemtherapie_merkmale). This table is 1:n related to another table (dk_systemtherapie). See the screenshot for the table structure.
When getting an entry for dk_systemtherapie, the program fetches the Collection "dkSystemtherapieMerkmalesById". However, the first table entry is fetched as often as the number of actual entries in the table is. It never fetches the other entries from dk_systemtherapie_merkmale. I assume it has something to do with the fact that hibernate can't differ between the entries, but I don't know how to fix it.
Table schema
I've created two corresponding entity classes, dk_systemtherapie:
#Entity
#Table(name = "dk_systemtherapie", schema = "***", catalog = "")
public class DkSystemtherapieEntity {
private int id;
private Collection<DkSystemtherapieMerkmaleEntity> dkSystemtherapieMerkmalesById;
#Id
#Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#OneToMany(mappedBy = "dkSystemtherapieByEintragId")
public Collection<DkSystemtherapieMerkmaleEntity> getDkSystemtherapieMerkmalesById() {
return dkSystemtherapieMerkmalesById;
}
public void setDkSystemtherapieMerkmalesById(Collection<DkSystemtherapieMerkmaleEntity> dkSystemtherapieMerkmalesById) {
this.dkSystemtherapieMerkmalesById = dkSystemtherapieMerkmalesById;
}
}
Here the second one, which is accessing the table without a primary key, dk_systhemtherapie_merkmale:
#Entity #IdClass(DkSystemtherapieMerkmaleEntity.class)
#Table(name = "dk_systemtherapie_merkmale", schema = "***", catalog = "")
public class DkSystemtherapieMerkmaleEntity implements Serializable {
#Id private Integer eintragId;
#Id private String feldname;
#Id private String feldwert;
private DkSystemtherapieEntity dkSystemtherapieByEintragId;
#Basic
#Column(name = "eintrag_id")
public Integer getEintragId() {
return eintragId;
}
public void setEintragId(Integer eintragId) {
this.eintragId = eintragId;
}
#Basic
#Column(name = "feldname")
public String getFeldname() {
return feldname;
}
public void setFeldname(String feldname) {
this.feldname = feldname;
}
#Basic
#Column(name = "feldwert")
public String getFeldwert() {
return feldwert;
}
public void setFeldwert(String feldwert) {
this.feldwert = feldwert;
}
#Id
#ManyToOne
#JoinColumn(name = "eintrag_id", referencedColumnName = "id")
public DkSystemtherapieEntity getDkSystemtherapieByEintragId() {
return dkSystemtherapieByEintragId;
}
public void setDkSystemtherapieByEintragId(DkSystemtherapieEntity dkSystemtherapieByEintragId) {
this.dkSystemtherapieByEintragId = dkSystemtherapieByEintragId;
}
}
I assume the problem is releated to the fact that Hibernate is using the following annotation as the one and only id for fetching data from database.
#Id
#ManyToOne
#JoinColumn(name = "eintrag_id", referencedColumnName = "id")
public DkSystemtherapieEntity getDkSystemtherapieByEintragId() {
return dkSystemtherapieByEintragId;
}
This leads to the problem that when getting more than one entry with the same id (as the id is not unique), you will get the number of entries you would like to but hibernate is always fetching the first entry for this id. So in fact you are getting dublicate entries.
So how to fix this?
According to this question: Hibernate and no PK, there are two workarounds which are actually only working when you don't have NULL entries in your table (otherwise the returning object will be NULL as well) and no 1:n relationship. For my understanding, hibernate is not supporting entities on tables without primary key (documentation). To make sure getting the correct results, I would suggest using NativeQuery.
Remove the Annotations and private DkSystemtherapieEntity dkSystemtherapieByEintragId; (incl. beans) from DkSystemtherapieMerkmaleEntity.java und add a constructor.
public class DkSystemtherapieMerkmaleEntity {
private Integer eintragId;
private String feldname;
private String feldwert;
public DkSystemtherapieMerkmaleEntity(Integer eintragId, String feldname, String feldwert) {
this.eintragId = eintragId;
this.feldname = feldname;
this.feldwert = feldwert;
}
public Integer getEintragId() {
return eintragId;
}
public void setEintragId(Integer eintragId) {
this.eintragId = eintragId;
}
public String getFeldname() {
return feldname;
}
public void setFeldname(String feldname) {
this.feldname = feldname;
}
public String getFeldwert() {
return feldwert;
}
public void setFeldwert(String feldwert) {
this.feldwert = feldwert;
}
}
Remove private Collection<DkSystemtherapieMerkmaleEntity> dkSystemtherapieMerkmalesById; (incl. beans) from DkSystemtherapieEntity.java.
Always when you need to get entries for a particular eintrag_id, use the following method instead of the Collection in DkSystemtherapieEntity.java.
public List<DkSystemtherapieMerkmaleEntity> getDkSystemtherapieMerkmaleEntities(int id) {
Transaction tx = session.beginTransaction();
String sql = "SELECT * FROM dk_systemtherapie_merkmale WHERE eintrag_id =:id";
List<Object[]> resultList;
resultList = session.createNativeQuery(sql)
.addScalar("eintrag_id", IntegerType.INSTANCE)
.addScalar("feldname", StringType.INSTANCE)
.addScalar("feldwert", StringType.INSTANCE)
.setParameter("id", id).getResultList();
tx.commit();
List<DkSystemtherapieMerkmaleEntity> merkmale = new ArrayList<>();
for (Object[] o : resultList) {
merkmale.add(new DkSystemtherapieMerkmaleEntity((Integer) o[0], (String) o[1], (String) o[2]));
}
return merkmale;
}
Call getDkSystemtherapieMerkmaleEntities(dkSystemtherapieEntityObject.getid()) instead of getDkSystemtherapieMerkmalesById().
I'm working with Spring, hibernate and MySql but I have some problem with seralization of query result.
First in my entity I added #JsonManagedReference on Set structure (#OneToMany side) and #JsonBackReference on single object reference (#ManyToOne side) and it works but I wasn't be able to retrieve all needed information (for example #ManyToOne reference).
So i swapping #JsonBackReference on set structure and #JsonManagedReference on single object but I retrieve
No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.model.tablesField.TableUI["data"]->java.util.ArrayList[0]->com.domain.Car["carType"]->com.domain.CarType_$$_jvst744_f["handler"])
I tried also with #JsonIgnore on Set structure but it doesn't work for the same issues.
This is my spring configuration
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
// properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
properties.put("hibernate.enable_lazy_load_no_trans",true);
return properties;
and this is part of one of my several entities:
/**
* Car generated by hbm2java
*/
#Entity
#Table(name = "car", catalog = "ATS")
public class Car implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer idCar;
#JsonManagedReference
private CarType carType;
#JsonManagedReference
private Fleet fleet;
private String id;
private int initialKm;
private String carChassis;
private String note;
#JsonBackReference
private Set<Acquisition> acquisitions = new HashSet<Acquisition>(0);
public Car() {
}
public Car(CarType carType, Fleet fleet, int initialKm, String carChassis) {
this.carType = carType;
this.fleet = fleet;
this.initialKm = initialKm;
this.carChassis = carChassis;
}
public Car(CarType carType, Fleet fleet, String id, int initialKm, String carChassis, String note,
Set<Acquisition> acquisitions) {
this.carType = carType;
this.fleet = fleet;
this.id = id;
this.initialKm = initialKm;
this.carChassis = carChassis;
this.note = note;
this.acquisitions = acquisitions;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id_car", unique = true, nullable = false)
public Integer getIdCar() {
return this.idCar;
}
public void setIdCar(Integer idCar) {
this.idCar = idCar;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_carType", nullable = false)
public CarType getCarType() {
return this.carType;
}
public void setCarType(CarType carType) {
this.carType = carType;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_fleet", nullable = false)
public Fleet getFleet() {
return this.fleet;
}
public void setFleet(Fleet fleet) {
this.fleet = fleet;
}
#Column(name = "id", length = 5)
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
#Column(name = "initialKm", nullable = false)
public int getInitialKm() {
return this.initialKm;
}
public void setInitialKm(int initialKm) {
this.initialKm = initialKm;
}
#Column(name = "carChassis", nullable = false, length = 20)
public String getCarChassis() {
return this.carChassis;
}
public void setCarChassis(String carChassis) {
this.carChassis = carChassis;
}
#Column(name = "note", length = 100)
public String getNote() {
return this.note;
}
public void setNote(String note) {
this.note = note;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "car")
public Set<Acquisition> getAcquisitions() {
return this.acquisitions;
}
public void setAcquisitions(Set<Acquisition> acquisitions) {
this.acquisitions = acquisitions;
}
}
one method that uses the query:
#Override
#RequestMapping(value = { "/cars/{idFleet}"}, method = RequestMethod.GET)
public #ResponseBody TableUI getCars(#PathVariable int idFleet) {
TableUI ajaxCall=new TableUI();
try {
ajaxCall.setData(fleetAndCarService.findCarsByIdFleet(idFleet));
return ajaxCall;
} catch (QueryException e) {
ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
LOG.error("Threw exception in FleetAndCarControllerImpl::addCar :" + errorResponse.getStacktrace());
return ajaxCall;
}
}
two class for the query:
public interface DefRdiRepository extends JpaRepository<DefRdi, Integer>{
//#Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM DefRdi c WHERE c.parName = ?1 AND c.description= ?2")
//Boolean existsByParNameAndDescription(String parName, String description);
//Query method of spring, I put findBy and then the key of research
DefRdi findByParNameAndDescription(String parName, String description);
}
public interface CarRepository extends JpaRepository<Car, Integer>, CarRepositoryCustom {
//Query method of spring, I put findBy and then the key of research
List<Car> findByFleetIdFleet(int idFleet);
}
Where is my error? I don't want Set object but only the single reference. The problem is only when I serialize. Thanks
UPDATE:
I use #JSonIgnore on all set collectionts and Eager instead lazy ad all works fine, but is there a way to retrieve all the information only when I want, for example having two different query?
So it doesn't work
#Override
#Transactional
public List<Car> findByFleetIdFleet(int idFleet) {
List<Car> carList= carRepository.findByFleetIdFleet(idFleet);
for (Car car:carList){
Hibernate.initialize(car.getCarType());
Hibernate.initialize(car.getFleet());
}
return carList;
// return carRepository.findByFleetIdFleet(idFleet);
}
All collections need to be fetched eagerly when loading them from data base, in order to get serialized by Spring. Make sure you fetch them eagerly (e.g. FetchMode.JOIN). You could also swap #JsonManagedReference from wanted fields with #JsonIgnore to black listed fields, Spring automatically serialises every field without annotation.
Update:
Changing the data repository to something like that should work, I am not sure it compiles, but I think you will get the point:
#EntityGraph(value = "some.entity.graph", type = EntityGraph.EntityGraphType.FETCH)
#Query(
value = "SELECT c FROM Car c INNER JOIN FETCH c.acquisitions WHERE c.id = :idFleet"
)
public interface CarRepository extends JpaRepository<Car, Integer>, CarRepositoryCustom {
//Query method of spring, I put findBy and then the key of research
List<Car> findByFleetIdFleet(int idFleet);
}
For more information look at this post and read the official documentation.
Workaround:
There seems to be a workaround, however fetching those collections eager like shown above should have a positive performance impact, since there is no need for loading proxies afterwards. Also no open transactions are needed at controller level.
I need to use raw SQL within a Spring Data Repository, is this possible? Everything I see around #Query is always entity based.
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.
YES, You can do this in bellow ways:
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.
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 :)
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);
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();
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;
}
}
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.