VO and DAO, How to design classes and execute query - java

I have a 3 tables:
Item: item_id (pk), short_description, ...
SupplierItem: item_id (fk), supplier_id (fk), vendor_product_number, ...
Supplier: item_supplier (pk), name, ...
Relation between Item and Supplier is many to many. SupplierItem is
intermediate table.
I want use VO and DAO.
How to design this in VO (Java)?
After, How can I do the following query in java code.
select i.item_id, i.short_description, s.vendor_product_number as FONUA_PRODUCT_CODE
from item i
left join supplier_item s
on i.item_id=s.item_id
where ((i.item_id=:item_id) OR :item_id IS NULL)
and i.parent_item_id is null
order by vendor_product_number DESC"
I still do not understand the concept in use VO and DAO.
Thanks

DAO would be the java file where you define your query and get the results of the query call on the database.
The results from the query will be saved by setting them as values to the properties of a particular VO.
For Example:
Your query returns ,
item_id, short_description, vendor_product_number
So let us say that you will have to create another java file say ItemVO.java and declare the particular properties of the ItemVO object,
For Ex:
private String itemId;
private String shortDescription;
private String vendorShortNum;
/*Define your getters and setters*/
In the DAO file you will have to map the query results to the VO file's objects.
ItemVO itemVO= new ItemVO();
itemVO.setItemId(/*the particular column value from the query result*/);
itemVO.setShortDescription(/*the particular column value from the query result*/);
itemVO.setVendorShortNum(/*the particular column value from the query result*/);

Related

Spring Boot JPA Query with Multiple column Condition and IN clause with combination of two columns

I have a Employee class and DB Table- Employee(Empid,Empname,EmpSalary,EmpJoiningDate)
Another class EmpData(Empid,EmpJoiningDate)
I have list , List<EmpData> empdata = new ArrayList();
Need to fetch all records from employee table with this combination using the empdata list,
This query I need to run for all combinations from List using JPA
For single combination below query works fine.
#query(value="select * from employee where empid=:empid and empJoiningDate=:empJoiningDate")
List<Employee> fetchEmpData(#param("empid") String empid,#param("empJoiningDate") String empJoiningDate)
instead of firing a separate query for each (empid, empJoiningDate ) combination, i need to fire a single query for all (empid, empJoiningDate ) combinations present in list . Is there any way to do this ?
Help me to revise the above query to run on the list.
If I assume Empid as primary key then why are you going for query. You already have your result set in your parameters.
So Your question is unclear. Relations are not defined.
I assume that you need to only two fields from DB to map into your EmpData Class and Empid and EmpJoiningDate has ManyToMany relation.
then use
#query(value="select Empid, EmpJoiningDate from employee where empid=:empid
and empJoiningDate=:empJoiningDate", nativeQuery = true)
List<EmpData> fetchEmpData(#param("empid") String
empid,#param("empJoiningDate") String empJoiningDate)

Spring JPA Criteria Builder specific columns

I'm using JPA criteria builder to query Database for the records. However, I want to return specific columns from a table using JPA criteria API.
Currently, my implementation returns full object. But, I want to return only specific columns and those columns could be dynamic. Below code will query on Person table and returns Full-Object of Person.
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> query = cb.createQuery(Person.class);
Root<Person> root = query.from(Person.class);
query.select(cb.equal(root.get("id"), 1));
TypedQuery<Person> result = em.createQuery(query);
List<Person> personList = result.getResultList();
I know we can create a minified class like PersonMini which will include only a specific field like below but, In my case, the columns could be dynamic and based on the user's preference.
class PersonMini {
private long id;
private String name;
// .. constructor and getter/setter
}
It's not feasible to create a separate mini-classes of Person. Has anyone solved such issue before or could you please suggest another approach if that would solve my problem.
EDIT:
As mentioned in here.
If the type of the criteria query is CriteriaQuery for some user-defined class X (i.e., a criteria query object created by passing a X class argument to the createQuery method), the elements of the list passed to the multiselect method will be passed to the X constructor and an instance of type X will be returned for each row.
If I use multiselect method and use PersonMini Class then I will need a constructor for each and every combination of the fields. Because the selection of the fields is done by Users. selection of fields is not static.
Suppose, in PersonMini class I have 3 fields. Id, Name, and City then User could choose Id and Name, Name and City, City(alone), Id(alone), Id and City. For each combination I need constructor otherwise it will throw error runtime.
For two-three field, it is feasible to have a different combination of constructor but for 15-20 field it is not.

Is it possible to add native query in hibernate for using as entity select?

When a class annotated with #Entity annotaion hibernate uses queries like SELECT * FROM class_name. But for some reason it is needed to run custom select query for class. Is there a way to provide such query?
Yes, according to the official hibernate reference, you can do it like:
sess.createSQLQuery("SELECT * FROM CATS").addEntity(Cat.class);
or:
sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").addEntity(Cat.class);
Criteria cr = getCurrentSession().createCritiera(class_name.class)
.setProjection(Projections.projectionList()
.add(Projections.property("id"), "id")
.add(Projections.property("name"), "name"))
.setResultTransformer(Transformers.aliasToBean(class_name.class));
List<class_name> list = cr.list();
Act as select id,name from class_name this will return List of class_name containing objects only have id and name and the rest of variables in class_name will be null (as you only selected id and name)
I would recommend you getHibernatTemplate() from HibernateDaoSupport. Afterwards you can call find("from Class where....") and you get back an object which you can cast to your java class easily.
i.e.
List < User > users = (List < User > )getHibernateTemplate("from User");

EJB - How to search by non-indexed fields?

I'm trying to create "search engine" on my DB.
I have a table with Id, Name and Description.
When I have an Id I can get the record with this Id by find().
But if I want to get records by Name or Description how can I do that? Did I've to set the Name as index?
Thanks.
As a general rule, if you have to frequently query a table by one of its fields and the table contains many records, it might be a good idea to create an index for that field in the database.
About the other question: if you need to get records by name, by description or by some other field and you're using JPA, then use the JPQL query language. For example, assuming that the entity is of type MyEntity (with fields id, name, description) the following query will return a list of entities with name aName:
EntityManager em = ... // get the entity manager
Query q = em.createQuery("SELECT me FROM MyEntity me WHERE me.name = :name");
q.setParameter("name", aName); // aName is the name you're looking for
List<MyEntity> results = (List<MyEntity>) q.getResultList();
Read more about the Java Persistence API in the tutorial.

How to selectively fetch items from a certain table via JPA

Environment: JPA 1, Hibernate 3.3.x
I have an JPA entity class (User), how do I selectively fetch member variables say (first_name, last_name) instead of fetching all user attributes using the JPA api.
Do you mean something like this (and in that case, the result of your query will be an Object[]):
SELECT u.firstName, u.lastName FROM User u
Alternatively, you could use a constructor expression in the SELECT clause:
SELECT NEW com.acme.example.UserDetails(u.firstName, u.lastName) FROM User u
The class used in the NEW is not necessarily an Entity, it just has to provide a proper constructor.
If you query for more columns you'll get an object result which you'll have to cast to an object array to retrieve values. Better is to create a viewObject class in which you directly store the results:
select new full.package.name.UserView(u.firstName, u.LastName) from User u
where UserView looks like:
class UserView {
String firstName, String lastName;
// getters, setters/constuctor
}

Categories