Hibernate - Select all rows in a table - java

Im trying to get my query to load all rows in a table, im working with hibernate.
#Override
public List<Teacher> getTeachersBySubject(Subject subject) {
List<Teacher> teachersBySubject = entityManager.createQuery("SELECT * FROM teacher t INNER JOIN teacher_subject ts on t.email = ts.email")
.getResultList();
return teachersBySubject;
}
The * (All) Gives the error im dealing with, it won't load because of hibernate
the error that im getting is this : org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: * near line 1, column 8 [SELECT * FROM com.scalda.vos.models.Teacher t INNER JOIN teacher_subject ts on t.email = ts.email]

its not native and your writing hql so replace * with t.

You have written a native query, which must be compiled using the createNativeQuery method.
The createQuery expects HQL and not native SQL, and therefore to do it in HQL use just "teacher FROM Teacher". Also, if you are just retrieving a Teacher and not a Teacher-Subject hybrid then, Hibernate can also help you with retrieving associations check this

HIbernate expects you to use JPQL, it looks like SQL, but should be like this:
SELECT t FROM teacher t JOIN t.subject
Of course, it depends on how you Teacher class is annotated (ManyToMany, OneToMany mappings).

as my recommendation, use hql for clear code in hibernate or using criteria
but, still running well in native.
For native SQL, use createSqlQuery, like :
List<Teacher> teachersBySubject = entityManager.createSqlQuery("SELECT * FROM teacher t INNER JOIN teacher_subject ts on t.email = ts.email")
.getResultList();

Related

GenericJDBCException: could not extract ResultSet

I found similar questions about this error but I can't make it work
I'm working on a java 8, spring 2.6.4 and a MySQL database
I'm trying to do a DELETE native query using JPA and I'm getting this error:
org.springframework.orm.jpa.JpaSystemException: could not extract ResultSet; nested exception is org.hibernate.exception.GenericJDBCException: could not extract ResultSet
this is my query:
#Query(value = "DELETE FROM reservation a WHERE a.slotid =:slotid", nativeQuery = true)
void deleteWhereSlotid(Integer slotid);
and this is the service:
repo.deleteWhereSlotid(reservationSlot.getId());
I've also tried:
#Query(value = "DELETE FROM reservation a WHERE a.slotid =:slotid", nativeQuery = true)
Object deleteWhereSlotid(Integer slotid);
//service
Object object= userCourseResRepo.deleteWhereSlotid(reservationSlot.getId());
but it failed
Usually I delete rows with deleteById(id) which comes with spring
The query works though, I tried it on phpMyadmin console and it worked
Someone know what I can try?
The way you have it set up, Spring Data assume you want to perform a query (typically a SELECT). For DELETE and similar statements that don't return a ResultSet you need to provide an additional #Modifying annotation.
#Modifying
#Query(value = "DELETE FROM reservation a WHERE a.slotid =:slotid", nativeQuery = true)
void deleteWhereSlotid(Integer slotid);
I know is not the best solution, but you can try to use a query SELECT to find your reservation object and then do this repo.deleteById(reservation.getId())
This should allow you to go ahead while you find a better way to do it
If you are using it that way, I believe the query should be:
DELETE a FROM reservation a WHERE a.slotid =:slotid
I am not particularly sure about the code, however, with Mysql, the case seems to be so when giving an alias to the table.
You need to add #Param
#Query(value = "DELETE FROM reservation a WHERE a.slotid =:slotid", nativeQuery = true)
Object deleteWhereSlotid(#Param("slotid")Integer slotid);
As mentioned above, we use the #Param annotation in the method declaration to match parameters defined by name in JPQL/Native query with parameters from the method declaration.

Dynamic Named Query in Entity class using JPQL example

I have a named query as below;
#NamedQuery(name = "MyEntityClass.findSomething", query = "SELECT item FROM MyTable mytbl")
Now I want to append dynamic sort clause to this query (based on UI parameters)
Can I get an example using JPQL for doing the same (like how to set a dynamic ORDER BY in the Entity class)
I have already tried using CriteriaQuery, but was looking for a JPQL implementation now.
NamedQueries are by definition NOT dynamic, it is not correct to change them programmatically.
So the way to go is to create a JPQL query (but not a named query) like this:
TypedQuery<MyEntity> query = em.createdQuery("SELECT item FROM MyEntity item ORDER BY "+sortingCol, MyEntity.class);
On the other hand, if you REALLY want to use the named query, you could do that the following way:
#NamedQuery(name = "MyEntityClass.findSomething", query = MyEntity.NAMED_QUERY)
#Entity
public class MyEntity {
public static final NAMED_QUERY= "SELECT item FROM MyTable mytbl";
//+your persistent fields/properties...
}
//and later in your code
TypedQuery<MyEntity> query = entityManager.createQuery(MyEntity.NAMED_QUERY + " ORDER BY " + sortingCol, MyEntity.class);
Complementing for JPA 2.1
As of JPA 2.1 it is possible to define named queries programmatically.
This can be achieved using entityManagerFactory.addNamedQuery(String name, Query).
Example:
Query q = this.em.createQuery("SELECT a FROM Book b JOIN b.authors a WHERE b.title LIKE :title GROUP BY a");
this.em.getEntityManagerFactory().addNamedQuery("selectAuthorOfBook", q);
// then use like any namedQuery
Reference here
This can be useful, for instance, if you have the orderby field defined as a application parameter. So, when the application starts up or on the first run of the query, you could define the NamedQuery with the defined OrderBy field.
On the other side, if your OrderBy can be changed anytime (or changes a lot), then you need dynamic queries instead of NamedQuery (static). It would not worth to (re)create a NamedQuery every time (by performance).
#NamedQuery
Persistence Provider converts the named queries from JPQL to SQL at deployment time.
Until now, there is no feature to create/update the query with #NamedQuery annotation at runtime.
On the other hand, you can use Reflection API, to change the annotation value at runtime. I think It is not solution, also it is not you wanted .
em.createQuery()
Persistence Provider converts the dynamic queries from JPQL to SQL every time it is invoked.
The main advantage of using dynamic queries is that the query can be created based on the user inputs.

distinct inner join hql

I've the following hibernate entities
public class Container {
...
#OneToMany
private List<ACLEntry> aclEntries;
}
For securing my container instances i use the following entity:
public class ACLEntry {
...
private Long sid;
private boolean principal;
private Integer mask;
}
The hql-queries will be created automatically so for searching container instances,
the following query will be created:
select container from Container container
inner join container.aclEntries as aclEntry
with bitwise_and (aclEntry.mask, 1) = 1 and
(aclEntry.sid = :userId or aclEntry.sid = :roleId)
The problem with this is, that the aclentry join could return 2 results which will result in duplicate container results.
Has anyone an idea how to solve this ?
As far as I understood the problem you need a container that can hold multiple entries of your Container object just replace your hql query with the following one:
With adding select distinct as native query.
As a brute force solution, you could write a native query.
It might make more sense to write this as a Criteria query, which easily supports selecting an object based on conditions of it's associations.
The same thing can be done in HQL or a native query, it might be instructive to execute a Criteria query specifying the same logic and just see what HQL/SQL it generates.

JPA Query MONTH/YEAR functions

How can I write a JPA query using MONTH function just like sql query?
#NamedQuery(name="querybymonth", query="select t from table1 t where MONTH(c_Date) = 5")
When I use the above pattern for query, I get an error: unexpected token - MONTH.
If you are using EclipseLink (2.1) you can use the FUNC() function to call any database function that is not defined in the JPA JPQL spec.
i.e.
FUNC('MONTH', c_Date)
In JPA 2.1 (EclipseLink 2.5) the FUNCTION syntax becomes part of the specification (and replaces the EclipseLink-specific FUNC).
If you are using TopLink Essentials, you cannot do this in JPQL, but you can define a TopLink Expression query for it (similar to JPA 2.0 criteria), or use native SQL.
Also if you are using any JPA 2.0 provider and using a Criteria query there is a function() API that can be used to define this.
I want to query YEAR(itemDate) but the function doesn't exit, then i saw the SUBSTRING() function so what i did was
Select q from table where SUBSTRING(itemDate, 1, 4)='2011'
and it works for me! hope it helps!
if you need you a dynamic variable, you can do that too. here :poDate is the year which is deifned in the setParameter();
#NamedQuery(name = "PurchaseOrders.findByYear", query = "SELECT p FROM PurchaseOrders p WHERE SUBSTRING(p.poDate, 1, 4) = :poDate")
Query q = em.createNamedQuery("PurchaseOrders.findByYear");
q.setParameter("poDate", s_year+"");
but if your okay with your solutions, that'll be fine. i just find JPA faster to execute.
The MONTH() function exists in Hibernate HQL but is not a standard JPA function. Maybe your JPA provider has some proprietary equivalent but you didn't mention it. If it doesn't, fall back on native SQL.
I am using Toplink Essentials for the same. Please help, if any function exists in Toplink. Thanks.
To my knowledge, TopLink doesn't have a direct equivalent. So either use a native SQL query or maybe a TopLink Expression query (not sure about this, and not sure this is available in TopLink Essentials).
Following worked for me with hibernate (4.3.9.Final) & JPA 2.1.
#NamedQuery(name = "PartyEntity.findByAID", query = "select distinct psc.party from PartyShortCode psc where (psc.shortCode = :aidNumber or FUNCTION('REPLACE',psc.accountReference,' ','') = :aidNumber) and psc.sourceSystem in :sourceSystem")
if your class holds a date type variable, you can use a query like this:
#Query("select m from Movement m where m.id_movement_type.id=1 and SubString(cast(m.date as text),1,4) = :year")
List<Movement> buysForYear(#Param("year") String year);

Simple jpa question

I have to go through some code of a project to implement some missiong functionality.
It uses jpa.In some popj classes i have found
#Entity
#Table(name="TYPE")
#NamedQueries( {
#NamedQuery(name = "getTypes", query = "SELECT dct FROM Type dct")
})
I know that i can used to get all records by using this query.Does this query return all records in type table?
This query will return all the Type entities including subtypes, if any. And since I can't say if this there are any subtypes, I can't say if this query will be restricted to the TYPE table.
Yes, it does. It generates an SQL query that looks roughly like this:
SELECT [column list here] FROM type

Categories