Mapping multiple hibernate Entities inside non-entity java bean - java

Hi I am using a spring boot app with Hibernate using Oracle as DB.
I have 5 classes named
1.Reqest -> Mapped with Request Table
2.Team -> Mapped with Team Table
3.Partner -Mapped with Partner Table
4.Customer -> Mapped with Customer Table
Now I want to Display a Summary of Request on summary screen of the app where all the information from above-mentioned tables is needed.
Suppose I create a bean class as follows.
public class SummaryBean{
Request req;
Team team;
Customer cust;
Partner part;
//Getter setters;
}
Now since I have all the tables mapped with Java classes I can use hql join query to fetch data.
I don't want use plain SQL query with join and then iterate the resulting Object[] list from hibernate query and stub data into SummaryBean manually.
All the above-mentioned tables have REQ_ID as joining column
My question is How can I make hibernate map the result of that query to SummaryBean object?
Is it possible at all?

You can use constructor query.
Something like
"select new SummaryBean(req, team, cust, part) from (here you join your tables)"
You need to provide a constructor for the SummaryBean with those 4 types.
Note that the SummaryBean class doesn't have to be mapped, but you might have to use fully qualified name in the query (packageName.className).

Related

QueryDSL, specify projection for join

I'm trying to use QueryDSL to fetch a collection of entities (table Category) where each entity has a #OneToMany association with an other type of entity (table User), and a join is used to get it all in one go.
Problem is that the second entity (the users) contains CLOB fields which should not be included. I don't want to include them in my query. Given the following QueryDSL query :
JPAQuery<CategoryEntity> baseQuery = new JPAQuery<>(entityManager)
.select(QCategoryEntity.categoryEntity)
.from(QCategoryEntity.categoryEntity)
.leftJoin(QCategoryEntity.categoryEntity.users, QUserEntity.userEntity)
.where(somePredicate);
QueryDSL will generate something like
SELECT categoryen0_.id, (...), useren0_.id, (...)
FROM category categoryen0
LEFT OUTER JOIN user useren0 ON ...
WHERE ...
How can a specific projection be applied to this query such that the CLOB data is excluded?
Notes :
I'm trying to avoid native queries and changing the domain model.
I have not found a way to use Projections on the join
itself.
Using subqueries inside joins is not supported by JPQL hence
it's not supported by QueryDSL either.
Turns out this was not working well due to my use of fetch joins, which prevented me from using projections. Solving it was a matter of using a basic join instead and manually reconstructing the relationship.
Collection<Tuple> tuples = new JPAQuery<>(entityManager)
.select(QCategoryEntity.categoryEntity, Projections.constructor(UserEntity.class, <constructor arguments>)
.from(QCategoryEntity.categoryEntity)
.join(QCategoryEntity.categoryEntity.users, QUserEntity.userEntity)
.where(somePredicate);

spring data JPA: How to execute aggregate functions

I am using Spring Data JPA and I have a requirement where I need to execute the SQL query as below:
select key_1, sum(key_2), sum(key_3) from table_1
where key_1 in ('1', '2') and {dynamic_columns} group by key_1;
For dynamic columns, I am using Spring Data JPA Specifications but I am not sure how can I write the aggregate functions like sum() on multiple columns.
With Spring Data JPA you have a few options in a spring repository.
References:
Baeldung - Spring data JPA
Spring.io - Spring data JPA
Specify a native query
#Query(value="select key_1, sum(key_2) ...", nativeQuery=true)
Optional<Object[]> getAggregates;
Use the providers (HQL for hibernate etc. query language)
#Query(value="select e.key_1, sum(e.key_2) from entity e ...")
Optional<Object[]> getAggregates;
You'll use objects here because you are not returning a specific entity you are adding custom (aggregate) columns. If you were returning a specific entity with a JPA repository you could return that entity instead of Object[]. Each item inside the object array will correspond to a columnof data, if you had multiple rows here you would use:
Optional<List<Object[]>> getAggregates;
Finally, if you have not used optionals before you will get your object array by:
if(objectsOptional.isPresent()) {
Objects[] objects = objectsOptional.get();
...
}
If this isn't what you were looking for i'll need more information to help you out.

Get data through Hibernate without Entity classes

We use Hibernate and annotations to map our db and entities. But for some data tables I don't want entity classes (Because these table names and all are keep changing) so that the application will be more dynamic
So is it possible using hibernate to load data from a table without a entity class?
If so how?
Hibernate provides a way to execute SQL query and to map it to an entity or any class : native sql queries.
Use plain JDBC. I'm not sure what you mean by "table names and all are keep changing" but it sounds like a bad idea to me.
What you could do is create the sql query using string concatenation then use plain JDBC to execute it. That way you can keep table names dynamic.
If Persistence class won't be used, then the data encapsulation won't occur thus data can be accessed directly.
Hibernate Queries interact with the POJO class to fetch data.
Query, Criteria, HQL all the classes use the POJO for fetching data.
Hibernate Framework was mainly designed for the ORM Mapping.
Thus without POJO class, not possible to interact with the database.
Thus using JDBC connection would be the option left.
Use Dynamic models introduced in Hibernate 5 version - 5.4.0.Final
Hibernate Dynamic Models
To achieve this you will need HBM files created.
Session s = openSession();
Transaction tx = s.beginTransaction();
Session s = openSession();
// Create a customer
Map david = new HashMap();
david.put("name", "David");
// Create an organization
Map foobar = new HashMap();
foobar.put("name", "Foobar Inc.");
// Link both
david.put("organization", foobar);
// Save both
s.save("Customer", david);
s.save("Organization", foobar);
tx.commit();
s.close();
Here Customer & Organization are table names
Organization is Parent of Customer.
Click on the above link for more details

Will joins work in hibernate if the tables participating in the join are not mapped as entities in hibernate configuration?

Let's suppose, am having two tables in my database and i have to write a join query using two tables. I mapped one of those tables as entity class in my MVC project, but there is no mapping for the other table as entity.
so when i run hql, will that join work?
if it doesn't, and if its necessary to have a mapping, should i specify the constraints (primary/foreign key) between those entities?
My application just reads the data from tables, hence i don't want to waste much time writing entity classes. Is there any easy approach using hibernate?
About your question: HQL only works with mapped entity, but can return not-mapped object with ResultTranformer, but is not your case. You can create minimal definition of unwanted entity with just relationships and property needed by your hql.
Another way to resolve is create the plain SQL query and return only mapped entity with session.createSQLQuery(yourQuerySQL).addEntity(YourMappedEntity.class).
Hibernate only knows what is there in session factory. If you have not defined some entity Hibernate would never know about is, so there is no question about writting hql involving that entity.
Alternatively you can get a connection from the session and then execute custom sql rather than hql.
To use plain sql you can use something like:
getSession().doWork(new Work() {
#Override
public void execute(Connection connection) throws SQLException {
// TODO Auto-generated method stub
}
})

How Can I Query a DB for ResultSet which is not Mapped into an Entity(JPA, JBoss)

I'm running an application in JBoss and Using JPA.
For a report I need a group by query which I expect to return a result set with the following structure example:
count,idA,idB
I did not find a way to implement this in JPA.
What are my best options for implementing this considering I'm developing in JBoss 5, EJB3
You can use a custom holder class and use the NEW keyword in your query:
SELECT NEW com.mycompany.myapp.MyClass(count, idA, idB)
FROM ...
WHERE ...
Of course, MyClass needs to have the proper constructor defined.
In the case of Native queries, you can create a dummy entity into which the result set can be mapped to (Native query will not be mapped into an Object unless its a real managed entity).
The entity is a dummy as it will not be persisted and it only used for mapping the result set of the native query into this entity.

Categories