Properly use of BeanListHandler when join tables - java

I'm using DBUtils in my simple project. I have Item and Person entity class (persons and items as tables in database). This simplified the class to better show what I mean. Now i need to get list of items with login names using BeanListHandler. To do this i added login property to Item, but this is ugly solution. Is something better to do that and use advantages of BeanListHandler?
public class Person {
private Long id;
private String login;
}
public class Item {
private Long id;
private String name;
// ... a lot more properties of item
private Long personId; // this is real column in "items" table
private String login; // UGLY (login is not in "items" table, only for BeanListHandler)
}
QueryRunner q = new QueryRunner(getDataSource());
String sql = "select i.*, p.login from items i, persons p where p.id = i.personId";
List<Item> l = (List<Item>) q.query(sql, new BeanListHandler<Item>(Item.class));

Related

Spring data extracting rows with list of composite primary key

I am trying to extract data using composite key of other table, but here problem is, I have list of composite key. Below are the table.
#Embeddable
public class IdRangePk implements Serializable {
#Column("START_RANGE")
private String startRange;
#Column("END_RANGE")
private String endRange;
// default constructor
}
#Entity
#Table(name = "ID_RANGE")
public class IdRange {
#EmbeddedId
private IdRangePk idRangePk;
#Column(name = "PARTY_ID")
private String partyId;
#Column("STATUS")
private String status; // expired or active
// constructors, other fields, getters and setters
}
Here, ID_RANGE have composite primary key (START_RANGE, END_RANGE). So same PARTY_ID can have multiple combination of start & end range.
STATUS can be either "EXPIRED" or "ACTIVE".
#Entity
#Table(name = "MESSAGE")
public class Message {
#Id
#Column("MESSAGE_Id")
private String id;
#Column(name = "PARTY_ID")
private String partyId;
#Column("START_RANGE")
private String startRange;
#Column("END_RANGE")
private String endRange;
// default constructor
// constructors, other fields, getters and setters
}
Here, I need to extract the messages having active ranges for a given PARTY_ID. Also MESSAGE_ID is the primary key.
So I divided it into two steps
Extracting active ranges for given party id
#Repository
public interface IdRangeRepo extends JpaRepository<IdRange, IdRangePk> {
List<IdRange> findByPartyIdAndStatus(String partyId, String status);
}
List<IdRange> idRanges = findByPartyIdAndStatus("123", "ACTIVE");
Extracting message from list of active IdRange
List<String> startRange = new ArrayList<>();
List<String> endRange = new ArrayList<>();
idRanges.stream().forEach(range -> {
startRange.add(range.getStartRange());
endRange.add(range.getEndRange())
});
List<Message> activeRangeMessage = findByPartyIdAndStartRangeInAndEndRangeIn("123", startRange, endRange);
#Repository
public interface MessageRepo extends JpaRepository<Message, String> {
List<IdRange> findByPartyIdAndStartRangeInAndEndRangeIn(String partyId, List<String> startRange, List<String> endRange);
}
My second step query is not right, it is extracting more rows than the expected as query is counter by individually field instead of whole (for startRange & endRange which is a composite key). Can someone please help me correct my query or provide an easiest way to extract rows. I have used derived method but #Query will also do.

I am having trouble with a Predicate in JPA in inherited code

I have some inherited code that is using JPA and is supposed to return a list of all processes that include all listed chemicals - an AND operation. However, the list is always empty. The code that returns the processes that have any of the listed chemicals (OR) seems to be OK. JDK version is 1.7. Hibernate 5.0.2
I have tried looking at the Javadocs, tutorials on JPA and hibernate, etc. But none give me a good feel for the Predicate class.
final CriteriaBuilder cb = getCriteriaBuilder();
final CriteriaQuery<Process> cq = cb.createQuery(Process.class);
final Root<Constituent> constituentRoot = cq.from(Constituent.class);
List<Predicate> clist - new ArrayList<Predicate>();
//chemical_id_list is a List of type Integer = List<Integer> passed to method.
//It contains all of the ids of the chemicals of interest.
for (Integer id: chemical_id_list) {
clist.add(cb.equal(constituentRoot.get(Constituent_.chemical), id));
}
//Code in common with the OR operation, which works..
It seems to me that the cb.equal part of this code is wrong. Constituent_.chemical is an attribute of the Constituent class, not an integer, which is what the "id" parameter is. How could a chemical object ever be "equal" to an integer? Or am I completely misunderstanding something? Thanks for your time.
Here is what is in the Constituent class:
public class Constituent implements Serializable{
private int constituentId;
private String chemicalNotes;
private String labelText;
private String quantity;
private int sort;
private Chemical chemical;
private Phase phase;
private Role role;
private Step step;
//getters and setters
}
Here is what is in the Chemical class:
public class Chemical
{
private int chemicalId;
private String boilingPoint;
private String canonicalFormula;
private String meltingPoint;
private String name;
private String notes;
//getters and setters
}
Here is what is in the Process class, although I do not show the use of it in the code here:
public class Process
{
private int processId;
private String name;
private String notes;
private List<Step> steps;
//Getters and setters not shown.
}
The problem in this query is that you join the chemical only once. Due to that, you check that the id of that 1 chemical is equal to all the Integer in your List. So, as soon as you List contains more than one Integer, the result set is empty.
You need a separate join for each chemical id that you want to check.
This query should return all Constituent that have all Chemicals identified by the chemical_id_list
final CriteriaBuilder cb = getCriteriaBuilder();
final CriteriaQuery<Process> cq = cb.createQuery(Process.class);
final Root<Constituent> constituentRoot = cq.from(Constituent.class);
List<Predicate> clist - new ArrayList<Predicate>();
//chemical_id_list is a List of type Integer = List<Integer> passed to method.
//It contains all of the ids of the chemicals of interest.
for (Integer id: chemical_id_list) {
Join<Constituent, Chemical> chemical = root.join(Constituent_.chemical);
clist.add(cb.equal(chemical.get(Chemical_.id), id));
}

hibernate query combining 3 tables to get object corresponding to one table

I have 3 tables named role,permission and role_permission and their corresponding pojos
public class RoleTO
{
private int roleId;
private String roleName;
private int applicationId;
}
,
public class RolePermissionsTO
{
private int role_permissionId;
private int roleId;
private int permissionId;
}
,
public class PermissionTO
{
private int permissionId;
private String permission;
private String permissionDesc;
private int applicationId;
}
Now I have a method in my dao class
public List<PermissionTO> getPermissions(int applicationId, String roleName)throws HibernateException
{
Session session = getCurrentSession();
String hql = "SELECT P FROM PermissionTO P,Role R where P.applicationId=R.applicationId and P.applicationId=:applicationId and P.roleName=:roleName";
Query query = session.createQuery(hql);
query.setParameter("applicationId",applicationId);
query.setParameter("roleName",roleName);
return query.list();
}
But I need these three tables to be connected so that I get all the permissions in the permission class for the given application Id and the roleName linking the three tables.
Can anybody help
SELECT P FROM PermissionTO P,Role R
where P.applicationId=R.applicationId
AND R.applicationId=:applicationId
AND R.roleName=:roleName";
OR
Criteria cr = session.createCriteria(PermissionTO.class, "permissionTo");
cr.createAlias("permissionTo.permissionId", "rolePermissionsTo"); // inner join by default
cr.createAlias("rolePermissionsTo.roleId", "roleTo");
cr.add(Restrictions.eq("roleTo.applicationId", applicationId)); // applicationId set value to parameter
cr.add(Restrictions.eq("roleTo.roleName", roleName)); // roleName set value to parameter
List list = cr.list();
I also have a similar issue, but couldnt find a solution.
but in your query I find that you should be using some constraint to connect the RoleTO to RolePermissinTo using RoleId and ApplicationId and then use this result to get the corresponding PermissionTO list for each given role.
I am not expert with queries, i guess this should be the logic

Struts 2 select and Distinct select items

I have a ArrayList which of type empDetail (a POJO class).
List<EmpDetail> empDetailList = new ArrayList<EmpDetail>();
This list represents a table in the database.
I need values for a dropdown list and so I did
<s:select list="empDetailList" listKey="country" listValue="country" name="country"></s:select>
By this I get all rows of country column from database and its good. But I need unique country in this dropdown list.
I know I can write a SQL query to get distinct country, but how to do it in this kind of scenario.
Update 1:
Do any one of you have Hibernate solution for this?
Update 2:
My POJO class as follows...
package bean;
import java.io.Serializable;
import java.sql.Date;
public class EmpDetail implements Serializable{
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private int age;
private String address;
private String city;
private String section;
private String country;
private String classStudying;
private String fatherName;
private String motherNmae;
private Date DOJ;
private String certificates;
private Date CompletedDate;
private String crossCheckedBy;
private Date crossCheckedDate;
private String comments;
//and its getters and setters...
}
You need to group by country objects. Simple HQL query
from EmpDetail where id in (select max(id) from EmpDetail group by country)
If you want to display distinct select items means
EmpDetail empDetail = new EmpDetail();
Map<Object, Object> empDetailMap = new LinkedHashMap<Object, Object>();
if (empDetailList.size() > 0) {
for (Iterator<EmpDetail> iter = industryDetail.iterator(); iter.hasNext();) {
empDetail = (EmpDetail) iter.next();
empDetailMap.put(empDetail.getId(),empDetail.getName());
}
}

Hibernate Criteria for list

Good Day,
I have a Hibernate mapping that looks something like this:
public class Item implements Serializable {
private lond id;
private String Name;
private boolean status;
...
}
public class ItemHolder implements Serializable {
private long id;
private List<Item> items;
...
}
How can I do query to get all Item Holder's witch contains my Item?
(with criteria)
You just need a join:
Criteria c = session.createCriteria(ItemHolder.class, "itemHolder");
c.createAlias("itemHolder.items", "item");
c.add(Restrictions.eq("item.id", theItemId);
Criteria criteria=session.createCriteria(ItemHolder.class);
criteria.createAlias("items", "item");
criteria.add(Restrictions.eq("item.Name", "my Item").ignoreCase());
you can restrict with your requirement : id or name..
The query could be something like:
Item loadedItem = ...;
Query query = session.createQuery("from ItemHolder ih where :item in elements(ih.items)");
query.setParameter("item", loadedItem);
List list = query.list();

Categories

Resources