0

I want to the set null values on runtime depending on the type I get

Here is my code

@SuppressWarnings("rawtypes")
// input can be Intger,Date, BigInt etc which Mysql supports
String input = "."+st.getType();
// param :- java.sql.Types.Integer or java.sql.Types.BigInt
Class clazz = Class.forName("java.sql.Types");
Field field = clazz.getField(input);
int val = field.getInt(null);
pstmt.setNull(1,val);
10
  • use Integer instead of int. int can only be 0 while Integer can also be null Commented Apr 13, 2017 at 14:09
  • Ok not the problem of that. suppose I want to insert for BigInt on coderun i.e not manually setting to java.sql.Types.BigInt. How to do that? Commented Apr 13, 2017 at 14:17
  • what is st? Where is it declared and how is it initialized? Commented Apr 13, 2017 at 14:31
  • @IanMcLaird I have a class Stateros . It's object is st and st.getType() would give me it's either varchar or Date or Integer.. Commented Apr 13, 2017 at 14:37
  • 1
    What are you trying to do? What is st, why the reflection magic? Commented Apr 13, 2017 at 20:13

1 Answer 1

2

I'm going to slightly challenge your question in this answer. I do not believe that you need to do what you are doing, but as it's somewhat unclear, I'll do what I can to help you out.

First, based on the variable name pstmt I'm going to guess that this is a PreparedStatement that looks something like this:

INSERT INTO my_table (my_int, my_date, my_varchar, my_bool) VALUES (?, ?, ?, ?);

If this is the case, then you don't need to do any reflection at all, because Parameter 1 will always be an INTEGER, Parameter 2 will always be a DATE and so on. So you know what type to use in setNull because you know the position already (because you have to, because it's the first argument to setNull), and you know the statement. It's generally going to be much easier to follow your code if you just do the obvious thing and set the values.

if (myInt != null) {
    pstmt.setInt(1, myInt);
} else {
    pstmt.setNull(1, Types.INTEGER);
}
pstmt.setDate(2, myDate);  // already handles null
// and so on

Now, this might get a tad trickier if you're trying to set the columns in a loop for some reason. I suggest to you that this is a bad idea because it'll be less obvious to future developers what you're up to.

However, the JDBC API has setObject for just such an occasion. setObject will allow null values, so you don't have to handle the null and not-null cases separately. There's even a version of setObject that will allow you to do this without specifying the type. In that case, it's just:

for (int i = 0; i < myObjects.size(); ++i) {
    Object obj = myObjects.get(i);
    pstmt.setObject(i, obj);
}

No casting, no remembering the type, no reflection needed. The documentation says it's not supported by every database, but I'd give this a shot before you do reflection.

Now to Answer Your Question

If, for some reason, you need to do this with reflection (because you're one of the unlucky few whose database doesn't support un-typed nulls), you were actually pretty close.

public void apply(PreparedStatement pstmt, int param, String typeName, Object value) {
    try {
        Class<?> types = Types.class;
        Field field = types.getField(typeName);
        int typeValue = field.getInt(null);

        pstmt.setObject(param, obj, typeValue);
    } catch (Exception e) {
        // handle exceptions
    }
}

So what's different here from what you were trying? First, the field name doesn't have a . in front of it. That's not part of the field name. Secondly, the typeName parameter here must exactly match the java.sql.Types field name. This is a case-sensitive String. So, for example it's "INTEGER" not "int". In your comment, you indicated that your st.getType() method had an ArrayList. I've assumed that this method returns a single string, based on its knowledge of the query. Just make sure that your type names are the same as the names used by java.sql.Types and that the object in question can actually be used as (cast / converted to) that type.

Sign up to request clarification or add additional context in comments.

1 Comment

Cool explanation. Thanks :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.