I'd like to create query like this with QueryDSL
update WorkMessage w set w.totalPrice = 0.12 - w.totalCost;
I tried like this
Expression<Float> priceExpr = Expressions.constant(0.12f);
new JPAUpdateClause(em, w)
.set(w.totalPrice , priceExpr.subtract(w.totalCost));
But this doesn't work - Expression doesn't have subtract method.
I did it like this:
new JPAUpdateClause(em, w)
.set(w.totalPrice , w.totalCost.subtract(0.12f).negate());
but I'd like to know how to do it the first way.
//EDit
The second way don't work:
JPAUpdateClause.toString says:
update WorkMessage workMessage
set workMessage.totalPrice = -(workMessage.totalCost - :a1)
but the SQL result is
update work_message set total_price=-total_cost-?
Parentheses just dissapeared. Am I doing something wrong? It looks like theese:
w.totalCost.subtract(0.12f).negate()
w.totalCost.negate().subtract(0.12f)
have the same result.
For the above problem
w.totalCost.negate().add(0.12f)
works. But I think there is a bug.
We removed the DSL Constant types some time ago from Querydsl. If you really want to write it the first way, then you have to express it like this :
Expressions.operation(Float.class, Ops.SUB,
Expressions.constant(0.12f), w.totalCost)
or
NumberOperation.create(Float.class, Ops.SUB,
Expressions.constant(0.12f), w.totalCost)
if you need a NumberExpression
I had the same problem some time ago (needed the constant 0), and did build my own ConstantNumberExpression class. It turned out surprisingly easy :-)
A collegue just had the same problem, for the constant 1, so I decided to post it here.
private static class ConstantNumberExpression extends NumberExpression<Integer> {
private static final long serialVersionUID = 1220768215234001828L;
public ConstantNumberExpression(final int constant) {
super(new ConstantImpl<>(constant));
}
#Override
#Nullable
public <R, C> R accept(final Visitor<R, C> v, #Nullable final C context) {
return v.visit((Constant<Integer>) mixin, context);
}
}
Of course this could be done a bit more generic, using a type parameter, but we did need it only for Integer (actually only for zero and one).
Related
I'm returning to Java after having been away for a very, very long time, and I'm trying to do in Java the sort of thing that I've often done in Javascript or Typescript. But I can't figure it out.
I'm trying to create a mapping between two different systems to easily map types and copy values from one system to the other. The systems are Neo4j and Excel, although my question doesn't really have anything to do with either of those. Basically the idea is that users can export data from Neo4j to an Excel sheet, edit values there, and then import it again. (I know! It's a terrible idea! But they really want it and we can blame them if they mess up.)
Still, at the very least I'd like them to not change the types of data in neo4j properties, so I'm building a fairly strict mapping:
public enum Neo4jExcelDataTypeMapping {
STRING("String", cell -> cell.getStringCellValue()),
INTEGER("Integer", cell -> cell.getNumericCellValue()),
FLOAT("Float", cell -> cell.getNumericCellValue()),
BOOLEAN("Boolean", cell -> cell.getBooleanCellValue()),
STRING_ARRAY("String[]",
cell -> Neo4jExcelDataTypeMapping.deserializeArrayToString(cell.getStringCellValue()),
value -> serializeArray((Object[]) value)
),
DATE("Date",
cell -> LocalDate.parse(cell.getStringCellValue()),
value -> ((LocalDate)value).format(DateTimeFormatter.ISO_LOCAL_DATE)),
);
interface ExcelCellReader {
Object readValue(Cell cell);
}
interface ExcelCellWriter {
Object writeValue(Object value);
}
public final String className;
public final ExcelCellReader excelCellReader;
public final ExcelCellWriter excelCellWriter;
private Neo4jExcelDataTypeMapping(String className, ExcelCellReader excelCellReader) {
this.className = className;
this.excelCellReader = excelCellReader;
this.excelCellWriter = value -> value;
}
private Neo4jExcelDataTypeMapping(String className, ExcelCellReader excelCellReader, ExcelCellWriter excelCellWriter) {
this.className = className;
this.excelCellReader = excelCellReader;
this.excelCellWriter = excelCellWriter;
}
public static Neo4jExcelDataTypeMapping fromNeo4jType(String type) {
for (Neo4jExcelDataTypeMapping instance : Neo4jExcelDataTypeMapping.values()) {
if (instance.className.equals(type)) {
return instance;
}
}
return null;
}
}
(I'm leaving out the serialization/deserialization of arrays in a readable manner, because that's a whole separate issue.)
This code seems fine. The IDE doesn't complain about it at least. But then I try to use it in a unit test:
#Test
public void testStringMapping() {
String testString = "Test String";
VirtualNode node = new VirtualNode(1);
node.setProperty("test", testString);
Cell cell = row.createCell(0);
String neo4jType = node.getProperty("test").getClass().getSimpleName();
Neo4jExcelDataTypeMapping mapping = Neo4jExcelDataTypeMapping.fromNeo4jType(neo4jType);
cell.setCellValue(mapping.excelCellWriter.writeValue(node.getProperty("test")));
}
Here, the problem is that cell.setCellValue() expects a specific type. It's heavily overloaded, so it can accept String, Integer, Float, various Dates, and more. But not Object. Now all the objects I'm returning from my lambda will be one of those types, but the lambda itself says it's returning an Object, and Java doesn't like that.
In TypeScript, I might have it return String|Integer|Float|Date, but you can't do that in Java. Is it possible to do this with generics somehow?
I don't want to explicitly cast in cell.setCellValue((String)mapping.excelCellWriter.writeValue(node.getProperty("test"))); because this is just going to be a single line that should work for all data types. I wrote the enum exactly to handle this, but it can't seem to handle this one final cast. I suspect some generic type magic could do it, but I never really mastered that aspect of Java.
(Also: I'm not a fan of the excelWriter.writeValue(). Is there a way to make excelWriter() both a property of the enum and the function that's called? Or is that too JavaScript of me?)
I'm trying to use a column as a regular expression to match against a user provided string, but can't figure out how to do it with QueryDSL. Mostly I can't figure out how to put the user supplied string on the lefthand side of the expression.
Basically I'm looking to do something similar to the following, where ~ is my databases symbol for regex matching…
SELECT * FROM thing WHERE 'user supplied string' ~ thing.match
The following works
Expressions.predicate(Ops.MATCHES, Expressions.constant(...), path)
I don't know that this is the best way, but the only solution I was able to get working was to subclass StringExpression
class ConstantExpression extends StringExpression {
private Constant<String> constant;
static public ConstantExpression create(String constant) {
return new ConstantExpression(new ConstantImpl<String>(constant);
}
public ConstantExpression(Constant<String> mixin) {
super(mixin);
constant = mixin;
}
public <R,C> R accept(Visitor<R,C> v, C context) {
return v.visit(constnat, context);
}
}
Then I was able to use that as the lefthand side of the equation…
createJPAQueryFactory().from(qthing)
.where(ConstantExpression.create("user supplied…").like(thing.match)
Situation: I'm working on legacy code and trying to improve readability. The following example should visualize the intent:
private static final String CONSTANT_1 = "anyValue";
private static final String CONSTANT_2 = "anyValue";
private static final String CONSTANT_3 = "anyValue";
private static final String CONSTANT_4 = "anyValue";
private static final String CONSTANT_5 = "anyValue";
private final SomeType someField = new SomeType();
private void contentOfSomeMethods(){
someMethod(someField, CONSTANT_1, true);
someMethod(someField, CONSTANT_2, true);
someMethod(someField, CONSTANT_3, true);
someMethod(someField, CONSTANT_4, false);
someMethod(someField, CONSTANT_5, false);
}
private void someMethod(SomeType type, String value, boolean someFlag) { }
Imagine, there are about 50 calls of someMethod using about 50 constants. I want to do safe automatical refactorings on that code so that the contentOfSomeMethods method changes to
private void contentOfSomeMethods(){
doItWith(CONSTANT_1);
doItWith(CONSTANT_2);
doItWith(CONSTANT_3);
doItNotWith(CONSTANT_4);
doItNotWith(CONSTANT_5);
}
and two additional methods are generated:
private void doItWith(String value) {
someMethod(someField, value, true);
}
private void doItNotWith(String value) {
someMethod(someField, value, false);
}
The naive way is to extract all constants in contentOfSomeMethods inside local variables and use then the extract method refactoring to create the desired methods. And afterwards to inline back the local variables. But this solution doesn't scale up.
Another way is to use search and replace with regular expressions, but this is not a safe refactoring, so I could break the code without noticing it.
Do you have any better suggestions? Do you know some plugins for Eclipse that allow that?
I don't know of any utility that would do this directly.
I think using a regular expression is the only to go. First, you will need to create the two target methods doItWith and doItNotWith. Then, you can highlight the contents of the method contentOfSomeMethods, hit Ctrl+F, and use the following regular expressions:
Find: someMethod\(someField, (\w*), true\);
Replace with: doItWith(\1);
and then
Find: someMethod\(someField, (\w*), false\);
Replace with: doItNotWith(\1);
Be sure to check "Regular Expressions" and "Selected lines". Here's a picture of it:
The regular expressions match the constant that is used inside the function call with (\w*) and then it is used during the replacement with \1. Using this regular expression only on the selected lines minimizes the chance of breaking unrelated code.
Do it with a regular expression and verify it.
I'm assuming that each call to someMethod spans only one line. If not this method is still useful but slower.
Copy the original file.
Use ctrl+alt+h to show the Callers of someMethod and get a count of them.
Do regex search and replaces restricted to the proper area :
Find : someMethod(someField,([ ]*CONSTANT_[0-9]+)[ ]*,[ ]*true[ ]*)[ ]*;
Replace : doItWith("$1");
Find : someMethod(someField,([ ]*CONSTANT_[0-9]+)[ ]*,[ ]*false[ ]*)[ ]*;
Replace : doItNotWith("$1");
Make a diff of the original file and the new file showing only the lines of the original file which have changed.
diff --changed-group-format='%<' --unchanged-group-format='' original.java refactored.java | wc
You should get the same number of lines as you got in the callers of someMethod.
If the calls to someMethod are multiline, or if you want greater verification, just drop | wc to see the lines which were modified in the original file to ensure that only the correct lines have been modified.
Alas I know nothing in Eclipse that allows to do this today.
This is something I would like to achieve one day in AutoRefactor: https://github.com/JnRouvignac/AutoRefactor/issues/8
However the road to get there is quite long.
The only ways I know today are to extract local variables then extract method (as you suggested) or use regexes (as somebody else suggested).
I have a scala function with the following signature:
def getValue: Validation[ Throwable, String ]
Now, I want to process in Java the result (say res) of calling this function.
I can call res.isSuccess() and res.isFailure() but how do I extract the underlying Throwable or success String ?
I tried casting but testing (res instanceof scalaz.Failure) results in a scalaz.Failure cannot be resolved to a type (the scala and scalaz jars are visible)
Is there a generic way of doing this for Validation, Option, Either, etc... ?
EDIT I realize I can probably use a fold but that would lead to a lot of ugly boilerplate code in Java (which does not need more). Anything better looking ?
Success and Failure are both case classes:
final case class Success[E, A](a: A) extends Validation[E, A]
final case class Failure[E, A](e: E) extends Validation[E, A]
So you can write the following, for example:
import scalaz.*;
public class Javaz {
public static void main(String[] args) {
Validation<Throwable, String> res = new Success<Throwable, String>("test");
if (res.isSuccess()) {
System.out.println(((Success) res).a());
} else {
System.out.println(((Failure) res).e());
}
}
}
For Option and Either you can use the get method (after taking the left or right projection in the case of Either).
If at all possible it's probably cleaner to do this kind of unwrapping with a fold, etc. on the Scala side, though.
What's the best practice for specifying flags in a Java method?
I've seen SWT using int as bitfields, like:
(example partially from "Effective Java, 2nd Ed." page 159):
public class Text {
public static final int STYLE_BOLD = 1 << 0; // 1
public static final int STYLE_ITALIC = 1 << 1; // 2
void printText(String text, int flags) {
}
}
and your client call looks like:
printText("hello", Text.STYLE_BOLD | Text.STYLE_ITALIC);
..but this is discouraged as you can mixed flags (int values) from different classes together without any compiler checks.
In the same book ("Effective Java"), I see the use of EnumSet, but then your user call becomes:
printText("hello", EnumSet.of(Style.Bold, Style.ITALIC));
I find this a bit verbose and I prefer the elegance of SWT.
Is there any other alternative or is this basically the two tastes you must pick?
Guess you have hit a wall. I don't see any other option. Java is verbose that's a fact. In situations like this i usually add a local variable to make the code more readable. You can do this,
EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.ITALIC);
printText("hello", styles);
If you want bit style flags, Java wraps them in a BitSet. It's been around for ages, yet few people bother to use it (preferring embedding C style bit handling in ints).
The api for BitSet can be found here.
Coupled with a few well chosen static ints, it does pretty well until you start getting into checking and setting multiple bits in one pass.
I advise that you go with the EnumSet approach.
EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.Italic);
This approach provides better type safety, and Style being an enum will have full-blown OO capabilities.
Late answer for anyone coming across this. Here is one way to do it to reduce memory and have a nice enum like api:
public static class MyFlag {
public static final MyFlag A = new MyFlag(1<<0);
public static final MyFlag B = new MyFlag(1<<1);
public static final MyFlag C = new MyFlag(1<<2);
public static final MyFlag ALL = A.and(B).and(C);
private final int flag;
private MyFlag(int flag){
this.flag = flag;
}
public MyFlag and(MyFlag limit){
return new MyFlag(flag & limit.flag);
}
public MyFlag not(MyFlag limit){
return new MyFlag(flag | ~limit.flag);
}
public boolean isSet(MyFlag limit){
if(limit ==null){
return false;
}
return (this.flag & limit.flag) != 0;
}
}
method:
public void doFoo(MyFlag flag){
if(MyFlag.A.isSet(flag)){
....
}
if(MyFlag.C.isSet(flag)){
....
}
}
call:
x.doFoo(MyFlag.A.and(MyFlag.C));
If you only have a limited number of methods that will be taking a set of styles (like printText, in your example), you can tweak their signature to take a variable number of Style params:
void printText(String text, Style... flags) {
EnumSet<Style> style = logicalOr(flags); // see comment below
...
}
And then your calls are very close to the untyped (int) flag route:
printText("hello", Style.BOLD, Style.ITALIC);
Sadly, there is no EnumSet.of(E... ) factory, just EnumSet.of(E first, E... more), so you'll need a generic logicalOr method to split your array into first + rest chunks. Left as an exercise to the reader =).