I am using Hibernate with my Spring MVC project.
Lets say my model has 2 objects each linked to Oracle tables, respectively USERS (USERID, NAME) and USERMONEYDATA (CATEGORY, USERID, AMOUNT)
My users can add , edit and remove rows in USERMONEYDATA, that belongs to them of course.
Now, I want to have a view that aggregates those data.
Using oracle, I made a simple view to get the total amount per user and category :
select userid, category, sum(amount)
from USERS a inner join USERMONEYDATA b on a.USERID = b.USERID
group by userid, category
But what is the best way to use it? should I create a new MODEL object specifically for this view ?
Should I aggregate directly in Hibernate ? But if yes, how do I display the results if I dont have a specific POJO object to map it to ?
thanks
If User and UserMoneyData are mapped as Hibernate entities, it's a natural choice to run aggregate queries in Hibernate.
By default, HQL or JPQL SELECT clause with multiple paths produces tuples in the form of Object[]. Since this kind of data is read-only, you may display these arrays directly, without converting them to objects.
Another option is to create a POJO for representing results of the query and use a constructor syntax SELECT NEW MoneyReport(u.userId, d.category, SUM(d.amount)) .... These POJOs don't need to be entities.
See also:
Chapter 15. HQL: The Hibernate Query Language
Related
How to retrieve/display column names and its data based on dynamic query in spring data jpa?
Example dynamic query be like
Select empid, empname, address from emp (or)
Select productiD, pname, price, pquantity from Product
I don't want to map entity just need to display data?
For a completely dynamic query Spring Data JPA doesn't offer any special support, so in order to integrate it into your repository you'll need to define a custom method.
Since you only want a Map anyway the easiest way might be to use a SQL query, execute it with a JdbcTemplate and have a simple ResultSetExtractor that inserts the values from the ResultSet into a Map.
If you want to utilise the mapping information of JPA you might construct a query using the Criteria API where you explicitly specify all the columns you want and specify Tuple as target type.
I am attempting to create a domain/entity class based on a complex query. The query unions a bunch of tables together and unfortunately I am not able to create a view on the database for this query. I have been trying to set up the entity object but I am unsure of how to ensure that the marshaling works properly (and ensure the entity acts as read-only object).
As an example of the query, I am doing something like this:
Select
U_T.a,
U_T.b,
U_T.c,
C_T.a
FROM
(select
A_T.a,
null as b,
A_T.c,
1 as ind
from A_T
UNION
select
B_T.a,
B_T.b,
null,
0 as ind
FROM B_T
) U_T
left outer join C_T on C_T.fk_a = U_T.a;
The other issues are that this union can result in instances where there is no unique key column. This is fine as this data is for viewing only, and never editing. However the #Entity annotation wants a column to be listed with the #ID annotation. Another issue is that I do not believe I can use the other entity classes as the goal is to reduce the number of DB transactions from this query (as the actual one can result in hundreds of recursive queries being performed).
If I need to give any more information please let me know.
Example:
List<Object[]> list = em.createQuery(
"SELECT 'Foo', 123 FROM IrcEvent ev", Object[].class).getResultList();
What I don't like in that example:
How do I know the table name? Can't I specify the entity class instead?
How do I know the column name? jOOQ provides auto-completion by creating a DSL from the database schema.
There could be syntax errors everywhere.
What I basically want is something like
entityManager.deleteAll(EntityClass.class);
to delete the rows of an antire table (for example).
JPA 2 Criteria API http://docs.oracle.com/javaee/6/tutorial/doc/gjitv.html is for creating type safe queries programmatically, but it does not support deletes
Most of the DAO examples I've seen consist of simple queries only involving one table.
I'm working on refactoring a project with no DAO that has lots of SQL queries where multiple tables are used. My question is how to best design the model for the DAO? In the examples below I could create a object that covers each specific query. However I'm uncertain as to whether this is good practise or not. e.g. is it better to have one object representing each db table?
CustomerPaymentDAO to cover this query:
select
a.username,
p.creation_date,
p.amount,
c.card_type
from
account a,
payment p,
payment_type t,
payment_card c
where
...
CustomerPurchaseDAO to cover this query:
select
a.username,
i.name,
i.cost,
c.name,
v.value
from
account a,
item i,
category c,
voucher v
where
...
Generally speaking, there are two options:
Create an entity corresponding to each table and specify necessary relationships (many-to-many, many-to-one, one-to-one).
In the database create a view for each query, and create entities on per view basis (in your example - two views + two entities).
The second case is fine for read-only objects. If you need to create/update/delete entities then you need to create an entity corresponding to each single table.
Please help me with these Hibernate querying issues.
Consider the following structure:
#Entity
class Manager {
#OneToMany
List<Project> projects;
}
0) there are 2 possible ways of dynamic fetching in HQL:
select m from Manager m join m.projects
from Manager m join fetch m.projects
In my setup second one always returns a result of cartesian product with wrong number of objects in a list, while the first one always returns correct number of entities in a list. But the sql queries look the same. Does this mean that "select" clause removes redundant objects from the list in-memory? In this case its strange to see an advice in a book to use select distinct ... to get rid of redundant entities, while "select" does the job. If this is a wrong assumption than why these 2 queries return different results?
If I utilize dynamic fetching by one of the 2 methods above I see a classic n+1 select problem output in my hibernate SQL log. Indeed, FetchMode annotations (subselect or join) do not have power while fetching dynamically. Do I really can't solve the n+1 problem in this particular case?
Looks like Hibernate Criteria API does not support generics. Am I right? Looks like I have to use JPA Criteria API instead?
Is it possible to write HQL query with an entity name parameter inside? For example "from :myEntityParam p where p.id=1" and call setParameter("myEntityParam", MyClass.class) after this. Actually what I want is generic HQL query to replace multiple non-generic dao's by one generic one.
0) I always use a select clause, because it allows telling what you want to select, and is mandatory in JPQL anyway. If you want to select the managers with their projects, use
select distinct m from Manager m left join fetch m.projects
If you don't use the distinct keyword, the list will contain n instances of each manager (n being the number of projects of the manager): Hibernate returns as many elements as there are rows in the result set.
1) If you want to avoid the n + 1 problem, fetch the other association in the same query:
select distinct m from Manager m
left join fetch m.projects
left join fetch m.boss
You may also configure batch fetching to load 10 bosses (for example) at a time when the first boss is accessed. Search for "batch fetching" in the reference doc.
2) The whole Hibernate API is not generified. It's been made on JDK 1.4, before generics. That doesn't mean it isn't useful.
3) No. HQL query parameters are, in the end, prepared statement parameters. You must use String concatenation to do this.