Simple jpa question - java

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

Related

Hibernate - Select all rows in a table

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();

JPA NamedQuery Select specific column and return class type

I am using JPA, I have the basic named query like this
#NamedQuery(name="Manifest.findAll", query="SELECT m FROM Manifest m")
When I call this,
entityManager.createNamedQuery("Manifest.getManifestInfo").getResultList()
I get the object back in a list like this
[{id:"1", name:"foo"},{id:"2", name:"bar"}]
But then I have another named query where I just get the names
#NamedQuery(name="Manifest.getManifestName", query="SELECT m.name FROM Manifest m")
When I run that query I get
[["foo"],["bar"]]
How can I get the second query to return the object type so its liek
[{name:"foo"},{name:"bar"}]
I made this simpler to show what I am trying to do here, the actual table has more columns but it is the same principal.
How can I return the object type?
The feature for that use case in JPA is an Entity Graph.
Define it on your entity like this:
#NamedEntityGraph(name="nameOnly", attributeNodes={
#NamedAttributeNode("name")
})
#Entity
public class Manifest {
...
}
You'd leave your query itself unchanged, but apply the Entity Graph to the query before running it, either as a Load or a Fetch Graph (see link above for explanation):
EntityGraph<EmailMessage> eg = em.getEntityGraph("nameOnly");
entityManager.createNamedQuery("Manifest.getManifestInfo").setHint("javax.persistence.loadgraph", eg).getResultList()

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.

How to bulk delete from element collection in jpa

I'm using jpa 2.0 and I have the following entity:
#Entity
public class Folder{
#ElementCollection
#CollectionTable(name="folder_files")
private Set<String> files;
// .....
}
Given a file name, I would like to delete all entries where files == theGivenFileName. In sql it would be something like this:
Delete from folder_files where files = XXX
Is there a way to perform this query using criteria-api?
If not, is there a way to perform this query using jpql?
UPDATE:
I think my question was not clear enough:
Since jpql uses entities (and not tables) I cannot just perform the sql written above plus since I'm using #ElementCollection I don't know how to address this variablr or even deal with it. I would like to delete all entries in that collection (in my case, the files set) which holds a given value, from all entities. Is that possible using jpql or (even better) criteria-api?
The Delete FROM clause requires an Entity, so there is no way to delete from an element collection from what I understand.
You can use a native SQL query, or you can map the element collection as a OneToMany to an Entity instead.
You can use the like query just the syntax is slightly changed.
query = em.createQuery("SELECT i FROM Item i WHERE UPPER(i.name) LIKE :keyword ");
query.setParameter("keyword", "%" + keyword.toUpperCase() + "%");
You can read more on following link,
https://forums.oracle.com/forums/thread.jspa?threadID=423742
Updated:
#Noam you can do it: Like in Criteria API
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.add( Restrictions.between("weight", minWeight, maxWeight) )
.list();
Kindly read more on it at following link:
http://ctpconsulting.github.com/query/1.0.0.Alpha3/criteria.html
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querycriteria.html
This cannot be done. Via JPQL it does not work because DELETE statement can only be applied to entities. Excerpt from JPA 2.0 specification:
Bulk update and delete operations apply to entities of a single entity
class (together with its subclasses,if any).
...
delete_statement ::= delete_clause [where_clause]
delete_clause ::= DELETE FROM entity_name [[AS] identification_variable]
Also it doesn't work via Criteria API. CriteriaQuery supports only selecting - not updates or removals.
You have to go for native SQL.

How to find using JPQL if member value is in a collection of values

I have an object in which a member is an enum, and I want to write a query returning all elements for which that member is in a list of values. So, I've written the following JQP query
#NamedQuery(name = MyBean.FIND_BY_STATUSES, query = "select t from "+MyBean.TABLE+" t where t.status member of :statuses"),
class MyBean {
#Enumerated(EnumType.STRING)
private MyEnum status;
}
That I try to get using the following EJB code
Query findByStatuses = getEntityManager().createNamedQuery(MyBean.FIND_BY_STATUSES);
findByStatuses.setParameter("statuses", Arrays.asList(statuses));
return findByStatuses.getResultList();
Unfortunatly, Glassfish endlessly tells me I'm wrong (which I am, obviously).
But what do I have to fix ? and how ?
First your query references to table name, so it tries to be kind of SQL, but maybe database does not have "MEMBER OF"-operator which would be suitable for this kind of use, so let's try with JPQL. There we cannot use MEMBER OF, because it takes path expression as an argument, and that is not what we provide in setParameter. Instead we use IN:
#NamedQuery(name = MyBean.FIND_BY_STATUSES, query = "select t from MyBean t where t.status in(:statuses)")
No need to modify part where you run query.

Categories