Building Hibernate query depending of parameters that can be nulls - java

so i am working on a project right now
1st time using Hibernate
in this projet i am using Swing too
i have a form with multiple jTextFields
public List<Object[]> getoperations(String a,String c,String n,String e,String d) {
SessionDao s=new SessionDao();
session=s.getSession();
Query q;
q=session.createQuery("select idTiers,beneficiaire,emetteur,montant,numcompte,t_param_nature_operation.libelleNature,dateValidite,dateCreation where");
if (a != null && !a.isEmpty()) { q+= " and codeBanque='" + a + "'"; }
if (c != null && !c.isEmpty()) { q += " and numCompte='" + c + "'"; }
if (n != null && !n.isEmpty()) { q += " and t_param_nature_operation_.libelleNature='" + n + "'"; }
if (e != null && !e.isEmpty()) { q += " and decision='" + e + "'"; }
if (d != null && !d.isEmpty()) { q += " and dateCreation='" + d + "'"; }
q+= " order by idTiers" ;
return q.list();
}
As you see I am making a test on the values to add them in the query.
My question is there a way to add those values?
since query +="" isn't working.

Personally, I would add Guava utils to my project and use isNotBlank()
function. Anyway, you can write your own static function that would
return true if not null and not empty and false otherwise, and later
use it. It'll make your code much clearer.
The above was my comment and I decided to show you this little piece of code.
public static boolean isBlank(String s) {
if (s == null)
return true;
if (s.isEmpty())
return true;
return false;
}
Now you can simply write:
//static import your isBlank() method
//import static package.classInWhichIsBlankIsDeclared;
if (!isBlank(a) { q+= " and codeBanque='" + a + "'"; }
if (!isBlank(b) { q+= " and codeBanque='" + b + "'"; }
if (!isBlank(c) { q+= " and codeBanque='" + c + "'"; }
if (!isBlank(d) { q+= " and codeBanque='" + d + "'"; }
It's much more readable so it'll be much easier to debug in case of errors in the future.
Please, have a look at DRY principle and follow it. If your issue require checking same condition 4 or 5 times (2 times should be enough to use DRY) consider writing a function. call it the way that it'll be human-friendly instead of combination of different logical statements.
DRY. Don't Repeat Yourself.
"Every piece of knowledge must have a single, unambiguous, authoritative representation within a system"
Wikipedia article about DRY

you should consider using Criteria. it's more clean when dealing with multiple where statements.
eg
Criteria cr = session.createCriteria(YourEntityClass.class);
cr.add(Restrictions.eq("property1", value1));
cr.add(Restrictions.eq("property2", value2));
List results = cr.list();
have a look at these examples here

Related

How can I write this expression more compactly in Java 8?

How can I write that if more compact using java 8?
Optional.ofNullable(city).ifPresent(c -> {
if (!city.equalsIgnoreCase(district)) {
address.setCity(district + ", " + c);
}
});
As Eran commented, you can avoid the spurious detour over Optional by just directly checking for null:
if (city != null && !district.equalsIgnoreCase(city)) {
address.setCity(district + ", " + city);
}

if statement and user input advice

My user inputs work fine, my problem is I want an if statement that will say are both inputs equal?, but I get the attached error.
I need the code to be: if cork is entered in batman and robin?. This is what I tried:
System.out.println("From " + batman);
System.out.println("To " + Robin);
if(batman.equals("Cork") + Robin.equals("Cork") {
} else {
System.err.println("");
}
that here:
if(batman.equals("Cork") + Robin.equals("Cork") {
makes no sense because you are doing something like concatenating true with true or similar...
you have to do instead:
if(batman.equals("Cork") && Robin.equals("Cork") {
Your code should look like this :
System.out.println("From " + batman);
System.out.println("To " + Robin);
if(batman.equals("Cork") && Robin.equals("Cork")) {
// Statements
} else {
System.err.println("");
}
You should simply use && when requiring more then one test in an if statement.
+ doesn't work in such cases it simply concatenates values. Hope it helps :)

Java object declaration following return;?

I came across some unfamiliar Java syntax while looking at some code from jstl 1.1.2. It occurs to me the code I'm looking at was reverse compiled by Beyond Compare (or a plug-in thereof), so that might have something to do with it.
The code at the end of the method looks like this:
...
p.parse(page.getInputStream(), h);
if(failed)
return vmFromString("taglib " + prefix + " (" + uri + ") allows only the " +
"following taglibs to be imported: " + permittedTaglibs);
return null;
SaxException ex;
ex;
return vmFromString(ex.toString());
ex;
return vmFromString(ex.toString());
ex;
return vmFromString(ex.toString());
}
In jstl 1.1, before they refactored the PermittedTaglibsHandler, it looks like this:
...
saxparser.parse(pagedata.getInputStream(), permittedtaglibshandler);
if(failed)
return vmFromString("taglib " + s+ " (" + s1+ ") allows only the " +
"following taglibs to be imported: " + permittedTaglibs);
return null;
Object obj;
obj;
return vmFromString(((SaxException) (obj)).toString());
obj;
return vmFromString(((ParserConfigurationException) (obj)).toString());
obj;
return vmFromString(((IOException) (obj)).toString());
}
Is this odd syntax just an artifact of the reverse compile, or is there such a thing as meaningful code that follows a return statement?
Thanks,
Rebeccah
The code is just the exception handler loop customized to handle multiple exceptions - thus the multiple return statements. Its obviously not been translated correctly into Java.

How to disable pretty-printing in Groovy MarkupBuilder?

I have a string input in my Mule flow. It passes through my Groovy Script and outputs XML. I originaly had the script followed by an XSLT converter to remove empty nodes and set the indent to "no" in the output tag. But now I removed it as I cannot use it in conjunction with my script if I want to keep the special characters (see previous question here).
Instead I now check each value before printing the nodes. But the problem I have is my XML needs to be unindented in order to work with my InDesign project I adapt the XML for. I lost that ability when I removed the XSLT so I fixed one problem but created another.
I found the method getPrinter(), I used it with the setAutoIndent(false) but it didn't change anything to the output and created no errors. Not to sure where to use it.
Here's my script :
public Boolean isEmpty(value){
if(value.toString().trim() == "" || value.toString().trim() == '' || value == null)
return true;
}
root = new XmlSlurper(false,false).parseText(payload)
if(root.name() == 'GetActivitiesResponse')
startEach = root.children().children()
else
startEach = root.children()
def xml = new StringWriter().with { w -> new groovy.xml.MarkupBuilder(w).with {
mkp.xmlDeclaration(version: "1.0", encoding: "utf-8")
escapeAttributes = false
getPrinter().setAutoIndent(false);
"w_import_saisie_web"() {
startEach.each { p -> "w_evenement"() {
if(!isEmpty(p.PresentationDate))
"w_dates"{ mkp.yieldUnescaped (p.PresentationDate.toString() + "
") }
if(!isEmpty(p.SubTitle))
"w_contexte"{ mkp.yieldUnescaped (p.SubTitle.toString() + "
") }
//if(!isEmpty(p.SubTitle))
"w_nom_evenement"{ /*p.GEVT_Type*/ mkp.yieldUnescaped ("Nom evenement" + "
") }
if(!isEmpty(p.Name))
"w_titre"{ mkp.yieldUnescaped (p.Name.toString() + "
")}
if(!isEmpty(p.ShortDescription) || !isEmpty(p.Teaser))
"w_texte"{mkp.yieldUnescaped (p.ShortDescription.toString() + p.Teaser.toString() + "
")}
p.SubEvents.children().each { q -> "w_bloc_sous_evenement"() {
if(!isEmpty(q.PresentationDate) || !isEmpty(q.Name))
"w_sous_eve_titre"{ mkp.yieldUnescaped (q.PresentationDate.toString() + q.Name.toString() + "
")}
if(!isEmpty(q.ShortDescription) || !isEmpty(q.Teaser) || !isEmpty(q.WebDescription))
"w_sous_eve_desc"{mkp.yieldUnescaped (q.ShortDescription.toString() + q.Teaser.toString() + q.WebDescription.toString() + "
")}
}
}
if(!isEmpty(p.Site) || !isEmpty(p.PresentationHours))
"w_coordonnees"{ mkp.yieldUnescaped ("teeeessdfsdfsdfst" + p.Site.toString() + ' - ' + p.PresentationHours.toString() + "
")}
}
}
}
}
w.toString()
}
Add an IndentPrinter when you create the MarkupBuilder.
def xml = new MarkupBuilder(new IndentPrinter(new PrintWriter(writer), "", true))
See this question:
groovy.xml.MarkupBuilder disable PrettyPrint
I tried a bunch of different things to see if setAutoIndent was effective (setting it before passing the IndentPrinter to the MarkupBuilder for example) and it didn't seem to have any effect. So, like you, I'm wondering about its purpose.
Realised I was searching too hard... just added this simple line to the toString() at the end...
w.toString().replaceAll(">\\s+<", "><").trim();

Library for evaluating logical expressions on Java objects

Let's say I have the following class:
class Person {
int age;
String city;
Collection<Person> friends;
Person spouse;
}
I need a library which would allow me to evaluate whether a logical expression is true on a given Person object. The expression would look something like this:
((age>25 OR spouse.age>27) AND city=="New-York" AND size(friends)>100)
So, the requirements are:
Ability to use basic logical operators
Access properties of the given object
Access properties of an internal object
Use simple mathematical\sql-like functions such as size,max,sum
Suggestions?
You could use a ScriptEngine + reflection:
access all the fields in your object and create variable that have those values
evaluate the expression
Here is a contrived example which outputs:
age = 35
city = "London"
age > 32 && city == "London" => true
age > 32 && city == "Paris" => false
age < 32 && city == "London" => false
It could become quite messy if you want to deal with non primitive types, such as collections.
public class Test1 {
public static void main(String[] args) throws Exception{
Person p = new Person();
p.age = 35;
p.city = "London";
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
Class<Person> c = Person.class;
for (Field f : c.getDeclaredFields()) {
Object o = f.get(p);
String assignement = null;
if (o instanceof String) {
assignement = f.getName() + " = \"" + String.valueOf(o) + "\"";
} else {
assignement = f.getName() + " = " + String.valueOf(o);
}
engine.eval(assignement);
System.out.println(assignement);
}
String condition = "age > 32 && city == \"London\"";
System.out.println(condition + " => " + engine.eval(condition));
condition = "age > 32 && city == \"Paris\"";
System.out.println(condition + " => " + engine.eval(condition));
condition = "age < 32 && city == \"London\"";
System.out.println(condition + " => " + engine.eval(condition));
}
public static class Person {
int age;
String city;
}
}
OK, think I found what I wanted, it's a variation on assylias' answer but I prefer it since it's more standardized (woudn't want to depend specifically on Javascript expressions, or run Javascript at all for that matter).
Apparently there is a Unified Expression Language for evaluating expressions, it was originally designed for JSP but can be used for other stuff as well. There are several parser implementations, I'll probably go either with Spring EL or JUEL
You can use rhino library from Mozilla. https://github.com/mozilla/rhino
Example :
#Test
public void shouldCheckLogicalOperations(){
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
ScriptableObject.putProperty(scope, "form_admin_checked", true);
ScriptableObject.putProperty(scope, "form_limit_value", 50000);
String script = "((form_admin_checked && form_limit_value<2000) || (form_admin_checked && !form_admin_checked) || form_admin_checked && form_limit_value==50000)";
String expectedResponse = "true";
Object result = cx.evaluateString(scope, script, "<cmd>", 1, null);
Assert.assertEquals(expectedResponse, result.toString());
} finally {
// Exit from the context.
Context.exit();
}
}

Categories

Resources