How to make a simple left join with criteria? - java

I have a table of users, with user_id.
I'm fetching users like this:
Criteria c = session.createCriteria(User.class);
now I have a table tickets with a foreign key to the users table. there is a column user_id
i want in my criteria to get all the users with ticket type X.
i tried something like this:
c.createAlias("ticket", "ticket");
c.add(Restrictions.ne("ticket.type", "X"));

In the createAlias method you can specify which join you need.
Criteria c = session.createCriteria(User.class)
.createAlias("ticket", JoinType.LEFT_OUTER_JOIN);
or
Criteria c = session.createCriteria(User.class, "user")
.createAlias("user.ticket", "ticket", JoinType.LEFT_OUTER_JOIN);

Related

Add count of child table to select from parent with hibernate criteria API

How can I execute this SQL query using the Hibernate Criteria API?
SELECT c.*, count(r.id) FROM COURSE c left join REFERRAL r on c.id = r.course_id group by c.id
Something like this seems close enough:
Criteria criteria = currentSession().createCriteria(Referral.class, "r");
criteria.createAlias("r.course", "course");
ProjectionList projections = Projections.projectionList();
projections.add(Projections.groupProperty("course.id"));
projections.add(Projections.count("r.id"));
return list(criteria
.setProjection(projections));

Get multiple entities from hibernate sql join

I have 4 table:
Orders(orderID, orderDate, orderItem (OneToMany))
OrderItem(id, order(manyToOne), book (manyToOne), quantity)
Book (id, title, cost)
User(id, username, password)
Here is my query in SQL:
String sql = "SELECT orders.id, book.title, orderitem.quantity
FROM orderitem INNER JOIN book ON book.id = orderitem.book_id INNER JOIN orders ON orders.id = orderitem.orders_id WHERE user_id = 1;
(user_id is the foreign key of User in Orders table)
(orders_id is the foreign key of Orders in OrderItem table)
List<OrderItem> orderBookInfo = (List<OrderItem>) session.createSQLQuery(sql); // returns List<Object[]> why?!
This query result comes from joining of 3 tables (Book, Order, OderItem)
And this is the result in table:
Question is how can i assign each result's column to it's corresponding properties?
For example:
orderBookInfo.order.id = (first location of orderBookInfo)
orderBookInfo.book.title = (second location of orderBookInfo)
You need to execute an Entity query instead. Assuming you already mapped the entities properly, this is how the HQL query would look like:
SELECT o
FROM orderitem oi
JOIN FETCH oi.book
JOIN FETCH oi.orders
JOIN FETCH oi.user u
WHERE u.id = 1;

Criteria (NOT IN)

please, help me:
I have next tables:
Unit
id
name
User
id
name
Rate
unit_id
user_id
I do not understand how to create correct structure of criteria from SQL:
Code:
SELECT * FROM Unit WHERE id not in (SELECT unit_id FROM Rate WHERE user_id = 55);
I saw this answer. But I do not understand how to make Condition linked to another Table (Entity).
Looking yor tag I think you need the Criteria view of your SQL query; so assuming Unit and Rate classes:
// This is the subquery
DetachedCriteria subquery = DetachedCriteria.forClass(Rate.class)
.add(Restrictions.eq("user_id", 55))
.setProjection(Projections.id())
// This corresponds to (SELECT * FROM Unit WHERE id not in (subquery))
Criteria criteria = session
.createCriteria(Unit.class)
.add(Subqueries.notIn("id", subquery));
I don't know that IN would be the most appropriate in this case. Try an inner join to link up the tables:
SELECT * FROM Unit INNER JOIN Rate ON Rate.unit_id = Unit.id
WHERE Rate.user_id = 55

Hibernate, search by primary key returns all from table

I have this issue with Hibernate that when i try to retrieve unique result using criteria hibernate returns all the content from the table.
Session session = HibernateUtil.beginTransaction();
Customer c = new Customer();
c.setCustId(custId);
Example ex = Example.create(c);
Criteria criteria = HibernateUtil.getSession().createCriteria(Customer.class);
criteria.add(ex);
Customer customer = (Customer)criteria.uniqueResult();
HibernateUtil.commitTransaction();
HibernateUtil.closeSession();
However querying the table with:
Customer customer = (Customer)session
.createSQLQuery("select * from customer_ where custid = :id")
.addEntity(Customer.class)
.setInteger("id", custId)
.uniqueResult();
returns correct entry.
custId is the table's primary key. And the Customer class contains 2 #OneToMany mappings.
Do I need to add something to the criteria example above??
The documentation says:
Version properties, identifiers and associations are ignored.
(emphasis mine)
Why not simply using Session.get() if you have the identifier?

Hibernate detached queries as a part of the criteria query

java experts can you please help me write detached queries as a part of the criteria query for the following SQL statement.
select A.*
FROM AETABLE A
where not exists
(
select entryid
FROM AETABLE B
where B.classpk = A.classpk
and B.userid = A.userid
and B.modifiedDate > A.modifiedDate
)
and userid = 10146
You need to write a correlated subquery. Assuming property / class names match column / table names above:
DetachedCriteria subquery = DetachedCriteria.forClass(AETable.class, "b")
.add(Property.forName("b.classpk").eqProperty("a.classpk"))
.add(Property.forName("b.userid").eqProperty("a.userid"))
.add(Property.forName("b.modifiedDate").gtProperty("a.modifiedDate"));
Criteria criteria = session.createCriteria(AETable.class, "a")
.add(Property.forName("userid").eq(new Integer(10146)))
.add(Subqueries.notExists(subquery);
Just one addition to the above query. If the entryid is not the primary key, then you'll need to add projection.
DetachedCriteria subquery = DetachedCriteria.forClass(AETable.class, "b")
.add(Property.forName("b.classpk").eqProperty("a.classpk"))
.add(Property.forName("b.userid").eqProperty("a.userid"))
.add(Property.forName("b.modifiedDate").gtProperty("a.modifiedDate"))
.add(setProjection(Projections.property("entryId")); // Additional projection property
Criteria criteria = session.createCriteria(AETable.class, "a")
.add(Property.forName("userid").eq(new Integer(10146)))
.add(Subqueries.notExists(subquery);

Categories