In my mysql database I have a table,named:-file_upload
table structure is ;-
I have stored picture in this table..Now I want to fetch the image..
So,I have:--
#Table(name = "file_upload")
public class ProfilePic {
private long id;
private String fileName;
private byte[] data;
--setters and getters with #Column annotation---
public ProfilePic(BigInteger userId) {
super();
this.userId = userId;
}
}
my dao class is:--
public ProfilePic FetchImage(ProfilePic profilePic) {
String hql = "select data from ProfilePic where userId = :userId1 ";
logger.info( profilePic.getUserId());
Query query = (Query) sessionFactory.getCurrentSession().createQuery(hql)
.setParameter("userId1", profilePic.getUserId());
return (ProfilePic) query.uniqueResult();
}
But I am getting error:---
org.hibernate.NonUniqueResultException: query did not return a unique result: 4
why??where is the problem??
This error said that Your query returns 4 rows , that this user has 4 rows in your file_upload table so query.uniqueResult() doesn't return unique result so change query.uniqueResult() to query.List()
use query.uniqueResult() when you guarantee 100% that your query will return only one single result
I don't know if you need to get all the ProfilePic objects associated with that user id or not but you can get the list and choose the one you want
public ArrayList<ProfilePic> FetchImage(ProfilePic profilePic) {
String hql = "select data from ProfilePic where userId = :userId1 ";
logger.info( profilePic.getUserId());
Query query = (Query) sessionFactory.getCurrentSession().createQuery(hql)
.setParameter("userId1", profilePic.getUserId());
return (ArrayList<ProfilePic>) query.List();
}
Related
I have a simple API that expects three parameters and sends a response back, whenever I try to pass the three parameters I end up with an error
org.hibernate.hql.internal.ast.QuerySyntaxException: REPORTS
is not mapped [SELECT e FROM REPORTS e WHERE e.country =
:country AND e.projectId = :projectId AND e.code = :code]
The Model class
#Entity(name = "REPORTS")
#Table(name = "REPORTS")
public class DashboardModel {
public String Country;
public String Project;
public String HtmlContent;
public String FileName;
public String Code;
public String TeamLead;
public String Team;
public DateTime CreateDate;
public DateTime UpdateDate;
//boiler plate code
My Controller
#GetMapping(path = "/report/reportsheet")
public ResponseEntity<String> getReportSheet(#RequestParam("country") String country,
#RequestParam("projectId") String projectId,
#RequestParam("clusterNumber") String clusterNumber){
String report = dashboardService.getReport(country,projectId,clusterNumber);
//String report_ = wallboardService.getStateReportLabelByCountryProjectAndType(country,projectId,reportType);
return ResponseEntity.status(HttpStatus.OK).body(report);
My Service
public String getReport(String country,String projectId,String code){
TypedQuery<DashboardModel> query = entityManager.createQuery(
"SELECT e FROM REPORTS e WHERE e.country = :country AND e.projectId = :projectId AND e.code = :clusterNumber" , DashboardModel.class);
List<DashboardModel> dashboard = query
.setParameter("country", country)
.setParameter("projectId", projectId)
.setParameter("clusterNumber", code)
.getResultList();
return String.valueOf(dashboard);
}
How should I map the table correctly?
You have to use entity class names like DashboardModel in the JPQL and a table name REPORTS in the SQL.
The second parameter DashboardModel.class in the createQuery() is not related to entity class name in the SELECT clause.
You can just use createQuery(jpql) with one parameter, but that method returns a List without element type. So what the second parameter DashboardModel.class for.
You don't need to specify table name here #Entity(name = "REPORTS")
just #Entity
I guess the entity is not in a package that is scanned by Spring Boot. Here is an article about this: https://springbootdev.com/2017/11/13/what-are-the-uses-of-entityscan-and-enablejparepositories-annotations/
I am trying to join 3 tables to get required info using entityManager.createQuery.
Code littlepet as follows:
List<Object[]> o=entityManager.createQuery("SELECT u.loginId,ui.emailId,u.userId,ui.firstName,up.password,ui.phoneNunber,u.roleTypeId" + " From Users as u,UserInfo ui, UserPassword as up where u.userId = up.userId " + "AND u.userId=ui.userId").getResultList();
I have a bean with the above returned fields UserDetails.
public class UserDetails
{
String LoginId;
String Email;
String UserId;
String FirstName;
String Password;
String Mobile;
String RoleTypeId;
int Status;
getters() & setters()
}
But when I am trying to use List of UserDetails instead List of Object[] it says ClassCastException.
How to get/convert the returned object with customized bean?
List<UserDetails> o=entityManager.createQuery("SELECT new package.UserDetails( u.loginId,ui.emailId,u.userId,ui.firstName,up.password,ui.phoneNunber,u.roleTypeId)" + " From Users as u,UserInfo ui, UserPassword as up where u.userId = up.userId " + "AND u.userId=ui.userId").getResultList();
You need to have constructor with parameters in the same order as the fields are selected in the query, thus UserDetails(loginId, emailId, userId, firstName, password, phoneNunber, roleTypeId)
Or you can use your code and then write a converter which converts an array of objects into UserDetails.
List<Object[]> retrievedObjects = //yourCode.
for (Object[] objs : retrievedObjects) {
//write convert method which populates **UserDetails** fields from the objects.
UserDetails ud = convert(objs);
}
You can use a result transformer. Result transformer is a Hibernate feature (not JPA). So you need to use Session or Query from Hibernate.
Something like this:
List<UserDetails> result = entityManager.createQuery(
"SELECT u.loginId as loginId, ui.emailId as emailId ..."
).unwrap(org.hibernate.query.Query.class)
.setResultTransformer(new AliasToBeanResultTransformer(UserDetails.class))
.list();
You need to have aliases in the HQL: u.loginId as loginId and corresponding properties in the UserDetails:
class UserDetails
{
private String loginId;
public String getLoginId() {
return loginId;
}
public void setLoginId(String loginId) {
this.loginId = loginId;
}
}
Examples of transformers:
http://jpwh.org/examples/jpwh2/jpwh-2e-examples-20151103/examples/src/test/java/org/jpwh/test/querying/advanced/TransformResults.java
I'm stuck, I run this query with hibernate, but do not know how to get the values that the query returns.
Query:
select idMagistrado, count(*) as numeroDemandas from demandamagistrado group by idMagistrado order by numeroDemandas asc limit 3;
DAO:
public Set<Magistrado> get3Magistrado() {
ConnectionDataBase cdb = new ConnectionDataBase();
Set<Magistrado> magistrados = null;
try {
Query createQuery = cdb.getSession().createQuery("select idMagistrado, count(*) as numeroDemandas from demandamagistrado group by idMagistrado order by numeroDemandas asc limit 3");
// Here, HELP!
if (magistrados == null) {
return null;
}
}
catch (HibernateException he) {
cdb.catchException(he);
}
finally {
cdb.closeSession();
}
return magistrados;
}
And the result in de MySQL console:
mysql> select idMagistrado, count(*) as numeroDemandas from demandamagistrado group by idMagistrado order by numeroDemandas asc limit 3;
+--------------+----------------+
| idMagistrado | numeroDemandas |
+--------------+----------------+
| 3 | 1 |
| 2 | 2 |
| 1 | 3 |
+--------------+----------------+
3 rows in set (0.00 sec)
The Query object has no method to let me know the values of idMagistrado and numeroDemandas. I do not know what to do, HELP.
I think you should know "HQL" is different from "SQL";
when you use HQL, you should query from class (not table).
so if you wanted excute the sql and get result in hibernate:
String sql = "select idMagistrado, count(*) as numeroDemandas from demandamagistrado
group by idMagistrado order by numeroDemandas asc limit 3";
you should use the method createSQLQuery (not createQuery) in this way:
List<Object[]> objList = cdb.getSession().createSQLQuery(sql).list();
for(Object[] objs : objList){
int idMagistrado = Integer.valueOf(objs[0]);
int numeroDemandas = Integer.valuesOf(objs[1]);
System.out.println(idMagistrado + ":" + numeroDemandas);
}
HQL is an object-oriented query language, similar to SQL, but instead of operating on tables and columns, HQL works with persistent objects and their properties.
Lets assume that we have a database table structure like below :
Then the Entity class for each table can be given (Hibernate mapping Java classes to database tables):
Subject
public class Subject implements java.io.Serializable {
private Integer id;
private String subName;
private String day;
private String time;
private Set subjectHasStuDetailses = new HashSet();
public Subject() {
}
//getters and setters
...
StuDetails
public class StuDetails implements java.io.Serializable {
private Integer id;
private String FName;
private String LName;
private String sex;
private String dob;
private Set subjectHasStuDetailses = new HashSet();
public StuDetails() {
}
//getters and setters
...
SubjectHasStuDetails
public class SubjectHasStuDetails implements java.io.Serializable {
private Integer id;
private StuDetails stuDetails;
private Subject subject;
public SubjectHasStuDetails() {
}
//getters and setters
...
In every entity class we can override the default constructor as we need.
Lets assume that our entity classes are in a package named com.hibernate.entities. If we need to get all the subjects doing by a selected student then our Hql query can be:
Query query = ss.createQuery("FROM com.hibernate.entities.SubjectHasStuDetails shs WHERE "
+ "shs.stuDetails.id= :s_id").
setInteger("s_id", 32);
List<com.hibernate.entities.SubjectHasStuDetails> shs = query.list();
for (SubjectHasStuDetails sh : shs) {
sh.getSubject().getSubName();
}
As we can see in the given example of Hql query we are referring to entity members of the class which is mapped to the required table.Not referring the table column names.
So in your case also you should refer the mapped entities.
SELECT d.member_variable, COUNT(*) AS d.member_variable FROM packagename.EntitityClass d GROUP BY d.member_variable ORDER BY d.member_variable ASC LIMIT 3
Update:
If you are using identified relationship:
Subject:
public class Subject implements java.io.Serializable {
private Integer id;
private String subName;
private String day;
private String time;
private Set<Student> students = new HashSet<>();
...
Student:
public class Student implements java.io.Serializable {
private Integer id;
private String FName;
private String LName;
private int age;
private Set subjects = new HashSet();
...
Query:
Query q = s.createQuery("FROM com.hibernate.entities.Subject sub JOIN sub.students s WHERE s.id= :stu_id")
.setInteger("stu_id", 1);
List<String> subj = q.list();
for (String ss : subj) {
System.out.println(ss);
}
I have a rather big model Applicant:
public class Applicant{
private Long id
private String name;
...
...
}
To populate a selection list, I need a list of (id, name) tuples and I use this search query:
public List getNames() {
Query query = em.createQuery("select a.id, a.name from Applicant a");
return query.getResultList();
}
However, I get a list of Object[]'s and I don't really want to convert these in the business layer to the corresponding types (Long and String). What is the best way to approach this? Should I iterate through the list and manually do the type conversion before returning it? Or should I make a helper class:
public class ApplicantTuple{
public Long id
public String name;
public Application(Long id, String name) {
...
}
}
and then have a search query:
Query query = em.createQuery("select NEW my.model.ApplicantTuple(a.id, a.name) from Applicant a");
Or is there a better way to type search queries?
Since you're apparently using JPA2, use the type-safe methods:
public List<Applicant> getApplicants() {
TypedQuery<Applicant> query = em.createQuery(
"select a.id, a.name from Applicant a",
Applicant.class
);
return query.getResultList();
}
Then just use the Objects:
for(Applicant app: getApplicants()){
selectionList.populate(app.getName(), app.getId());
}
I would like to return a List of Integers from a
javax.persistence.EntityManager.createNativeQuery call
Why is the following incorrect?
entityManager.createNativeQuery("Select P.AppID From P", Integer.class);
specifically why do I get "...Unknown entity: java.lang.Integer"
Would I have to create an entity class that has a single field that is an Integer ?
Thanks
What you do is called a projection. That's when you return only a scalar value that belongs to one entity. You can do this with JPA. See scalar value.
I think in this case, omitting the entity type altogether is possible:
Query query = em.createNativeQuery( "select id from users where username = ?");
query.setParameter(1, "lt");
BigDecimal val = (BigDecimal) query.getSingleResult();
Example taken from here.
That doesn't work because the second parameter should be a mapped entity and of course Integer is not a persistent class (since it doesn't have the #Entity annotation on it).
for you you should do the following:
Query q = em.createNativeQuery("select id from users where username = :username");
q.setParameter("username", "lt");
List<BigDecimal> values = q.getResultList();
or if you want to use HQL you can do something like this:
Query q = em.createQuery("select new Integer(id) from users where username = :username");
q.setParameter("username", "lt");
List<Integer> values = q.getResultList();
Regards.
Here is a DB2 Stored Procidure that receive a parameter
SQL
CREATE PROCEDURE getStateByName (IN StateName VARCHAR(128))
DYNAMIC RESULT SETS 1
P1: BEGIN
-- Declare cursor
DECLARE State_Cursor CURSOR WITH RETURN for
-- #######################################################################
-- # Replace the SQL statement with your statement.
-- # Note: Be sure to end statements with the terminator character (usually ';')
-- #
-- # The example SQL statement SELECT NAME FROM SYSIBM.SYSTABLES
-- # returns all names from SYSIBM.SYSTABLES.
-- ######################################################################
SELECT * FROM COUNTRY.STATE
WHERE PROVINCE_NAME LIKE UPPER(stateName);
-- Cursor left open for client application
OPEN Province_Cursor;
END P1
Java
//Country is a db2 scheme
//Now here is a java Entity bean Method
public List<Province> getStateByName(String stateName) throws Exception {
EntityManager em = this.em;
List<State> states= null;
try {
Query query = em.createNativeQuery("call NGB.getStateByName(?1)", Province.class);
query.setParameter(1, provinceName);
states= (List<Province>) query.getResultList();
} catch (Exception ex) {
throw ex;
}
return states;
}
Suppose your query is "select id,name from users where rollNo = 1001".
Here query will return a object with id and name column.
Your Response class is like bellow:
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 a Object Array and set data with 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 rollNo = ?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 you have to get EntityManager and call this getUserByRoll(EntityManager entityManager,String rollNo) function. Calling procedure is given bellow:
#PersistenceContext
private EntityManager entityManager;
UserObject userObject = getUserByRoll(entityManager,"1001");
Now you have data in this userObject.
Here is Imports
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
Note:
query.getSingleResult() return a array. You have to maintain the column position and data type.
select id,name from users where rollNo = ?1
query return a array and it's [0] --> id and [1] -> name.
For more info, visit this Answer
Thanks :)
JPA was designed to provide an automatic mapping between Objects and a relational database. Since Integer is not a persistant entity, why do you need to use JPA ? A simple JDBC request will work fine.