六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 206|回复: 0

spring jdbctemplate 实体属性映射值为null

[复制链接]

升级  29.33%

24

主题

24

主题

24

主题

秀才

Rank: 2

积分
94
 楼主| 发表于 2013-1-14 23:03:57 | 显示全部楼层 |阅读模式
今天在做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;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     */    private String underscoreName(String name) {        StringBuffer result = new StringBuffer();        if (name != null && name.length() > 0) {            //把第一个字母小写了            result.append(name.substring(0, 1).toLowerCase());            for (int i = 1; i < name.length(); i++) {                //获取第二个字母                String s = name.substring(i, i + 1);                //如果第二个字母是大写的                if (s.equals(s.toUpperCase())) {                    //给他添加下划线                    result.append("_");                    //然后加上第三个小写字母                    result.append(s.toLowerCase());                } else {                    //或者直接返回                    result.append(s);                }            }        }        return result.toString();    } 
 
执行完这段代码发现.
 
CPicPath被替换成了c_pic_path
T_CurTag被替换成了t_cur_tag和tcurtag
但是却没有一个和tCurTag替换出来的属性一样.所以实体的这个属性最终没有set到值
不知道我说的对不....个人理解.因为spring的有段源码实在看不懂..只能瞎猜了.
具体的原因是因为字段的下划线.所以在获取方法.根据set方法设置属性的时候发生了错位.造成set值失败
太晚了..有时间再详细研究...
总的来说就是下划线造成的.
 
我艹...讨厌的下划线
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表