how to query the join table using hibernate? - java

I have created three tables in Oracle SQL Developer namely
1.Test_Employee2
2.Test_Project2
3.Employee_Project2.
The table Employee_Project2 is the join table as the relation between Test_Project2 and Employee_Project2 is Many-To-Many.
In hibernate I created to two hibernate classes TestEmployee and TestProject for Test_Project2 and Employee_Project2 tables respectively,
and the table Employee_Project2 was defined in TestProject hibernate class as follows:
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "Employee_Project2", joinColumns = #JoinColumn(name = "proj_id"), inverseJoinColumns = #JoinColumn(name = "emp_id"))
private Set<TestEmployee> employeesList;
I populated the tables Test_Project2 and Employee_Project2 with some records, and the join table Employee_Project2 automatically got populated with some records.
now the problem I am facing currently is, I want to use a simple select statement on the join table Employee_Project2 using hiberante as follows:
String hql = "FROM Employee_Project2";
Query query = session.createQuery(hql);
List results = query.list();
for (Object row : results) {
//what to do here
}
how can I do that despite the join table 'Employee_Project2' is not a hibernate class.?
update:
I would like to retrieve all the records in the hibernate table "TestProject", so i wrote the following code
String hql = "FROM TestProject";
Query query = session.createQuery(hql);
List results = query.list();
System.out.println("results.get(0)" + results.get(0).toString());
now the problem is, at run time i receive something like the following
results.get(0)msc.hibernate.persistence.TestProject#12ec9534
how can i get the values contained in the each row??

What you want to do is to create typed query. With proper mapping you can get related objects as well - no need to query join tables as ORM will do this for you:
Query query = session.createQuery(hql);
List<TestProject> results = query.list();
for (TestProject row : results) {
//what to do here
// do whatever you want
}
And with propper relation mapping you can get relations like this:
for (TestProject row : results) {
Set<TestEmployee> employees=row.getEmployeesList();
// do more work.
}
As for "how to"s - the topic is too broad to cover it in single answer etc. but you should be able to start from here - http://hibernate.org/orm/documentation/5.1/

Related

Best approach to delete 2000 records using JPQL in spring-jpa

If in the database table, the records limit exceeds 10000 (10K) , then i need to delete old 2000 (2K) based on timestamp by using JPA name query.
Below are my named queries,
#NamedQuery(name = FIND_COMMN_LOG_ID_BY_DEVICE_ID,
query = "select entity.id from table1 entity where entity.deviceId =:deviceId ORDER BY recordedTime ASC"),
#NamedQuery(name = DELETE_LOG_BY_DEVICE_ID_BASED_ON_TIMESTAMP,
query = "delete from table1 entity where entity.id in (:IdList)")})
There are used this way:
List<Integer> list = entityManager.createNamedQuery(Constants.FIND_COMMN_LOG_ID_BY_DEVICE_ID)
.setParameter("deviceId", deviceId)
.setMaxResults(2000)
.getResultList();
int count = entityManager.createNamedQuery(Constants.DELETE_LOG_BY_DEVICE_ID_BASED_ON_TIMESTAMP)
.setParameter("IdList", list)
.executeUpdate();
Above queries are working but i am getting performance issues and it is taking a lot of time to delete 2000 records and server is crashing also.
Can anyone has better simple and fast approach to delete 2000 records?
Thanks in Advance!!
Try something like that :
#NamedQuery(name = FIND_COMMN_LOG_ID_BY_DEVICE_ID, query = "select entity from table1 entity where entity.deviceId =:deviceId ORDER BY recordedTime ASC"),
List entities = entityManager.createNamedQuery(Constants.FIND_COMMN_LOG_ID_BY_DEVICE_ID).setParameter("deviceId", id).execute();
entityRepository.deleteInBatch(entities);

Hibernate: Query to select values from multiple tables using CriteriaQuery

Let's say, I have a query like
Select a.valA, b.valB
from tableA a join tableB b on a.joinCol = b.joinCol
where a.someCol = 1.
I want to execute it using Hibernate (and Spring Data) in one query to the database. I know, I can write just
Query query = em.createQuery(...);
List<Object[]> resultRows = (List<Object[]>)query.getResultList();
But my question would be - is it possible to do it in a typesafe way, using CriteriaQuery for example? The difficulty is, that, as you see, I need to select values from different tables. Is there some way to do this?
Simple example where an Employee has many to many relation to several jobs that he may have :
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Tuple> criteria = builder.createTupleQuery();
Root<TableA> root = criteria.from(TableA.class);
Path<Long> qId = root.get("id");
Path<String> qTitle = root.get("title");
Join<TableA, TableB> tableTwo = root.join("joinColmn", JoinType.INNER);
criteria.multiselect(qId, qTitle, tableTwo);
List<Tuple> tuples = session.createQuery(criteria).getResultList();
for (Tuple tuple : tuples)
{
Long id = tuple.get(qId);
String title = tuple.get(qTitle);
TableB tableB= tuple.get(tableTwo);
}
but saw that there is an alternate answer here :
JPA Criteria API - How to add JOIN clause (as general sentence as possible)

How to update only one row in table but with greatest id number by JPQL

I run following code intend to update the least record in the table on Hibernate 3.6.7 final (JPA 2.0?) :
Query query = em.createQuery("UPDATE MyTable a SET a.isEnable=1 WHERE a.isEnable=0 ORDER BY a.id DESC").setMaxResults(1);
query.executeUpdate();
but hibernate ignores ORDER BY when generating sql.
Is ORDER BY for SELECT use only in JPQL? How to execute UPDATE query with ORDER BY in JPA?
thanks for any help.
To update the record with the last ID in a table you do the following:
TypedQuery<MyEntity> query = em.createQuery("SELECT a FROM MyEntity a WHERE a.isEnable=0 ORDER BY a.id DESC", MyEntity.class);
query.setMaxResults(1);
List<MyEntity> resultList = query.getResultList();
if (resultList.size()>0) {
resultList.get(0).setEnabled(true);
//eventually you can to em.flush();
}

hibernate HQL delete query nullifies single column

I am working on spring hibernate application and trying to delete from a table using non-id many-to-one relationship based column.
Entity classes are:
#Entity
public class Day {
#id(name = "DAY_ID")
dayId;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "DAY_ID")
List<Holiday> holidayList;
...
}
#Entity
public class Holiday {
#id(name="HOLIDAY_ID")
holidayId;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "DAY_ID")
Day day;
...
}
I am trying to delete a row from holiday table using hql.
String query = "DELETE FROM Holiday WHERE day.dayId = " + dayObject.getdayId();
Query holidayDeleteQuery = getSession().createQuery(query);
holidayDeleteQuery.executeUpdate();
In the console i am getting proper delete query but on checking DB found out that the row is still there but now the DAY_ID column in holiday table is null. I am not able to figure out why is this happening?
EDIT: help!!! My main problem is why DAY_ID column is changing to null value??
I'm not sure that this is your problem, but in your query you say "DELETE FROM Holidays ...", but your Class name is Holiday. In HQL you should be using Class names rather than table names or anything else. Is this typo in your code or just on here?
Actually after looking further there are a few more problems. This is how I'd write it:
String query = "DELETE FROM Holiday h WHERE h.day = :day";
Query holidayDeleteQuery = getSession().createQuery(query);
query.setParameter("day", dayObject);
holidayDeleteQuery.executeUpdate();
To break it down - use the Class name "Holiday", assign it an alias "h" then reference the day field of the Holiday object ("h.day") and compare it to the actual Day object you have.
What is your ONDELETE foreign key constrain? Might it that other part of your application inserting a row?

Hibernate Criteria Api Subqueries

I am currently working on a project to transfer some legacy jdbc select statements over to using Hibernate and it's criteria api.
The two relevant table columns and the SQL query looks like:
-QUERIES-
primaryId
-QUERYDETAILS-
primaryId
linkedQueryId -> Foreign key references queries.primaryId
value1
value2
select *
from queries q
where q.primaryId not in (SELECT qd.linkedQueryId
FROM querydetails qd
WHERE (qd.value1 LIKE 'PROMPT%'
OR qd.value2 LIKE 'PROMPT%'));
My entity relationships look like:
#Table("queries")
public class QueryEntity{
#Id
#Column
private Long primaryId;
#OneToMany(targetEntity = QueryDetailEntity.class, mappedBy = "query", fetch = FetchType.EAGER)
private Set<QueryDetailEntities> queryDetails;
//..getters/setters..
}
#Entity
#Table(name = "queryDetails")
public class QueryDetailEntity {
#Id
#Column
private Long primaryId;
#ManyToOne(targetEntity = QueryEntity.class)
private QueryEntity query;
#Column(name="value1")
private String value1;
#Column(name="value2")
private String value2;
//..getters/setters..
}
I am attempting to utilize the criteria api in this way:
Criteria crit = sessionFactory.getCurrentSession().createCriteria(QueryEntity.class);
DetachedCriteria subQuery = DetachedCriteria.forClass(QueryDetailEntity.class);
LogicalExpression hasPrompt = Restrictions.or(Restrictions.ilike("value1", "PROMPT%"),
Restrictions.ilike("value2", "PROMPT%"));
subQuery.add(hasPrompt);
Criterion subQueryCrit = Subqueries.notIn("queryDetails", subQuery);
crit.add(subQueryCrit);
List<QueryMainEntity> entities = (List<QueryMainEntity>) crit.list();
System.out.println("# of results = " + entities.size());
I am getting a NullPointerException on the crit.list() line that looks like
Exception in thread "main" java.lang.NullPointerException
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getProjectedTypes(CriteriaQueryTranslator.java:362)
at org.hibernate.criterion.SubqueryExpression.createAndSetInnerQuery(SubqueryExpression.java:153)
at org.hibernate.criterion.SubqueryExpression.toSqlString(SubqueryExpression.java:69)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:380)
at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:114)
at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:83)
at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:92)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1687)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
Now, I think its pretty safe to say I'm using the Criteria Api/Detached Query Api incorrectly, but I'm not sure what the 'correct' way to do it is since the Hibernate Docs only briefly cover criteria api subqueries.
I realize this is a pretty long question, but I figure its appear to put it all the relevant aspects of the question (query I'm attempting to represent via Criteria API, tables, entities).
Give this a shot:
DetachedCriteria d = DetachedCriteria.forClass(QueryDetailEntity.class, "qd");
d.setProjection(Projections.projectionList().add(Projections.property("qd.query")));
d.add(Restrictions.or(Restrictions.like("qd.value1", "PROMPT%"), Restrictions.like("qd.value2", "PROMPT%")));
criteria = session.createCriteria(QueryEntity.class, "q");
criteria.add(Subqueries.propertyNotIn("q.primaryId", d));
criteria.list();
The use of the following are property names, not column names:
qd.query
qd.value1
qd.value2
q.primaryId
As a side note, if this is not a dynamically generated query, have you given thought to using HQL instead?

Categories

Resources