Code change

View: New views
2 Messages — Rating Filter:   Alert me  

Code change

by Rainer Heesen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

I had the following error message in my junit tests:

java.lang.NullPointerException
        at org.skife.jdbi.v2.BeanMapper.map(BeanMapper.java:136)
        at org.skife.jdbi.v2.Query$1.munge(Query.java:80)
        at org.skife.jdbi.v2.Query$1.munge(Query.java:74)
        at org.skife.jdbi.v2.SQLStatement.internalExecute(SQLStatement.java:887)
        at org.skife.jdbi.v2.Query.list(Query.java:72)
        at
com.recruiter.portal.DatabaseSecurityHandler.loadLoginData(DatabaseSecurityHandler.java:157)
        at
com.recruiter.portal.DatabaseSecurityHandlerTest.testDatabase(DatabaseSecurityHandlerTest.java:314)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at junit.framework.TestCase.runTest(TestCase.java:154)

It was my fault of course since I didn't provide an appropriate method in my
bean class.  (descriptor.getWriteMethod() was null)

However, it is easer to debug if we add another catch statement in
BeanMapper.java.

Enclosed you will find a changed BeanMapper.java version. Could it be part of
the next jDBI release?

Kind regards

 Rainer


[BeanMapper.java]

/*
 * Copyright 2004-2007 Brian McCallister
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.skife.jdbi.v2;

import org.skife.jdbi.v2.tweak.ResultSetMapper;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * A result set mapper which maps the fields in a statement into a JavaBean. This uses
 * the JDK's built in bean mapping facilities, so it does not support nested properties.
 */
public class BeanMapper<T> implements ResultSetMapper<T>
{
    private final Class<T> type;
        private final Map<String, PropertyDescriptor> properties = new HashMap<String, PropertyDescriptor>();

        public BeanMapper(Class<T> type)
    {
        this.type = type;
        try
        {
            BeanInfo info = Introspector.getBeanInfo(type);

                        for (PropertyDescriptor descriptor : info.getPropertyDescriptors())
                        {
                                properties.put(descriptor.getName().toLowerCase(), descriptor);
                        }
                }
        catch (IntrospectionException e)
        {
            throw new IllegalArgumentException(e);
        }
        }

        public T map(int row, ResultSet rs, StatementContext ctx)
                        throws SQLException
        {
                T bean;
        try
        {
            bean = type.newInstance();
        }
        catch (Exception e)
        {
            throw new IllegalArgumentException(String.format("A bean, %s, was mapped " +
                                                             "which was not instantiable", type.getName()),
                                               e);
        }

                ResultSetMetaData metadata = rs.getMetaData();

                for (int i = 1; i <= metadata.getColumnCount(); ++i) {
                        String name = metadata.getColumnName(i).toLowerCase();

                        PropertyDescriptor descriptor = properties.get(name);

                        if (descriptor != null) {
                                Class type = descriptor.getPropertyType();

                                Object value;

                                if (type.isAssignableFrom(Boolean.class) || type.isAssignableFrom(boolean.class)) {
                                        value = rs.getBoolean(i);
                                }
                                else if (type.isAssignableFrom(Byte.class) || type.isAssignableFrom(byte.class)) {
                                        value = rs.getByte(i);
                                }
                                else if (type.isAssignableFrom(Short.class) || type.isAssignableFrom(short.class)) {
                                        value = rs.getShort(i);
                                }
                                else if (type.isAssignableFrom(Integer.class) || type.isAssignableFrom(int.class)) {
                                        value = rs.getInt(i);
                                }
                                else if (type.isAssignableFrom(Long.class) || type.isAssignableFrom(long.class)) {
                                        value = rs.getLong(i);
                                }
                                else if (type.isAssignableFrom(Float.class) || type.isAssignableFrom(float.class)) {
                                        value = rs.getFloat(i);
                                }
                                else if (type.isAssignableFrom(Double.class) || type.isAssignableFrom(double.class)) {
                                        value = rs.getDouble(i);
                                }
                                else if (type.isAssignableFrom(BigDecimal.class)) {
                                        value = rs.getBigDecimal(i);
                                }
                                else if (type.isAssignableFrom(Timestamp.class)) {
                                        value = rs.getTimestamp(i);
                                }
                                else if (type.isAssignableFrom(Time.class)) {
                                        value = rs.getTime(i);
                                }
                                else if (type.isAssignableFrom(Date.class)) {
                                        value = rs.getDate(i);
                                }
                                else if (type.isAssignableFrom(String.class)) {
                                        value = rs.getString(i);
                                }
                                else {
                                        value = rs.getObject(i);
                                }

                                if (rs.wasNull() && !type.isPrimitive()) {
                                        value = null;
                                }

                                try
                                {
                                        descriptor.getWriteMethod().invoke(bean, value);
                                }
                                catch (IllegalAccessException e)
                                {
                                        throw new IllegalArgumentException(String.format("Unable to access setter for " +
                                                                                                                                         "property, %s", name), e);
                                }
                                catch (InvocationTargetException e)
                                {
                                        throw new IllegalArgumentException(String.format("Invocation target exception trying to " +
                                                                                                                                         "invoker setter for the %s property", name), e);
                                }
        catch (NullPointerException e)
        {
          throw new IllegalArgumentException(String.format("No appropriate method to " +
                                   "write value %s ", value.toString()), e);
        }

                        }
                }

        return bean;
        }
}



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

Re: Code change

by Brian McCallister :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Awesome, thank you!

-Brian

On Thu, Mar 20, 2008 at 8:24 AM, Rainer Heesen <rainer.heesen@...> wrote:
Hello,

I had the following error message in my junit tests:

java.lang.NullPointerException
       at org.skife.jdbi.v2.BeanMapper.map(BeanMapper.java:136)
       at org.skife.jdbi.v2.Query$1.munge(Query.java:80)
       at org.skife.jdbi.v2.Query$1.munge(Query.java:74)
       at org.skife.jdbi.v2.SQLStatement.internalExecute(SQLStatement.java:887)
       at org.skife.jdbi.v2.Query.list(Query.java:72)
       at
com.recruiter.portal.DatabaseSecurityHandler.loadLoginData(DatabaseSecurityHandler.java:157)
       at
com.recruiter.portal.DatabaseSecurityHandlerTest.testDatabase(DatabaseSecurityHandlerTest.java:314)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at junit.framework.TestCase.runTest(TestCase.java:154)

It was my fault of course since I didn't provide an appropriate method in my
bean class.  (descriptor.getWriteMethod() was null)

However, it is easer to debug if we add another catch statement in
BeanMapper.java.

Enclosed you will find a changed BeanMapper.java version. Could it be part of
the next jDBI release?

Kind regards

 Rainer


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email