I pass a Map as parameter of the following method:
public List<User> getByParameterOrAll(Map<String, String> paramsMap) {
String email = null;
String emailValue = null;
String phone = null;
String phoneValue = null;
Iterator<Map.Entry<String, String>> entries = paramsMap.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<String, String> entry = entries.next();
if (entry.getKey().equals("email")){
email = entry.getKey();
emailValue = entry.getValue();
} else if (entry.getKey().equals("phone")){
phone = entry.getKey();
phoneValue = entry.getValue();
}
}
List<User> users = em.createQuery("SELECT u FROM User u WHERE u.email=:emailValue AND u.phone=:phoneValue", User.class).
setParameter(emailValue, email).
setParameter(phoneValue, phone).
getResultList();
return users;
}
And I catch for the line "setParameter(emailValue, email)"
java.lang.IllegalArgumentException: Could not locate named parameter [gmail#gmail.com], expecting one of [phoneValue, emailValue]
I attach the screen of my test
You should correct your query in the following way (see the documentation) :
List<User> users = em.createQuery("SELECT u FROM User u WHERE u.email=:emailValue AND u.phone=:phoneValue", User.class).
setParameter("emailValue", email).
setParameter("phoneValue", phone).
getResultList();
Related
I have a query where I retrieve DB values like:
public HashMap<String,String> getStateCapital(String Country) {
HashMap<String,String> c1 = new HashMap<String,String>();
String query = DB query+Country;
try {
Connection db = DriverManager.getConnection(URL,Username,Password);
Statement st = db.createStatement();
ResultSet rs = st.executeQuery(query);
while(rs.next()) {
c1.put("StateName",rs.getString(3));
c1.put("CapitalCity",rs.getString(4));
System.out.println(c1); // First c1 output
}
System.out.println(c1); // Second c1 output
}
}
Here when I print the first c1 I get HashMap<key,value> Output as
{StateName=Karnata, CapitalCity=Bengaluru}
{StateName=Kerala, CapitalCity=Thiruvananthapuram}
{StateName=Telangana, CapitalCity=Hyderabad}
{StateName=TamilNadu, CapitalCity=Chennai}
etc...
But when I print the second c1 I get HashMap<key,value> Output as
{StateName=Karnata, CapitalCity=Bengaluru}
How do I retrieve all the HashMap<key,value> like the first c1 Output outside while loop?
The values are overridden with each iteration, that's why the first println statement correctly prints out the key and value. The Map only contains the last added pair as long as by definition it doesn't allow duplicate keys.
I recommend rather using an object encapsulating the stateName and capitalCity and adding such an object into a List.
public class State {
private final String name;
private final String capitalCity
// all-args constructor and getters
}
List<State> c1 = new ArrayList<>();
...
// in the while-loop
c1.add(new State(rs.getString(3), rs.getString(3)));
Also, it is possible to group the map-values into the List resulting in Map<String, List<String>>.
Map<String, List<String>> c1 = new HashMap<>();
...
// in the while-loop
c1.computeIfAbsent("StateName", k -> new ArrayList<>()).add(rs.getString(3));
c1.computeIfAbsent("CapitalCity", k -> new ArrayList<>()).add(rs.getString(3));
An alternative solution would be using a sort of MultiValueMap (from Spring framework, but feel free to search for other libraries or frameworks if they offer something similar) that is just a wrapper to the structure above: Map<String, List<String>>.
A side note: Always program against interfaces, i.e.:
Map<String, String> map = new HashMap<>(); // :)
HashMap<String, String> map = new HashMap<>(); // :(
Consider that Map is a list of entries. Each entry is composed by a key and a value.
The key inside is unique, then the value is overridden every time you put the same key.
You can resolve to create a class that represents the state.
public class State {
private String stateName;
private String capitalCity;
public State(String stateName, String capitalCity) {
this.stateName = stateName;
this.capitalCity = capitalCity;
}
public String getStateName() {
return stateName;
}
public String getCapitalCity() {
return capitalCity;
}
#Override
public String toString() {
return "State{" +
"stateName='" + stateName + '\'' +
", capitalCity='" + capitalCity + '\'' +
'}';
}
}
And you can fill a list of State in order to avoid overriding.
public HashMap<String, String> getStateCapital(String Country) {
List<State> states = new ArrayList<>();
String query = DB query + Country;
try {
Connection db = DriverManager.getConnection(URL, Username, Password);
Statement st = db.createStatement();
ResultSet rs = st.executeQuery(query);
while (rs.next()) {
states.add(new State(rs.getString(3), rs.getString(3)));
}
System.out.println(states);
}
}
I am working on spring application. I am connecting to database using HibernateDaoSupport class in spring framework.
Below is my java code:
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
//imports..
public class MyTableDAOHibernateImpl extends HibernateDaoSupport implements MyTableDAO{
public String getDBValues() throws DataLayerException {
String value = "";
Map<String, String> map = null;
try {
map = (HashMap<String,String>)getHibernateTemplate()
.find("select mt.fname,mt.lname from MyTable as mt where aid= '29983L"' ");
System.out.println("MAP elements : " + map);
if (map != null && !map.isEmpty()) {
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
value = (String) pair.getValue();
System.out.println("name" + value);
}
}
} catch (final DataAccessException dae) {
throw new DataLayerException(dae);
}
return value;
}
The above code is throwing the below exception:
Encountered serious error building result : java.lang.ClassCastException: java.util.ArrayListjava.lang.ClassCastException: java.util.ArrayList
Please suggest, in my code getHibernateTemplate() is returning a Map<String,String> .As per my requirement i need to store the value returned from database in key,value pair using HashMap. Unable to trace the ClassCastException. Please advice.
getHibernateTemplate().find(...) returns List<?> of objects not Map<K,V>
You have to change to list in your code
List<Object[]> rs = ( List<Object[]> ) getHibernateTemplate().find("select mt.fname,mt.lname from MyTable as mt where aid= '29983L'");
In my Spring Data/JPA query I need to add filtering with many criteria and the user can choose whatever he want.
Is there a way to get working together QueryDSL and JPA 2.1 Entity Graph ? If so, could you please show an example ?
This is some code from my project using JPA Criteria API. Main idea that user can choose any field as filter and in service layer all filters are passed as List<Map<String, Object>>, where String key in map is a name of field and Object value is filter value. Maybe it will be helpfull:
public List<DocumentsShort> findAllByCriteria(Integer firstResult, Integer maxResult, String sort, String condition, List<Map<String, Object>> conditions) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<EntityClass> criteriaQuery = cb.createQuery(EntityClass.class);
Root<EntityClass> root = criteriaQuery.from(EntityClass.class);
Join<EntityClass, AnotherEntityClass> AnotherEntityClassJoin = root.join("fieldOfEntity", JoinType.LEFT);
Predicate predicate = cb.conjunction();
List<Predicate> predicateList = new ArrayList<>();
for (Map<String, Object> map : conditions) {
Predicate tempPredicate = cb.conjunction();
tempPredicate = cb.and(predicate, cb.equal(root.get("deleted"), 0)); // only entities not marked as deleted
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Path pathToField = null;
pathToField = root.get(key);
Object value = entry.getValue();
if (value == null) {
tempPredicate = cb.and(tempPredicate, cb.isNull(pathToField));
} else if (value instanceof String) {
tempPredicate = cb.and(tempPredicate, cb.like(pathToField, "%" + value + "%"));
} else if (value instanceof List) {
tempPredicate = cb.and(tempPredicate, pathToField.in(((List) value)));
} else {
tempPredicate = cb.and(tempPredicate, cb.equal(pathToField, value));
}
}
predicateList.add(tempPredicate);
}
criteriaQuery.where(cb.or(predicateList.toArray(new Predicate[predicateList.size()])));
TypedQuery query = entityManager.createQuery(criteriaQuery);
query.setFirstResult(firstResult != null ? firstResult : 0);
query.setMaxResults(maxResult != null ? maxResult : 500);
return query.getResultList();
}
I am using hibernate spring where I need to generate query on a condition.
DAO.java
public ReturnData updateUserDetails(Users users, String mailID)
{
if(!users.getImageURL().equals(""))
{
Query query = this.sessionFactory.getCurrentSession().createQuery("UPDATE users SET emailID=:email_ID, name=:name, imageURL=:imageURL WHERE emailID=:emailID")
//setString....
}
else
{
Query query = this.sessionFactory.getCurrentSession().createQuery("UPDATE users SET emailID=:email_ID, name=:name WHERE emailID=:emailID")
//setString....
}
}
In the above code, I check if image also has been uploaded or not. On the basis of this condition, I have to dynamically generate query. I have to rewrite the whole code for query+execution 2 times. Is it the good way, or is there any better way to do this?
You can dynamically append the query conditions to the query string if they are not null. After getting the final list of conditions, you can create Hibernate query.
StringBuilder sqlQuery = new StringBuilder();
Map<String,Object> parameters = new HashMap<String,Object>();
boolean isFirstSearchCriterion = true;
sqlQuery.append("UPDATE users");
if(email_ID!= null && !email_ID.trim().equals("")) {
if(isFirstSearchCriterion) {
sqlQuery.append(" set emailID= :email_ID");
} else {
sqlQuery.append(" and emailID= :email_ID");
}
parameters.put("email_ID",email_ID);
isFirstSearchCriterion = false;
}
if(name!= null && !name.trim().equals("")) {
if(isFirstSearchCriterion) {
sqlQuery.append(" set name= :name");
} else {
sqlQuery.append(" and name= :name");
}
parameters.put("name",name);
isFirstSearchCriterion = false;
}
if(imageURL!= null && !imageURL.trim().equals("")) {
if(isFirstSearchCriterion) {
sqlQuery.append(" set imageURL= :imageURL");
} else {
sqlQuery.append(" and imageURL= :imageURL");
}
parameters.put("imageURL",imageURL);
isFirstSearchCriterion = false;
}
Query query = this.sessionFactory.getCurrentSession().createQuery(sqlQuery);
Set<String> parameterSet = parameters.keySet();
for (Iterator<String> it = parameterSet.iterator(); it.hasNext();) {
String parameter = it.next();
query.setParameter(parameter, parameters.get(parameter));
}
You can simply do without checking empty String, if user has image url it will add in column or else empty url will be pass on.
public ReturnData updateUserDetails(Users users, String mailID)
{
Query query = this.sessionFactory.getCurrentSession().createQuery("UPDATE users SET emailID=:email_ID, name=:name, imageURL=:imageURL WHERE emailID=:emailID")
query.setParameter("imageURL",users.getImageURL(), Hibernate.STRING);
}
I am having a lot of trouble iterating through all my records. Perhaps, by reading my code someone could help.
private String saveData(Handle handle, String username, String name, String prof, String table) {
String sqlCommand;
Map<String, Object> userResults;
for (Integer tableNum = 1; tableNum < 5; tableNum++) {
//query all tables
sqlCommand = String.format("SELECT varname FROM s" + tableNum.toString());
userResults = handle.createQuery(sqlCommand)
.bind("username", username)
.first();
//attempt to ierate all records
for (Map.Entry<String, Object> entry : userResults.entrySet()) {
Object obj = entry.getValue(); // doesnt have .get(string) as below
}
//get the desired field
logger.debug("Results: " + userResults.toString());
String varname = (String) userResults.get("varname");
if ((varname.toLowerCase()).matches(name.toLowerCase()))
return "";
}
//save data
return name;
}
How do I iterate through each record of the table?
You say this works for row1. You cannot go to the next row as there is .first(); in your handle and you have not tried to fetch next record. Modify your query - the documentation here says you can use .list(maxRows);