日期:2014-05-16  浏览次数:20419 次

spring jdbctemplate 实体属性映射值为null

今天在做mysql和derby数据迁移的时候出现个问题.实体的某些属性经常获取不到值.总是为null

方法如下:

?

 public List<Test1> getTestAll() {
        String sql = "select * from Test";
        List<Test1> l = null;
        try {
            l = getSimpleJdbcTemplate().query(sql,
                    ParameterizedBeanPropertyRowMapper.newInstance(Test.class),
                    new Object[]{});
        } catch (DaoException e) {
            logger.error(e);
            throw e;
        }
        return l;
    }

?

?

?下图为test表的字段


?

?

下面是数据库对应的实体文件Test

?

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Column(name = "T_CurTag")
    private String tCurTag;
    @Column(name = "R_IsDel")
    private Integer rIsDel;
    @Column(name = "CPicPath")
    private String cPicPath;
    //get set方法省略...

?

实体文件使用hibernate jpa生成的

?

?

方法执行完毕之后.返回的list中取出实体对象test发现.

tCurTag,rIsDel值都为null.

很纳闷.自己瞅瞅几个字段区别也就在大小写和下划线了.

于是乎改了改.

数据库的字段变成了

T_Curtag,R_Isdel ? ? ? ? 正确

T_Cur_Tag,R_Is_Del ? ?正确

TCurTag,RIsDel ? ? ? ? ? ?正确

?

通过研究发现..java的命名规范还是有用的.

如果命名为

T_CurTag那么生成的属性就是tCurTag.通过看spring jdbctemplate的源码发现.

如果属性的名称不符合java的规范(还是jdbc的规范?)则会造成属性值映射失败的现象

?

首先根据这句

?

 ParameterizedBeanPropertyRowMapper.newInstance(Test1.class),

?

?查看其源码:

?

public static <T> ParameterizedBeanPropertyRowMapper<T> newInstance(Class<T> mappedClass) {
		ParameterizedBeanPropertyRowMapper<T> newInstance = new ParameterizedBeanPropertyRowMapper<T>();
		newInstance.setMappedClass(mappedClass);
		return newInstance;
	}
?

?

继续找这句

?

newInstance.setMappedClass(mappedClass);
?

?

?

?

         /**
	 * Set the class that each row should be mapped to.
	 */
	public void setMappedClass(Class mappedClass) {
		if (this.mappedClass == null) {
			initialize(mappedClass);
		}
		else {
			if (!this.mappedClass.equals(mappedClass)) {
				throw new InvalidDataAccessApiUsageException("The mapped class can not be reassigned to map to " +
						mappedClass + " since it is already providing mapping for " + this.mappedClass);
			}
		}
	}
?

?

然后是这句

?

initialize(mappedClass);

?

?找到这里.

?

?

/**
	 * Initialize the mapping metadata for the given class.
	 * @param mappedClass the mapped class.
	 */
	protected void initialize(Class mappedClass) {
		this.mappedClass = mappedClass;
		this.mappedFields = new HashMap();
		this.mappedProperties = new HashSet();
		PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(mappedClass);
		for (int i = 0; i < pds.length; i++) {
			PropertyDescriptor pd = pds[i];
			if (pd.getWriteMethod() != null) {
				this.mappedFields.put(pd.getName().toLowerCase(), pd);
				String underscoredName = underscoreName(pd.getName());
				if (!pd.getName().toLowerCase().equals(underscoredName)) {
					this.mappedFields.put(underscoredName, pd);
				}
				this.mappedProperties.add(pd.getName());
			}
		}
	}

?

?

终于找到关键代码:

?

?

    /**
     * Convert a name in camelCase to an underscored name in lower case.
     * Any upper case letters are converted to lower case with a preceding underscore.
     * @param name the string containing original name
     * @return the converted name
     */