Hibernate SQL mixes two column values from different tables - java

I am running this query
Query q = session.getCurrentSession()
.createSQLQuery("SELECT alt.*, cpp.*, l.*, u.*, br.*,np.*, afp.*, lmp.* FROM ActiveLoansTable alt " +
"JOIN loan l ON l.loanId=alt.loanId " +
"JOIN custpaymentplan cpp ON cpp.loanId=alt.loanId " +
"JOIN branches br ON br.branchId=l.branch_id " +
"JOIN users u ON u.userId=l.userId " +
"JOIN naturalPerson np ON np.personId=l.customerId " +
"LEFT JOIN additionalfinancialparameters afp on afp.loanId = l.loanId " +
"LEFT JOIN loanmanagementprice lmp on lmp.loanId = l.loanId " +
"WHERE l.status = :statusActive and (alt.isLateInSchedule=1 or alt.isLateOutSchedule=1) ")
.addEntity("alt", ActiveLoanTable.class)
.addEntity("cpp", CustPaymentPlan.class)
.addEntity("l", Loan.class)
.addEntity("u", User.class)
.addEntity("br", Branch.class)
.addEntity("np", NaturalPerson.class)
.addEntity("afp", AdditionalFinancialParameters.class)
.addEntity("lmp", LoanManagementPrice.class);
then I cast results to objects:
for (Object[] row : rows) {
ActiveLoanTable alt = (ActiveLoanTable) row[0];
CustPaymentPlan cpp = (CustPaymentPlan) row[1];
Loan l = (Loan) row[2];
User u = (User) row[3];
Branch br = (Branch) row[4];
NaturalPerson np = (NaturalPerson) row[5];
AdditionalFinancialParameters afp = (AdditionalFinancialParameters) row[6];
LoanManagementPrice lmp = (LoanManagementPrice) row[7];}
where naturalPerson and users both have column firstname and lastname. I want to return both of them but in the end result naturalperson values are overriden by users values. so np.firstname becomes u.firstname

Related

Casting objects from Hibernate native multiple join query

I have a hibernate native sql query joining three tables, and I'm trying to retrive 3 columns from the result
public void doTestQuery() {
try (Session session = HibernateUtilities.getSessionFactory().openSession()) {
transaction = session.beginTransaction();
String sql = "SELECT\r\n"
+ " users.username, \r\n"
+ " user_roles.role_name, \r\n"
+ " address.address\r\n"
+ "FROM\r\n"
+ " address\r\n"
+ " INNER JOIN\r\n"
+ " users\r\n"
+ " ON \r\n"
+ " address.iduser = users.iduser\r\n"
+ " INNER JOIN\r\n"
+ " user_roles\r\n"
+ " ON \r\n"
+ " users.iduser = user_roles.iduser";
NativeQuery query = session.createNativeQuery(sql);
List<Object[]> results = query.list();
for (Object[] arr : results) {
System.out.println(arr[0].toString() +" "+ arr[1].toString() +" "+ arr[2].toString());
}
transaction.commit();
}
If I replace the System.out.println with this code below, it gives me an error. Is there a way to cast objects from this kind of hibernate queries?
Users user = (Users) arr[0];
UserRoles userRole = (UserRoles) arr[1];
Address _address = (Address) arr[2];
System.out.println(user.getUsername() + userRole.getRolename() + _address.getAddress());
Hibernate requires special aliases to be able to fetch the data from a result set. For this purpose, Hibernate supports a special template in native SQL.
String sql = "SELECT "
+ " {u.*},"
+ " {r.*},"
+ " {a.*} "
+ "FROM "
+ " address a "
+ " INNER JOIN "
+ " users u "
+ " ON a.iduser = u.iduser "
+ " INNER JOIN "
+ " user_roles r "
+ " ON u.iduser = r.iduser";
NativeQuery query = session.createNativeQuery(sql);
query.addEntity("u", Users.class);
query.addEntity("r", UserRoles.class);
query.addEntity("a", Address.class);

SQL Query - FindCostumerWithHighestBill

I am try to find the costumer with the highest bill using this sql that I wrote , but apparently I run into this error :
Every derived table must have its own alias
This is what I wrote:
public static void findCustomerWithHighestBill(Connection c) throws SQLException {
String query = "SELECT CustomerID, CustomerName, CITY, sum(sum_all) As 'data'\r\n"
+ "FROM (SELECT *, sum(Price) As 'sum_all'\r\n"
+ " FROM (SELECT *, Customer.NAME AS \"CustomerName\"\r\n"
+ " FROM Transactions\r\n"
+ " INNER JOIN Product ON Product.ID = Transactions.ProductID\r\n"
+ " INNER JOIN Customer ON Customer.ID = Transactions.CustomerID)\r\n"
+ " GROUP BY CustomerID, ProductID\r\n"
+ " ) \r\n"
+ "GROUP BY CustomerID\r\n"
+ "ORDER BY data DESC";
Statement statement = c.createStatement();
ResultSet set = statement.executeQuery(query);
set.next();
System.out.println("CustomerID: " + set.getInt("CustomerID") +
", Name: " + set.getString("CustomerName") + ", City: " +
set.getString("CITY") + ", Bill: " + set.getFloat("data"));
}
Can please somoane help me zith this ?
Coming back ,
It seems that indeed ad most of you says in the comments I should identify my tables first but, apparently I also have miss to avoid the duplicate ID column.
Here goes my new query:
String query = "SELECT CID, CustomerName, City, sum(sum_all) As data" +
" FROM (SELECT *, sum(PPROD) As sum_all" +
" FROM (SELECT Product.ID as PID,Customer.ID as CID,Product.Price as PPROD,City, Customer.NAME AS CustomerName" +
" FROM Transactions" +
" INNER JOIN Product ON Product.ID = Transactions.ProductID" +
" INNER JOIN Customer ON Customer.ID = Transactions.CustomerID) As t2" +
" GROUP BY CID, PID" +
" ) As t1" +
" GROUP BY CID" +
" ORDER BY data DESC;";

SQLiteException: near "FROM": syntax error multiple Joins

Can anyone see if there is an error in my query here, it's my first attempt at multiple Joins, below is the logcat error. Thanks in advance
android.database.sqlite.SQLiteException: near "FROM": syntax error
(code 1 SQLITE_ERROR[1]): , while compiling: SELECT SUM(A.quantity),
A.ingredient, A.recipe, B.ingredient_type, B.measurement_name, C.id,
D.plan_name, FROM QUANTITY AS A JOIN INGREDIENTS AS B ON A.ingredient
= B.ingredient_name JOIN PLAN_RECIPES AS C ON A.recipe = C.recipe_name JOIN MEAL_PLAN AS D ON C.id = D.plan_recipe GROUP BY A.ingredient
WHERE D.plan_name LIKE ?
Code
public void loadIngredient() {
shopList.clear();
db = (new DatabaseManager(this).getWritableDatabase());
String RECIPE_SEARCH = " SELECT SUM(A.quantity), A.ingredient, A.recipe, B.ingredient_type, B.measurement_name, C.id, D.plan_name, " +
"FROM " + DatabaseManager.TABLE_QUANTITY + " AS A JOIN " + DatabaseManager.TABLE_INGREDIENTS +
" AS B ON A.ingredient = B.ingredient_name" + " JOIN " + DatabaseManager.TABLE_PLAN_RECIPES + " AS C ON A.recipe = C.recipe_name " +
" JOIN " + DatabaseManager.TABLE_MEAL_PLAN + " AS D ON C.id = D.plan_recipe GROUP BY A.ingredient";
String selectQuery = "";
selectQuery = RECIPE_SEARCH + " WHERE D.plan_name LIKE ?";
c = db.rawQuery(selectQuery, new String[]{"%" + search + "%"});
if (c.moveToFirst()) {
do {
Shopping_List shopping_list = new Shopping_List();
shopping_list.setQuantity(c.getDouble(c.getColumnIndex("quantity")));
shopping_list.setIngredient_name(c.getString(c.getColumnIndex("ingredient_name")));
shopping_list.setIngredient_type(c.getString(c.getColumnIndex("ingredient_type")));
shopping_list.setMeasurement_name(c.getString(c.getColumnIndex("measurement_name")));
shopList.add(shopping_list);
} while (c.moveToNext());
c.close();
}
}
There are several problems in your code.
The 1st is a comma that you must remove after D.plan_name inside the variable RECIPE_SEARCH right before the FROM clause.
The 2nd is the WHERE clause that must precede the GROUP BY clause.
The 3d is that you must alias the column SUM(A.quantity) that is returned by your query so you can retrieve it by that alias, say quantity.
The 4th is that there is no column ingredient_name returned by your query, but I assume this is the column A.ingredient which should be aliased to ingredient_name.
So change to this:
public void loadIngredient() {
shopList.clear();
db = (new DatabaseManager(this).getWritableDatabase());
String RECIPE_SEARCH =
"SELECT SUM(A.quantity) quantity, A.ingredient ingredient_name, A.recipe, B.ingredient_type, B.measurement_name, C.id, D.plan_name " +
"FROM " + DatabaseManager.TABLE_QUANTITY + " AS A JOIN " + DatabaseManager.TABLE_INGREDIENTS + " AS B ON A.ingredient = B.ingredient_name " +
"JOIN " + DatabaseManager.TABLE_PLAN_RECIPES + " AS C ON A.recipe = C.recipe_name " +
"JOIN " + DatabaseManager.TABLE_MEAL_PLAN + " AS D ON C.id = D.plan_recipe " +
"WHERE D.plan_name LIKE ? GROUP BY A.ingredient";
c = db.rawQuery(RECIPE_SEARCH, new String[]{"%" + search + "%"});
if (c.moveToFirst()) {
do {
Shopping_List shopping_list = new Shopping_List();
shopping_list.setQuantity(c.getDouble(c.getColumnIndex("quantity")));
shopping_list.setIngredient_name(c.getString(c.getColumnIndex("ingredient_name")));
shopping_list.setIngredient_type(c.getString(c.getColumnIndex("ingredient_type")));
shopping_list.setMeasurement_name(c.getString(c.getColumnIndex("measurement_name")));
shopList.add(shopping_list);
} while (c.moveToNext());
}
c.close();
db.close();
}
Also, your query returns columns that you don't use in the loop, which I did not remove, by you may remove them.

Subquery on java error

hi guys I tried to make query on java for access data from database but when I compile the error is syntax error at or near "v", when I try to compile my query on postgresql it work and the data can show, but when I compile on eclipse it can't
this the query
#Override
protected StringBuffer buildQuery(String sql, Object... objects) {
StringBuffer sbSQL = new StringBuffer("SELECT a.master_user_id, b.name, d.group_name, a.role, "
+ "(SELECT count (v.id) FROM project_member_dtl v "
+ "LEFT JOIN project_timeline p ON v.project_timeline_id = p.id "
+ "LEFT JOIN master_project_dtl j ON p.master_project_dtl_rid = j.rid "
+ "LEFT JOIN master_project aa ON j.master_project_sid = aa.sid "
+ "where ((v.member_plan_date > now()) AND (v.member_real_date IS NULL)) "
+ "AND j.is_freeze = 'n' "
+ "AND p.is_active = 'y' "
+ "AND aa.is_deleted = 'n' "
+ "AND v.master_user_id = a.master_user_id"
+ "AND v.master_role_id = a.master_role_id ) as in_progress, "
+ "(SELECT count (w.id) FROM project_member_dtl w "
+ "LEFT JOIN project_timeline q ON w.project_timeline_id = q.id "
+ "LEFT JOIN master_project_dtl k ON q.master_project_dtl_rid = k.rid "
+ "LEFT JOIN master_project bb ON k.master_project_sid = bb.sid "
+ "where ((w.member_plan_date < now()) "
+ "AND (w.member_real_date IS NULL)) "
+ "AND k.is_freeze = 'n' "
+ "AND q.is_active = 'y' "
+ "AND bb.is_deleted = 'n' "
+ "AND w.master_user_id = a.master_user_id "
+ "AND w.master_role_id = a.master_role_id ) as in_progress_late, "
+ "(SELECT count (x.id) FROM project_member_dtl x "
+ "LEFT JOIN project_timeline r ON x.project_timeline_id = r.id "
+ "LEFT JOIN master_project_dtl l ON r.master_project_dtl_rid = l.rid "
+ "LEFT JOIN master_project cc ON l.master_project_sid = cc.sid "
+ "where (x.member_plan_date IS NULL) "
+ "AND l.is_freeze = 'n' AND r.is_active = 'y' "
+ "AND cc.is_deleted = 'n' "
+ "AND x.master_user_id = a.master_user_id "
+ "AND x.master_role_id = a.master_role_id ) as waiting_list, "
+ "(SELECT count (y.id) FROM project_member_dtl y"
+ "LEFT JOIN project_timeline s ON y.project_timeline_id = s.id "
+ "LEFT JOIN master_project_dtl m ON s.master_project_dtl_rid = m.rid "
+ "LEFT JOIN master_project dd ON m.master_project_sid = dd.sid "
+ "where (y.member_plan_date > y.member_real_date) "
+ "AND m.is_freeze = 'n' AND s.is_active = 'y' "
+ "AND dd.is_deleted = 'n' "
+ "AND y.master_user_id = a.master_user_id "
+ "AND y.master_role_id = a.master_role_id ) as finish_on_time, "
+ "(SELECT count (z.id) FROM project_member_dtl z "
+ "LEFT JOIN project_timeline t ON z.project_timeline_id = t.id"
+ "LEFT JOIN master_project_dtl n ON t.master_project_dtl_rid = n.rid"
+ "LEFT JOIN master_project ee ON n.master_project_sid = ee.sid"
+ "where (z.member_plan_date < z.member_real_date)"
+ "AND n.is_freeze = 'n' AND t.is_active = 'y'"
+ "AND ee.is_deleted = 'n' "
+ "AND z.master_user_id = a.master_user_id "
+ "AND z.master_role_id = a.master_role_id ) as finish_over_time"
+ "FROM project_member_dtl a");
sbSQL.append("LEFT JOIN master_user b ON a.master_user_id = b.id ");
sbSQL.append("LEFT JOIN user_group c ON a.master_user_id = c.master_user_id ");
sbSQL.append("LEFT JOIN master_group d ON c.group_id = d.id ");
sbSQL.append(sql);
return sbSQL;
}
thanks
It's a typo. Make sure you keep a space at the end of each line
+"AND v.master_user_id = a.master_user_id "
In the first query you missed a space
+"AND v.master_user_id = a.master_user_id"
+ "AND v.master_role_id = a.master_role_id ) as in_progress, "
Now the query would be
...AND v.master_user_id = a.master_user_idAND v.master_role_id =....
SQL engine thinks that a.master_user_idAND is a column. So the next v is a problem. That's why the error
syntax error at or near "v"

JPA Eclipselink NamedQuery vs Query COUNT

Cannot get a Integer back from a NamedQuery???
#NamedQuery( name = Comm.COUNTLIKEVALUEINHOLDER,
query = "SELECT COUNT(c.id) " +
"FROM Comm c " +
"JOIN c.element e " +
"WHERE c.search1 LIKE :search1 " +
"AND c.search2 = :search2 " +
"AND c.type = :type " +
"AND e.holderelement = :holder"
)
Object q = em.createNamedQuery(Comm.COUNTLIKEVALUEINHOLDER)
.setParameter("search1", "bla%")
.setParameter("search2", "bla2")
.setParameter("type", t)
.setParameter("holder", h)
.getSingleResult();
I get a Entity back and not a Long or Integer from COUNT Aggregat.
But here I get a Integer back. It's exactly the same query.
Object i = em.createQuery("SELECT COUNT(c.id) " +
"FROM Comm c " +
"JOIN c.element e " +
"WHERE c.search1 LIKE :search1 " +
"AND c.search2 = :search2 " +
"AND c.type = :type " +
"AND e.holderelement = :holder")
.setParameter("search1", "bla%")
.setParameter("search2", "bla2")
.setParameter("type", t)
.setParameter("holder", h)
.getSingleResult();
Does anybody have an idea?
Short answer:
em.createQuery is used for creation of dynamic queries. Return type is determined by the return type of the QL language ("SELECT COUNT(c.id)" in the example above).
em.createNamedQuery is used for creation of static queries. Return type can be type casted, for example:
Object q = em.createNamedQuery(Comm.COUNTLIKEVALUEINHOLDER)
.setParameter("search1", "bla%")
.setParameter("search2", "bla2")
.setParameter("type", t)
.setParameter("holder", h)
.getSingleResult();
Integer count = (Integer) q;
`
see also:http://www.objectdb.com/java/jpa/query/api

Categories