JPA/ Hibernate function in multiselect NPE - java

Using a function in a multiselect (or select(construct(...)) results in a NullPointerException (Hibernate 4+) with the following code:
criteriaQuery.select(criteriaBuilder.construct(OrderCriteria.class,
order.get(Order_.id),
criteriaBuilder.function("array_to_string", String.class,
criteriaBuilder.function("array_agg", String.class, employee.<String>get(Employee_.firstName)), criteriaBuilder.literal(",")),
));
The following exception is thrown:
java.lang.NullPointerException
org.hibernate.internal.util.ReflectHelper.getConstructor(ReflectHelper.java:354)
org.hibernate.hql.internal.ast.tree.ConstructorNode.resolveConstructor(ConstructorNode.java:185)
I have traced the exception back to Hibernate ConstructionNode::resolveConstructorArgumentTypes.
It appears that getDataType() does not exist on MethodeNode (criteriaBuilder.function creates a MethodNode) resulting in a NPE:
private Type[] resolveConstructorArgumentTypes() throws SemanticException {
SelectExpression[] argumentExpressions = collectSelectExpressions();
if ( argumentExpressions == null ) {
// return an empty Type array
return new Type[] {};
}
Type[] types = new Type[argumentExpressions.length];
for ( int x = 0; x < argumentExpressions.length; x++ ) {
types[x] = argumentExpressions[x].getDataType(); --> [types[x] == null with MethodNode]
}
return types;
}
Is there something wrong with the way the select is constructed?

After a few hours it became clear the using an non-registered function cannot be used in this way, resulting in this very unclear exception.
Solution:
public class ExtendedPostgreSQL9Dialect extends PostgreSQL9Dialect{
public ExtendedPostgreSQL9Dialect() {
super();
registerFunction("array_agg", new StandardSQLFunction("array_agg", StandardBasicTypes.STRING));
}
}

Related

Writing a constructor of a class that extends an ArrayList

This is the signature of my class:
public class Constraint extends ArrayList<Interval> {
// ...
}
the other class Interval:
public class Interval {
// ...
}
has two ints, first and last
Constructor:
public Interval(int first, int last) {
this.first = first;
this.last = last;
}
A method that returns the union of two Intervals or more but should be of Constraint type:
public Constraint union(Interval interval) {
Interval a = new Interval(first, end);
int l = 0;
int max = 0;
// Interval result = new Interval(l, max);
l = (a.first < interval.end) ? a.first : interval.end;
max = (a.end > interval.end) ? a.end : interval.end;
return new Interval(l, max);
// the return here will return a new interval of type Interval but
// the method that I'm suppose to write should return something of
// type Constraint
}
My main issue is: how can I write the following constructor?
public Constraint(Collection<Interval> collection) throws NullPointerException {
// if the collection is empty, I have to write something like this:
if (collection == null) {
throw new NullPointerException("collection is empty");
}
// ...
}
Any help on how I should write the constructor of the class Constraint is really appreciated.
You have stumbled upon a deficiency of Java: the call to super() must be the first call in your constructor, so you are not allowed to precede it with code that checks against null. There is no good reason for this limitation, it is just the way java is. A flaw in the language. (If you learn Scala you will see that it totally did not have to be this way.)
So, the solution is to do the null-check in the same statement as the call to super. The following should accomplish this:
public Constraint( Collection<Interval> collection )
{
super( Objects.requireNonNull( collection ) );
}
If your version of java does not have Objects.requireNonNull() you can code a private static function yourself which checks the collection for nullity, throws if null, or returns the collection as-is if not null.

Java invokes String.valueOf(char[] data) instead of String.valueOf(int i) for Integer parameter and throw ClassCastException

I have a problem with invoking String.valueOf method. As argument I passed generic method which returns Integer type. And then exception is thrown because program try to cast that returned Integer to char[] to invoke String.valueOf method. As I know String has overloaded valueOf() method and one of them can take Integer parameter.
Below is screenshot from Eclipse expression evaluation which shows situation.
This line throws ClassCastException
String quality = String.valueOf(model.get(property));
This is what model.get(property) invokes:
public <X> X get(String property) {
X value = null;
try {
if (allowNestedValues && NestedModelUtil.isNestedProperty(property)) {
return (X) NestedModelUtil.getNestedValue(this, property);
}
if (map != null) {
Object objValue = map.get(property);
if (objValue != null)
value = (X) objValue;
}
} catch (Exception e) {
}
return map == null ? null : value;
}
EDIT:
I added this condition and compiler goes inside the if statement
if(model.get(property) instanceof Integer)
{
quality = String.valueOf(model.get(property));
}
How is the compiler supposed to infer the correct X the way you call it?
Split it into
YourType qualityRaw = model.get(property);
String quality = String.valueOf(qualityRaw);
You should try Integer.toString method if you know that your return type is of Integer type.

Passign attribute name as parameter automatically in Java-8

I would like to have a method to validate fields kind of
protected void validate(String field, String fieldName){
if (field==null || field.isEmpty){
throw new IllegalArgumentException("Parameter " + fieldName + " cannot be empty");
}
}
and use in my class for example
class Foo {
private String x;
private String y;
...
public void validateAll(){
validate(x, "x");
validate(y, "y");
}
}
It would be great to use in this way
public void validateAll(){
validate(x);
validate(y);
}
and let the compiler pass the name of the variable automatically to validate(field, fieldName) method
How can I achive this in Java-8 ?
You can achieve this in Java by abandoning the idea of having java classes with fields, and instead having a Map which maps Column objects to values. From a usage standpoint, it would look roughly like this:
public static final Column<String> X_COLUMN = new Column<>( "x", String.class );
public static final Column<String> Y_COLUMN = new Column<>( "y", String.class );
public static final Table FOO_TABLE = new Table( "Foo", X_COLUMN, Y_COLUMN, ... );
...
Row fooRow = new Row( FOO_TABLE );
fooRow.setFieldValue( X_COLUMN, "x" );
String x = fooRow.getFieldValue( X_COLUMN );
for( Column<?> column : fooRow.getTable().getColumns() )
doSomethingWithField( fooRow, column );
private static <T> void doSomethingWithField( Row row, Column<T> column )
{
T value = row.getFieldValue( column );
...do something with the field value...
}
Since a value passed as argument to a method bears no information about the field it originated from, if it was read from a field at all, you can’t reconstruct this information. However, since your intent to verify fields, the desired operation is possible when processing the fields in the first place, rather than their contained values:
class Foo {
private String x;
private String y;
//...
public void validateAll() {
for(Field f: Foo.class.getDeclaredFields()) {
if(!Modifier.isStatic(f.getModifiers()) && !f.getType().isPrimitive()) try {
Object o=f.get(this);
if(o==null || o.equals(""))
throw new IllegalArgumentException(f.getName()+" cannot be empty");
} catch(ReflectiveOperationException ex) { throw new AssertionError(); }
}
}
}
The general problem of this approach is that by the time validateAll() reports a problem, the Foo instance already contains the illegal state. It’s preferable to reject invalid values right when they are attempted to set for a property. In that case, the parameter name of the method might not be available reflectively, however, when a method named setX throws an IllegalArgumentException (as would be indicated by the stack trace), there is no need for an additional meta information in the message…

getting class of object wrapper from class of primitive types

So I have a object whose methods I get using reflection. I am getting expected arguments as Object... methodArgs and this cannot be changed. After checking the name I am doing a parameters check
if (method.getName().equals(methodName))
{
Class<?>[] pType = method.getParameterTypes();
if(pType.length == methodArgs.length)
{
boolean methodMatched = true;
for (int i = 0; i < methodArgs.length; i++)
{
if(!pType[i].equals(methodArgs[i].getClass()))
{
methodMatched = false;
}
}
if(methodMatched)
{
targetMethod = method;
break;
}
}
}
but it will fail for methods let say public void dummyMethod(boolean b); as methodArgs[i]..getClass() will return Boolean. How can I achieve this?
Somehow I want to convert boolean to 'Boolean' for pType. It can be any primitive data type.
I tried
Class.forName(boolean.class.getName()).getConstructor().newInstance().getClass();
but it does not work giving
Exception in thread "main" java.lang.ClassNotFoundException: boolean
Any suggestion is appreciated.

"int cannot be dereferenced" in Java

I'm fairly new to Java and I'm using BlueJ. I keep getting this "Int cannot be dereferenced" error when trying to compile and I'm not sure what the problem is. The error is specifically happening in my if statement at the bottom, where it says "equals" is an error and "int cannot be dereferenced." Hope to get some assistance as I have no idea what to do. Thank you in advance!
public class Catalog {
private Item[] list;
private int size;
// Construct an empty catalog with the specified capacity.
public Catalog(int max) {
list = new Item[max];
size = 0;
}
// Insert a new item into the catalog.
// Throw a CatalogFull exception if the catalog is full.
public void insert(Item obj) throws CatalogFull {
if (list.length == size) {
throw new CatalogFull();
}
list[size] = obj;
++size;
}
// Search the catalog for the item whose item number
// is the parameter id. Return the matching object
// if the search succeeds. Throw an ItemNotFound
// exception if the search fails.
public Item find(int id) throws ItemNotFound {
for (int pos = 0; pos < size; ++pos){
if (id.equals(list[pos].getItemNumber())){ //Getting error on "equals"
return list[pos];
}
else {
throw new ItemNotFound();
}
}
}
}
id is of primitive type int and not an Object. You cannot call methods on a primitive as you are doing here :
id.equals
Try replacing this:
if (id.equals(list[pos].getItemNumber())){ //Getting error on "equals"
with
if (id == list[pos].getItemNumber()){ //Getting error on "equals"
Basically, you're trying to use int as if it was an Object, which it isn't (well...it's complicated)
id.equals(list[pos].getItemNumber())
Should be...
id == list[pos].getItemNumber()
Dereferencing is the process of accessing the value referred to by a reference . Since, int is already a value (not a reference), it can not be dereferenced.
so u need to replace your code (.) to(==).
Assuming getItemNumber() returns an int, replace
if (id.equals(list[pos].getItemNumber()))
with
if (id == list[pos].getItemNumber())
Change
id.equals(list[pos].getItemNumber())
to
id == list[pos].getItemNumber()
For more details, you should learn the difference between the primitive types like int, char, and double and reference types.
As your methods an int datatype, you should use "==" instead of equals()
try replacing this
if (id.equals(list[pos].getItemNumber()))
with
if (id.equals==list[pos].getItemNumber())
it will fix the error .
I think you are getting this error in the initialization of the Integer somewhere
try
id == list[pos].getItemNumber()
instead of
id.equals(list[pos].getItemNumber()

Categories

Resources