How to access JPQL query return value (List) - jpa

This is my method
public void makeDeposit(String WristID, double deposit) {
List resultList = em.createQuery(
"SELECT c FROM Tbleaccountcb005916 c WHERE c.wristid LIKE :wId")
.setParameter("wId", WristID)
.setMaxResults(1)
.getResultList();
int aNo = (int) resultList.get(0);
Tbleaccountcb005916 makeDeposit = em.find(Tbleaccountcb005916.class, aNo);
double balance = makeDeposit.getBalance();
double Mdeposit = balance + deposit;
makeDeposit.setBalance(Mdeposit);
em.persist(makeDeposit);
}
I would like to access resultList value. This image show the resultList values (debugged)
I need to access resultList value (accountno = value = 2) and use it.
I tried this but it's not working:
int aNo = (int) resultList.get(0);

The query you've used returns a list of Tbleaccountcb005916 since you're returning cin the query statement.
List resultList = em.createQuery(
"SELECT c FROM Tbleaccountcb005916 c WHERE c.wristid LIKE :wId")
.setParameter("wId", WristID)
.setMaxResults(1)
.getResultList();
You can return c.accountno instead or cast the resultList items to Tbleaccountcb005916and access it's value.

Thanks to #Samuel Kok I found an answer for this. I just change the query to "c.accountno"
#Override
public void makeDeposit(String WristID, double deposit) {
List resultList;
resultList = em.createQuery(
"SELECT c.accountno FROM Tbleaccountcb005916 c WHERE c.wristid LIKE :wId")
.setParameter("wId", WristID)
.setMaxResults(1)
.getResultList();
int aNo = (int) resultList.get(0);
Tbleaccountcb005916 makeDeposit = em.find(Tbleaccountcb005916.class, aNo);
double balance = makeDeposit.getBalance();
double Mdeposit = balance + deposit;
makeDeposit.setBalance(Mdeposit);
em.persist(makeDeposit);
}
Screen Shot of debugger
enter image description here

Related

How to write Criteria Query Builder for select all from List?

I need a query which will return only results which are having all values from the list.
Something like:
SELECT *
FROM ads_tags
WHERE tag_value("a", "b", "c");
I know that query is not good, but the point is that I want to filter ads but only ads which are having all tags from the list.
With my code, I am getting all ads that have at least one tag from the list. That is because I am using IN interface.
#Override
public List<AdsDTO> findAll(AdsSubGroup adssubgroup, Long userId, String status, String adsType,
String businessType, Long adsGroupId, String region, Integer fromPrice,
Integer toPrice, Boolean fixedPrice, Boolean freeDelivery, Boolean productWarranty,
Boolean urgentSales, Boolean hasImage, Integer pageNumber, Integer pageSize, List<String> tags) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Ads> query = builder.createQuery(Ads.class);
Root<Ads> ads = query.from(Ads.class);
// query.orderBy(builder.desc(ads.get("adsDate")));
List<Predicate> predicates = new ArrayList<>();
Join<Ads, JwtUser> adsUsersJoin = ads.join("users");
Join<Ads, AdsSubGroup> adsAdsSubGroupJoin = ads.join("adssubgroup");
Join<Ads, Tag> tagsJoin = ads.join("adsTags");
In<List<String>> in = builder.in(tagsJoin.get("name"));
if (tags != null && tags.size() > 0) {
// in.value(tags);
tags.forEach(tag - > in.value(tags));
/*
* for (String tag : tags) { in.value(tag);
*
* }
*/
predicates.add(in);
}
query.select(ads);
query.distinct(true);
query.where(predicates.toArray(new Predicate[0]));
if (!(pageNumber == null && pageSize == null)) {
TypedQuery<Ads> typedQuery = em.createQuery(query);
typedQuery.setFirstResult((pageNumber - 1) * pageSize);
typedQuery.setMaxResults(pageSize);
List<Ads> adsList = typedQuery.getResultList();
return AdsConverter.convertToAdsDTO(adsList);
} else {
List<Ads> adsList = em.createQuery(query).getResultList();
return AdsConverter.convertToAdsDTO(adsList);
}
}
What I need to write instead of In interface to get all ads which have ALL tags from the list, not at least one?
You need a join for each element of type Tag in your list.
It's hard to fix your code because it's not a minimal example, however the following should help:
CriteriaQuery<Ads> query = builder.createQuery(Ads.class);
Root<Ads> ads = query.from(Ads.class);
List<Predicate> predicates = new ArrayList<>();
for (String tag : tags) {
Join<Ads, Tag> tagsJoin = ads.join("adsTags");
predicates.add(builder.equal(tagsJoin.get("name"), tag));
}

How to add a boolean array to boolean list?

I'm trying to do this:
NewRoomate(int studentID, List<Integer> rankedQuestions, boolean...trueFalseQuestions){
this.studentID = studentID;
this.rankedQuestions = rankedQuestions;
List<Boolean> wef = Arrays.asList(trueFalseQuestions);
}
But the compiler doesn't like it.
Problems:
How can I convert all of the booleans in the trueFalseQuestions array to a List?
Change boolean...trueFalseQuestions to Boolean...trueFalseQuestions
Result will be:
NewRoomate(int studentID, List<Integer> rankedQuestions, Boolean...trueFalseQuestions){
this.studentID = studentID;
this.rankedQuestions = rankedQuestions;
List<Boolean> wef = Arrays.asList(trueFalseQuestions);
}
NewRoomate(int studentID, List<Integer> rankedQuestions, Boolean...trueFalseQuestions){
this.studentID = studentID;
this.rankedQuestions = rankedQuestions;
List<Boolean> wef = Arrays.asList(trueFalseQuestions);
}
Just make it to Boolean from boolean.
NewRoomate(int studentID, List<Integer> rankedQuestions, boolean...trueFalseQuestions){
this.studentID = studentID;
this.rankedQuestions = rankedQuestions;
List<Boolean> wef = new ArrayList<Boolean>(); //initiate your list
for(boolean question : trueFalseQuestions){ //fill your list with questions
wef.add(question);
}
}

Create querydsl predicate from map

I need help creating a predicate to use with Spring data and querydsl. I'm in the process of converting Daos to Repositorys. And I came across one that has a dynamic query in it. I can create a predicate from a list, but I'm lost at how to create a a dynamic predicate from a map. Here is the code from the DaoImpl that I'm converting from:
public Set<String> getDocumentsByDocumentAssociation(Map.Entry<String,String>[] associations) {
String queryStr = "SELECT da FROM DocumentExternalAssocEntity as da WHERE";
StringBuilder sb = new StringBuilder(queryStr);
//loop through inputs. for first loop, skip appending the OR statements. Append OR for all others
for ( int i = 0; i < associations.length; i++ ){
if ( i > 0 ) {
sb.append(" OR");
}
String whereString = " (da.associationtype = :docAssocType" + i + " AND da.associationvalue = :docAssocValue" + i + ")";
sb.append(whereString);
}
//query when previous loop is done appending
final Query query = em.createQuery(sb.toString());
for( int i = 0; i < associations.length; i++ ) {
query.setParameter("docAssocType" + i, associations[i].getKey());
query.setParameter("docAssocValue" + i, associations[i].getValue());
}
And here is the relevant generated class:
private static final long serialVersionUID = 1971644089L;
public static final QDocumentExternalAssocEntity documentExternalAssocEntity = new QDocumentExternalAssocEntity("documentExternalAssocEntity");
public final StringPath associationtype = createString("associationtype");
public final StringPath associationvalue = createString("associationvalue");
Thanks, and let me know if you need any additional info
This should do it:
BooleanExpression expr = null;
for ( int i = 0; i < associations.length; i++ ){
BooleanExpression innerExpr =
documentExternalAssocEntity.associationtype.eq(associations[i].getKey())
.and(documentExternalAssocEntity.associationvalue.eq(associations[i].getValue()))
if (expr == null) {
expr = innerExpr;
} else {
expr = expr.or(innerExpr);
}
}

return a boolean - jdbcTemplate

I would like to return a boolean value using in this method:
public Boolean isSizeOk(String transactionId){
String sqlQuery = "SELECT true FROM customer_pool WHERE id = "+ transactionID + " AND level = 13)";
//The next line is the problem.
//If I am returning a Boolean List, I can write
List <Boolean> sizeResult = jdbcTemplate.queryForList(sqlQuery, Boolean.class, transactionId);
//But since I only want a boolean value, what will the statement be?
Boolean sizeResult = jdbcTemplate......?
return sizeResult;
}
Kindly help. Thanks.
If you want to write a method that checks that a record exists in the database you can use the following code:
Integer cnt = jdbcTemplate.queryForObject(
"SELECT count(*) FROM customer_pool WHERE id = ? AND level = 13)", Integer.class, id);
return cnt != null && cnt > 0
Counting rows in SQL just in order to get simple information about non-emptiness of result may be unnecessary overkill, you want just ask result set for first row and finish. For simple queries by primary key or other index the performance might be similar, however, for complex queries, or full table scan queries it might be slow. In Spring I prefer simple utility method
public boolean exists(String sql, Object... args) {
boolean result = query(sql, args, new ResultSetExtractor<Boolean>() {
#Override
public Boolean extractData(ResultSet rs) throws SQLException,DataAccessException {
boolean result = rs.next();
return result;
}
});
return result;
}
(Google "sql exists vs count" for more info.)
What about
// Change query accordingly
String query = "SELECT 1 FROM " + tableName + " WHERE " + idColumnName + " = ? LIMIT 1";
try {
jdbcTemplate.queryForObject(query, new Object[]{id}, Long.class);
return true;
} catch (EmptyResultDataAccessException e) {
return false;
}
Case 1: In case you are returning boolean:
Just check the size of sizeResult List, if the size is greater than 0 return true else return false.
Case 2: If you are returning boolean list then return type must be a boolean List.You must
write the method as:
public List<Boolean> isSizeOk(String transactionId, int sizeLimit){
String sqlQuery = "SELECT true FROM customer_pool WHERE id = ? AND level = 13)";
List <Boolean> sizeResult = jdbcTemplate.queryForList(sqlQuery, Boolean.class, transactionId);
Boolean sizeResult = jdbcTemplate......?
return sizeResult;
}

Android SQLite cannot bind argument

I'm trying to do a simple query of my database, where a unique Identification number is stored for a PendingIntent. To allow me to cancel a notification set by AlarmManager if needed.
The insertion of a value works fine, but I am unable to overcome the error:
java.lang.IllegalArgumentException: Cannot bind argument at index 1 because the index is out of range. The statement has 0 parameters.
Database structure:
public class DBAdapter {
private static final String TAG = "DBAdapter";
public static final String KEY_ROWID = "_id";
public static final String TASK = "task";
public static final String NOTIFICATION = "notification";
public static final int COL_ROWID = 0;
public static final int COL_TASK = 1;
public static final int COL_NOTIFICATION = 2;
public static final String[] ALL_KEYS = new String[] {KEY_ROWID, TASK, NOTIFICATION};
// DB info: it's name, and the table.
public static final String DATABASE_NAME = "TaskDB";
public static final String DATABASE_TABLE = "CurrentTasks";
public static final int DATABASE_VERSION = 3;
private static final String DATABASE_CREATE_SQL =
"create table " + DATABASE_TABLE
+ " (" + KEY_ROWID + " integer primary key, "
+ TASK + " text not null, "
+ NOTIFICATION + " integer"
+ ");";
Now I have created a method to extract the notification ID from the database as needed, using the following code:
public int getNotifID(long notifID){
String[] x = {ALL_KEYS[2]};
String[]args = new String[]{NOTIFICATION};
String where = NOTIFICATION + "=" + notifID;
int y = 0;
//String select = "SELECT "+NOTIFICATION+" FROM "+DATABASE_TABLE+" WHERE "+notifID+"="+NOTIFICATION;
//Cursor c = db.rawQuery(select,new String[]{});
Cursor c = db.query(true,DATABASE_TABLE,x,Long.toString(notifID),args,null,null,null,null,null);
if (c!= null && c.moveToFirst()){
y = c.getInt(COL_NOTIFICATION);
}
return y;
}
As you can see I have attempted to do this both with a rawQuery and a regular query, but with no success.
Rewrite your raw query to:
String select = "SELECT "+NOTIFICATION+" FROM "+DATABASE_TABLE+" WHERE "+NOTIFICATION+"=?";
Cursor c = db.rawQuery(select,new String[]{""+notifId});
if(c!=null && c.getCount()>0) {
c.moveToFirst();
}
c.close();