I have following User table and repository.
User:
id;name;job;age
1;steve;nurse;33
2;steve;programmer;null
3;steve;programmer;null
Repository method:
#Query("SELECT u FROM User u WHERE ("
+ "LOWER(u.name) = LOWER(:name) AND "
+ "LOWER(u.beruf) = LOWER(:job) AND "
+ "LOWER(u.alter) = LOWER(:age))")
public List<User> findUsers(#Param("name") String name,
#Param("job") String job,
#Param("age") String age);
If I call the repository method with following parameters
String name = "steve";
String job = "programmer";
List<User> result = repository.findUsers(name, job, null); // empy list ..why ?
I get an empty list as result, although I expect to get the entities with id=2 and id=3 as result.
What am I doing wrong ? How should I change the query to get the two entities as result.
Thanks
According to the documentation this behaviour is normal there is no way to ignore null fields. using #Query method.
instead you can use the query method specifications.
more information [here][jpa documentaiton]
if you want to keep your existing method you can also go like this:
#Query("SELECT u FROM User u WHERE ("
+ "LOWER(u.name) = LOWER(:name) AND "
+ "LOWER(u.beruf) = LOWER(:job) AND "
+ "( " +
" :age is null or LOWER(u.alter) = LOWER(:age) " +
")"
)
public List<User> findUsers(#Param("name") String name,
#Param("job") String job,
#Param("age") String age);
Related
I want to send a sql query by using Spring JPA like :
"SELECT NEW com.blalba.model.service.FamilyMaterialDto "
+ "(ms.id, mi.partNumber, ftc.commodityType, ftc.materialType, ms.grade, ms.thickness, ms.width) "
+ "FROM MaterialInstance mi, FamilyTypeCommodity ftc, MaterialSpecification ms "
+ "WHERE ftc.materialFamily.id = :familyId "
+ "AND (:typeId is null OR ftc.materialType.id = :typeId) "
+ "AND ftc.id = ms.familyTypeCommodity.id "
+ "AND ms.id = mi.materialSpecification.id "
+ "AND mi.materialSpecification.isActive = true"
However, when I remove some fields like "ms.width", I get the error:
Unable to locate appropriate constructor on class [com.commencis.sova.model.service.FamilyMaterialDto]. Expected arguments are: java.lang.String, java.lang.String, com.commencis.sova.model.entity.material.CommodityType, com.commencis.sova.model.entity.material.MaterialType, com.commencis.sova.model.entity.material.Grade, com.commencis.sova.model.entity.material.Thickness [SELECT NEW com.commencis.sova.model.service.FamilyMaterialDto (ms.id, mi.partNumber, ftc.commodityType, ftc.materialType, ms.grade, ms.thickness) FROM com.commencis.sova.model.entity.material.MaterialSpecification ms, com.commencis.sova.model.entity.material.MaterialInstance mi, com.commencis.sova.model.entity.material.FamilyTypeCommodity ftc WHERE ftc.materialFamily.id = :familyId AND (:typeId is null OR ftc.materialType.id = :typeId) AND mi.materialSpecification.isActive = true AND ms.id = mi.materialSpecification.id AND ftc.id = ms.familyTypeCommodity.id]
I understand that return Object[] cannot be parsed to DTO object. If I write constructor without the parameter - "Width", it will work properly. However, I want to provide that a query can be sendable without some parameters(sometimes one of them, sometimes five of them) and a result can be parsable with FamilyMaterialDTO.
How can I do? I don't have to use DTO, if there is another solution for this problem, please recommend.
I think you can make the query to return a map and you can create a constructor for FamilyMaterialDTO which takes the argument as a map. And based on the keys present in the map you can set the values...
For simplicity let me create my own class.
Class foo { String a; Integer b; Boolean c;}
And a sample query
"select new map (a as a, b as b) from Foo f"
Now this query will return a list of maps and the size of the list depends on how many rows the query returns.
Now you can create a constructor like this. Assume the size of list is 1.
foo (List<Map<?,?> list) {
Map map = list.get(0);
If(map.containsKey("a")) this.a = map.get("a");
If(map.containsKey("b")) this.b = map.get("b");
If(map.containsKey("c")) this.c = map.get("c"); }
I am trying to write a generic method to call DB records.
All works except to make the method useful I need to passing the WHERE name value too...as well as the value to match.
Something like this...
T values = db.SingleOrDefault<T>("WHERE " + name + " = #0", value);
This works but its a bit of a clunk!
string sql = "WHERE " + name + " = #0";
T values = db.SingleOrDefault<T>(sql, value);
Can this be done with different syntax?
Thanks
You can create an extension method to hide the syntax if that bothers you
public static T SingleOrDefaultWithWhere<T>(this PetaPoco.Database db, string name, object value) {
string sql = "WHERE " + name + " = #0";
return db.SingleOrDefault<T>(sql, value);
}
And then just call
T values = db.SingleOrDefaultWithWhere<T>(name, value);
I'm trying to search the max ID in the database, then increment it by 1 for each new entry as shown below:
var query2 = dbb.Database.SqlQuery<patient_visit>("SELECT MAX(CAST(SUBSTRING(pvid, 3, 10) AS int)) FROM patient_visit");
if (query2 != null)
{
objDetails.pvid = query2.ToString();
objDetails.pvid += 1;
objDetails.pvid = "PV" + objDetails.pvid;
}
string sql = "INSERT INTO patient_visit (pvid,paid) " +
"VALUES('" + objDetails.pvid + "', '" + paid + "')";
But when i try to insert it in the database, it gives out error
An exception of type 'System.Data.SqlClient.SqlException' occurred in EntityFramework.SqlServer.dll but was not handled in user code
Additional information: String or binary data would be truncated.
I've tried running the query in SQL Server and checked the value of 'pvid', it is 10 so after i include 'PV' to the integer pvid, it should be 12. So it should be fine, but why did i get that error? Please can anyone help me?
[Key]
[MaxLength(20), MinLength(12)]
public string pvid { get; set; }
When i replace the pvid with hard code ID, it works just fine. Why is this happening?
P/S: I know its not advisable to simply concatenate the input data with the query, but i've also tried querying using parameterized query but it gives same error.
string sql = "INSERT INTO patient_visit (pvid,paid) " +
"VALUES(#pvid, #paid)";
List<SqlParameter> parameterList = new List<SqlParameter>();
parameterList.Add(new SqlParameter("#pvid", objDetails.pvid));
parameterList.Add(new SqlParameter("#paid", paid));
SqlParameter[] parameters = parameterList.ToArray();
dbb.Database.ExecuteSqlCommand(sql, parameters);
Check the Field length of the column you are trying to put the data into.
I have had this problem before where the column was varchar(10) and I was trying to concatenate two char strings of 6 characters each. Making them 12 characters long. 2 longer than the target field.
Your problem might be similar.
I've gone through various forums to handle the IN clause using spring's namedParamJdbcTemplate but i still do not get the stuff I'm exactly looking for.
Below is my issue:
I've the following method:
public void updateBatchTableForStatus(List<Integer> reportShellIds, String scheduleType) {
Map<String,List<Integer>> shellIds = Collections.singletonMap("reportShellIds", reportShellIds);
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("reportShellIds", shellIds, Types.NUMERIC)
parameters.addValue("eventType", scheduleType, Types.VARCHAR);
this.namedParamJdbcTemplate.update(GET_EVENT_METADATA_INFO, parameters);
}
The query refered in above method is as defined below:
public static final String SQL_UPDATE_BATCH_LOOKUP_TABLE_FOR_STATUS_BY_BATCH_IDS = "" +
"UPDATE " +
TABLE_BATCH_REF + " BLK " +
"SET " +
"BLK.EXECUTION_STATUS_CODE = :eventType " +
"WHERE " +
"BLK.BATCH_ID in(:reportShellIds) ";
Datatype for BATCH_ID column is Number(24,0) and for the EXECUTION_STATUS_CODE column Varchar.
I'm using Oracle db.
However, the above method throws a SQL exception.
Can someone pls tell me where I'm wrong and what is the fix for it ?
Many thanks in advance.
Best Regards
LB
You are binding reportShellIds to a Map, but it needs to be a List for Spring to bind it correctly. Perhaps you meant shellIds.values() or the variable reportShellIds?
You can use another method with simple Map<String,Object> and place the array as is into the parameter map
public int update(String sql, java.util.Map<java.lang.String,?> paramMap)
I tried looking on google but without luck...
I have a SELECT SQLStatement and I want to use the LIKE operator but the parameters won't work and the query give me an error
public function getUsersList(username:String):SQLStatement
{
selectRecord= new SQLStatement();
selectRecord.sqlConnection = connection;
selectRecord.text =
"SELECT id_user, username,password,profile,leg_cliente " +
"FROM userlist " +
"WHERE username like '%:username%'";
selectRecord.parameters[":username"] = username;
return selectRecord;
}
The error I got is
':username' parameter name(s) found in parameters property but not in
the SQL specified.
I solved putting the wildcard % in the parameters instead of the statement...
selectRecord.text =
"SELECT id_user, username,password,profile,leg_cliente " +
"FROM userlist " +
"WHERE username like :username";
selectRecord.parameters[":username"] = "%"+ username+"%";
The starting problem was triggered because the query was like
selectRecord.text =
"SELECT id_user, username,password,profile,leg_cliente " +
"FROM userlist " +
"WHERE username like '%:username%'";
Putting the single quote in the statement won't let the statement to set the parameter, I suppose because the parameter key (in statement.text) is seen as a text and not a parameter itself...
This is a weird issue I've been stuck with for quite some time now. One solution I've used is like this:
var statementText:String="SELECT id_user, username,password,profile,leg_cliente " +
"FROM userlist " +
"WHERE username like '%:username%'";
var params:Dictionary=new Dictionary();
params[":username"] = username;
for(var key:Object in params) {
while(statementText.indexOf(key.toString()) >= 0) {
statementText= statementText.replace(key, params[key]);
}
}
selectRecord.text = statementText;