NutzCN Logo
问答 使用dao的fetchLinks一个奇怪的问题,查询出来的关联对象始终是空
发布于 2567天前 作者 cranehe 2040 次浏览 复制 上一个帖子 下一个帖子
标签:

在使用dao的fetchLinks做关联查询时候出现一个奇怪的问题,查询出来的关联对象始终是空,看日志里面关联的sql也执行了,而且单测sql是有数据的,一下是bean和service的代码:

Bean代码

@Table("doc_main")
public class Doc implements Serializable {

    private static final long serialVersionUID = -5226898588012567299L;

    @Name
    private String c_id;

    @Column("vc_title")
    private String title;

    @Column("c_parentid")
    private String type;

    @Column("c_createrid")
    private String creatorId;

    @Column("dt_createtime")
    private String createTime;

    @Column("c_isatt")
    private String hasAttach;

    /**
     * 文档相关附件
     */
    @Many(field = "docId", target = DocAttach.class)
    private List<DocAttach> docAttaches = new LinkedList<>();
....
}
@Table("doc_att")
public class DocAttach  implements Serializable {

    private static final long serialVersionUID = 5579089003216427936L;
    @Name
    private String c_id;

    @Column("vc_sname")
    private String name;

    @Column("vc_rname")
    private String realName;

    @Column("vc_type")
    private String type;

    @Column("i_filesize")
    private Long size;

    @Column("c_docid")
    private String docId;

    @Column("c_year")
    private String year;

    @Column("c_month")
    private String month;

    @Column("c_day")
    private String day;
...
}

Service代码片段

... 
Condition cnd = Cnd.where(typesGroup).and(dateStartGroup).and(dateEndGroup).desc("dt_createtime");

        Pager pager = primaryDao.createPager(pageNumber, pageSize);
        List<Doc> docs = primaryDao.query(Doc.class, cnd, pager);
        primaryDao.fetchLinks(docs,"docAttaches");
...

以上逻辑始终无法取到Doc中的DocAttach数据,list的size始终是0,nutz版本1.r.63

23 回复

连错数据库了吧

库是对的,Doc对象是有数据的

debug日志也是ok

2017-12-12 10:46:24,962 DEBUG [org.nutz.ioc.impl.NutIoc] - <Get 'primaryDao'<interface org.nutz.dao.Dao>>
2017-12-12 10:46:24,964 DEBUG [org.nutz.ioc.aop.SimpleAopMaker] - <Load AopConfigure for anno=org.nutz.ioc.aop.Aop by type=org.nutz.ioc.aop.config.impl.AnnotationAopConfigration>
2017-12-12 10:46:24,965 DEBUG [org.nutz.ioc.impl.NutIoc] - <	 >> Load definition name=primaryDao>
2017-12-12 10:46:24,965 DEBUG [org.nutz.ioc.loader.map.MapLoader] - <Loading define for name=primaryDao>
2017-12-12 10:46:24,969 DEBUG [org.nutz.ioc.loader.combo.ComboIocLoader] - <Found IocObject(primaryDao) in JsonLoader(paths=[config/dao.js])>
2017-12-12 10:46:24,969 DEBUG [org.nutz.ioc.impl.NutIoc] - <	 >> Make...'primaryDao'<interface org.nutz.dao.Dao>>
2017-12-12 10:46:24,969 DEBUG [org.nutz.ioc.impl.ScopeContext] - <Save object 'primaryDao' to [app] >
2017-12-12 10:46:24,971 DEBUG [org.nutz.ioc.impl.NutIoc] - <Get 'primaryDataSource'<>>
2017-12-12 10:46:24,971 DEBUG [org.nutz.ioc.impl.NutIoc] - <	 >> Load definition name=primaryDataSource>
2017-12-12 10:46:24,971 DEBUG [org.nutz.ioc.loader.map.MapLoader] - <Loading define for name=primaryDataSource>
2017-12-12 10:46:24,978 DEBUG [org.nutz.ioc.loader.combo.ComboIocLoader] - <Found IocObject(primaryDataSource) in JsonLoader(paths=[config/dao.js])>
2017-12-12 10:46:24,978 DEBUG [org.nutz.ioc.impl.NutIoc] - <	 >> Make...'primaryDataSource'<>>
2017-12-12 10:46:24,978 DEBUG [org.nutz.ioc.impl.ScopeContext] - <Save object 'primaryDataSource' to [app] >
2017-12-12 10:46:24,979 DEBUG [org.nutz.ioc.aop.impl.DefaultMirrorFactory] - <Load class org.apache.commons.dbcp.BasicDataSource without AOP>
2017-12-12 10:46:25,057 DEBUG [org.nutz.ioc.aop.impl.DefaultMirrorFactory] - <Load class org.nutz.dao.impl.NutDao without AOP>
2017-12-12 10:46:25,057 DEBUG [org.nutz.ioc.impl.NutIoc] - <Get 'primaryDataSource'<>>
2017-12-12 10:46:25,473 DEBUG [org.nutz.dao.jdbc.Jdbcs] - <Jdbcs init complete>
2017-12-12 10:46:25,473 INFO [org.nutz.dao.jdbc.Jdbcs] - <Get Connection from DataSource for JdbcExpert, if you lock at here, check your database server and configure>
2017-12-12 10:46:27,211 DEBUG [org.nutz.dao.impl.DaoSupport] - <select expert : org.nutz.dao.impl.jdbc.oracle.OracleJdbcExpert>
2017-12-12 10:46:27,387 DEBUG [org.nutz.dao.impl.DaoSupport] - <JDBC Driver --> 9.2.0.3.0>
2017-12-12 10:46:27,387 DEBUG [org.nutz.dao.impl.DaoSupport] - <JDBC Name   --> Oracle JDBC driver>
2017-12-12 10:46:27,387 DEBUG [org.nutz.dao.impl.DaoSupport] - <JDBC URL    --> jdbc:oracle:thin:@hehebaiy.kmdns.net:1521:orcl>
2017-12-12 10:46:27,387 DEBUG [org.nutz.dao.impl.DaoSupport] - <Database info --> ORACLE:[Oracle - Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options]>
2017-12-12 10:46:28,015 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM (SELECT T.*, ROWNUM RN FROM ( SELECT * FROM doc_main  WHERE (c_parentid IN (007)) AND (dt_createtime >= ?) AND (dt_createtime <= ?) ORDER BY dt_createtime DESC  ) T WHERE ROWNUM <= 10) WHERE RN > 0 
    |          1 |          2 |
    |------------|------------|
    | 2016-01-01 | 2017-12-01 |
  For example:> "SELECT * FROM (SELECT T.*, ROWNUM RN FROM ( SELECT * FROM doc_main  WHERE (c_parentid IN (007)) AND (dt_createtime >= '2016-01-01') AND (dt_createtime <= '2017-12-01') ORDER BY dt_createtime DESC  ) T WHERE ROWNUM <= 10) WHERE RN > 0 ">
2017-12-12 10:46:28,289 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>
2017-12-12 10:46:28,477 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM doc_att  WHERE c_docid=?
    |                                    1 |
    |--------------------------------------|
    | 2460b728-4931-4cbf-947c-edcca3a8839f |
  For example:> "SELECT * FROM doc_att  WHERE c_docid='2460b728-4931-4cbf-947c-edcca3a8839f'">
2017-12-12 10:46:28,638 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>
2017-12-12 10:46:29,010 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM doc_att  WHERE c_docid=?
    |                                    1 |
    |--------------------------------------|
    | 1640be0e-4d02-47bf-95cd-81c8ea20991c |
  For example:> "SELECT * FROM doc_att  WHERE c_docid='1640be0e-4d02-47bf-95cd-81c8ea20991c'">
2017-12-12 10:46:29,198 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>
2017-12-12 10:46:29,558 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM doc_att  WHERE c_docid=?
    |                                    1 |
    |--------------------------------------|
    | 18a10a19-e02a-40b0-8d46-6e4526c67cf4 |
  For example:> "SELECT * FROM doc_att  WHERE c_docid='18a10a19-e02a-40b0-8d46-6e4526c67cf4'">
2017-12-12 10:46:29,751 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>
2017-12-12 10:46:30,108 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM doc_att  WHERE c_docid=?
    |                                    1 |
    |--------------------------------------|
    | bf9a0078-9b42-4007-ae0d-8c43edb91777 |
  For example:> "SELECT * FROM doc_att  WHERE c_docid='bf9a0078-9b42-4007-ae0d-8c43edb91777'">
2017-12-12 10:46:30,281 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>
2017-12-12 10:46:30,639 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM doc_att  WHERE c_docid=?
    |                                    1 |
    |--------------------------------------|
    | 18c74b30-5455-4ce7-8994-74a377db9e75 |
  For example:> "SELECT * FROM doc_att  WHERE c_docid='18c74b30-5455-4ce7-8994-74a377db9e75'">
2017-12-12 10:46:30,831 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>
2017-12-12 10:46:31,225 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM doc_att  WHERE c_docid=?
    |                                    1 |
    |--------------------------------------|
    | dd25f7aa-ff2a-4dfd-8013-4c81bef226ef |
  For example:> "SELECT * FROM doc_att  WHERE c_docid='dd25f7aa-ff2a-4dfd-8013-4c81bef226ef'">
2017-12-12 10:46:31,397 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>
2017-12-12 10:46:31,758 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM doc_att  WHERE c_docid=?
    |                                    1 |
    |--------------------------------------|
    | a3bf9c71-f9c6-4687-8c15-f5f03833db33 |
  For example:> "SELECT * FROM doc_att  WHERE c_docid='a3bf9c71-f9c6-4687-8c15-f5f03833db33'">
2017-12-12 10:46:31,958 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>
2017-12-12 10:46:32,328 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM doc_att  WHERE c_docid=?
    |                                    1 |
    |--------------------------------------|
    | 3b634258-547a-4fd4-955c-fb8336ebe3f5 |
  For example:> "SELECT * FROM doc_att  WHERE c_docid='3b634258-547a-4fd4-955c-fb8336ebe3f5'">
2017-12-12 10:46:32,510 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>
2017-12-12 10:46:32,889 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM doc_att  WHERE c_docid=?
    |                                    1 |
    |--------------------------------------|
    | df82812e-8434-4980-b32d-3099c193f954 |
  For example:> "SELECT * FROM doc_att  WHERE c_docid='df82812e-8434-4980-b32d-3099c193f954'">
2017-12-12 10:46:33,098 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>
2017-12-12 10:46:33,489 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM doc_att  WHERE c_docid=?
    |                                    1 |
    |--------------------------------------|
    | e994bf8f-e631-4ded-b92d-02ecdf6a5790 |
  For example:> "SELECT * FROM doc_att  WHERE c_docid='e994bf8f-e631-4ded-b92d-02ecdf6a5790'">
2017-12-12 10:46:33,688 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>

别那么肯定,检查一下

表面看确实没有错误,但是跟进代码看到这样的错误

org.nutz.dao.DaoException: !Nutz SQL Error: 'SELECT * FROM doc_att  WHERE c_docid='
PreparedStatement: 
'SELECT * FROM doc_att  WHERE c_docid=?'
CaseMessage=ORA-01008: 并非所有变量都已绑定

感觉应该是关联的对象DocAttach的pojo必须包含数据库的全部字段,不然就会出现以上这个错误

还在debug看代码,追踪到最后jdbc那块,这里没有commit,难道跟这个有关系?

//org.nutz.dao.impl.sql.run
public void _runWithoutTransaction(DataSource dataSource, ConnCallback callback) {
        Connection conn = null;

        try {
            conn = this.selectDataSource((Transaction)null, dataSource, callback).getConnection();
            this.runCallback(conn, callback);
//这里始终没有commit,因为拿到的AutoCommit始终是true而没有能执行里面的conn.commit()
            if (!conn.getAutoCommit()) {
                conn.commit();
            }
        } catch (Exception var15) {
            try {
                if (conn != null) {
                    conn.rollback();
                }
            } catch (Exception var13) {
                ;
            }

            if (var15 instanceof DaoException) {
                throw (DaoException)var15;
            }

            throw new DaoException(var15);
        } finally {
            if (null != conn) {
                try {
                    conn.close();
                } catch (SQLException var14) {
                    if (log.isWarnEnabled()) {
                        log.warn("Fail to close connection!", var14);
                    }
                }
            }

        }

    }

select操作有啥commit不commit的。。。

需要用到的字段(包括关联字段)都是需要全部列出的

主表也要把所有数据库字段映射到pojo上?例如我这里的doc也要全部和数据库字段对应上?

话说,应该是debug一下setter方法,看看有没有调用,调用的参数是什么

问题定位到了,是子表doc_att的查询没有数据,单独查询这个表使用一下方法查询不到数据:

primaryDao.query(DocAttach.class, Cnd.where("docId","=", docId), null);

改成硬编码方式就可以:

primaryDao.query(DocAttach.class, Cnd.wrap("c_docid = '"+ docId+"'"), null);

是我用法不对?

docId是数字? 然后数据库里面是字符串?

不是数字,数据库和pojo都定义的字符串类型,所以才疑惑

传递的参数值也是字符串类型,是个uuid字符串

数据有空格或其他不可见字符吧

数据是同一个测试数据

b7e4374b-0b94-453e-9ef2-f08b69b55690

前后中间都没有空格,我再把nutz打印的sql贴出来看下吧,

# 使用wrap的sql日志
2017-12-12 15:21:00,491 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM doc_att  WHERE C_DOCID=?
    |                                    1 |
    |--------------------------------------|
    | b7e4374b-0b94-453e-9ef2-f08b69b55690 |
  For example:> "SELECT * FROM doc_att  WHERE C_DOCID='b7e4374b-0b94-453e-9ef2-f08b69b55690'">
2017-12-12 15:21:00,571 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>
2017-12-12 15:22:08,123 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM doc_att  WHERE c_docid = 'b7e4374b-0b94-453e-9ef2-f08b69b55690'>
2017-12-12 15:22:18,255 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>
# 使用where的sql日志
2017-12-12 15:25:52,578 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM oa_doc_att  WHERE c_docid=?
    |                                    1 |
    |--------------------------------------|
    | b7e4374b-0b94-453e-9ef2-f08b69b55690 |
  For example:> "SELECT * FROM oa_doc_att  WHERE c_docid='b7e4374b-0b94-453e-9ef2-f08b69b55690'">
2017-12-12 15:25:56,475 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>

请忽略表名,表名是我刚刚改成oa_doc_att的

primaryDao.query(DocAttach.class, Cnd.where("docId","=", ), null); // 查不出了? 

那我估计走jdbc也是一样的结果, 先来试一下自定义SQL出什么结果

List<Record> list = dao.execute(Sqls.queryRecord("SELECT * FROM oa_doc_att  WHERE c_docid=@id").setParam(id, docId)).getList(Record.class);

结果还是一样,啥都没有。。额~

2017-12-12 15:40:18,268 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM oa_doc_att  WHERE c_docid=?
    |                                    1 |
    |--------------------------------------|
    | b7e4374b-0b94-453e-9ef2-f08b69b55690 |
  For example:> "SELECT * FROM oa_doc_att  WHERE c_docid='b7e4374b-0b94-453e-9ef2-f08b69b55690'">
2017-12-12 15:40:21,467 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>

字段名和表名换成大写也是一样:

2017-12-12 15:41:33,039 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <SELECT * FROM oa_doc_att  WHERE C_DOCID=?
    |                                    1 |
    |--------------------------------------|
    | b7e4374b-0b94-453e-9ef2-f08b69b55690 |
  For example:> "SELECT * FROM oa_doc_att  WHERE C_DOCID='b7e4374b-0b94-453e-9ef2-f08b69b55690'">
2017-12-12 15:41:37,183 DEBUG [org.nutz.dao.impl.sql.run.NutDaoExecutor] - <...DONE>

想了想, 可以查出来,然后判断一下字符串嘛

List<XXX> list = dao.query(XXX.class, Cnd.where("c_docid", "like", "%9ef2-f08b69b55690"));
for (XXX en : list) {
    System.out.println(en.getDocId().equals("b7e4374b-0b94-453e-9ef2-f08b69b55690"));
}

感谢兽哥这么费心了,我已经把设计数据库的人鄙视了一下,是这样的,这个字段被设计成char类型,长度40,然而数据长度是36位,后面的4位被自动填充空格了,所以dao通过where比对时候出现了现在找不到的问题,但是我也奇怪wrap能找到?

原来是oracle的char, 这个坑遇过很多次

目前只能通过使用nutz的语法糖来变向填充一下它的空白了,填充在两个地方,查询调用的地方,还有就是set值的地方,这个坑啊。。。

Strings.alignLeft(原字符串, 总长度, 填充字符);
# 例如原来是 |b7e4374b-0b94-453e-9ef2-f08b69b55690| 填充后变为:|b7e4374b-0b94-453e-9ef2-f08b69b55690    |,多四个空格

再次感谢wendal的帮助!!!

添加回复
请先登陆
回到顶部