【问题标题】:Joining classes in ORMLite for Android throws SQL exception: could not find a foreign class or vice versa在 ORMLite for Android 中加入类会引发 SQL 异常:找不到外部类,反之亦然
【发布时间】:2014-04-22 14:35:49
【问题描述】:

我正在尝试使用 QueryBuilder 为两个不同的类创建一个连接查询,一个 Product 类和一个 Coupon 类,它引用了一个 Product 属性,storeId

public class Coupon {

    @DatabaseField(columnName = TableColumns.PRODUCT, foreign = true, foreignColumnName = Product.TableColumns.STOREID)
    private Product product;
}


public class Product {

    @DatabaseField(columnName = TableColumns.ID, generatedId = true)
    private Integer id;

    @DatabaseField(columnName = TableColumns.STOREID, index = true, unique = true)
    private Integer storeId;
}

我需要根据产品storeId获取优惠券列表。

public static List<Coupon> getByProduct(Product product) throws SQLException {
    QueryBuilder<Coupon, String> couponBuilder = dao.queryBuilder();
    QueryBuilder<Product, Integer> productBuilder = Product.dao.queryBuilder();     
    productBuilder.where().eq(Product.TableColumns.STOREID, product.getStoreId());
    return couponBuilder.join(productBuilder).query();
}

此查询引发 SQL 异常:

04-22 11:26:08.058: W/System.err(19479): java.sql.SQLException: Could not find a foreign class com.cde.express.mccopa.model.Coupon field in class com.cde.express.mccopa.model.Product or vice versa

04-22 11:26:08.059: W/System.err(19479):    at com.j256.ormlite.stmt.QueryBuilder.matchJoinedFields(QueryBuilder.java:554)

04-22 11:26:08.059: W/System.err(19479):    at com.j256.ormlite.stmt.QueryBuilder.addJoinInfo(QueryBuilder.java:525)

04-22 11:26:08.059: W/System.err(19479):    at com.j256.ormlite.stmt.QueryBuilder.join(QueryBuilder.java:316)

异常说我的类与外部字段无关,但 Coupon 类具有外部 Product 属性,并已正确注释。我已经检查了数据库,表中的值是正确的。

我该如何解决?

【问题讨论】:

  • 不,我不知道。

标签: java android sql ormlite


【解决方案1】:

查看QueryBuilder.java里面的代码

       for (FieldType fieldType : tableInfo.getFieldTypes()) {
            // if this is a foreign field and its foreign-id field is the same as the other's id
            FieldType foreignIdField = fieldType.getForeignIdField();
            if (fieldType.isForeign() && foreignIdField.equals(joinedQueryBuilder.tableInfo.getIdField())) {
                joinInfo.localField = fieldType;
                joinInfo.remoteField = foreignIdField;
                return;
            }
        }
        // if this other field is a foreign field and its foreign-id field is our id
        for (FieldType fieldType : joinedQueryBuilder.tableInfo.getFieldTypes()) {
            if (fieldType.isForeign() && fieldType.getForeignIdField().equals(idField)) {
                joinInfo.localField = idField;
                joinInfo.remoteField = fieldType;
                return;
            }
        }

上面指出,如果您想使用 QueryBuilder 进行连接,则需要确保在 id 字段上加入连接,所以在我看来,这就像 orm-lite 中 QueryBuilder.java 的限制。如果您已经提出Coupon.java 中作为 id 的外键会起作用。

一种快速的解决方法应该是使用原始查询字符串来实现您想要的。

例如——

final GenericRawResults<Coupon> results = couponDao.queryRaw("SELECT "
                + "product_table.product_id AS id, "
                + "product_table.store_id AS storeId "
                + " FROM coupon_table "
                + "JOIN product_table ON coupon_table.store_id = product_table.store_id "
                + "WHERE product_table.store_id = 1", new RawRowMapper<Coupon>() {

                    @Override
                    public Coupon mapRow(String[] columnNames, String[] resultColumns) throws SQLException {
                        final Integer productId = Integer.parseInt(resultColumns[0]);
                        final Integer storeId = Integer.parseInt(resultColumns[1]);

                        final Product product = new Product();
                        product.setId(productId);
                        product.setStoreId(storeId);

                        final Coupon coupon = new Coupon();
                        coupon.setProduct(product);
                        return coupon;
                    }

                });

            final Coupon coupon = results.getResults().get(0);
            final Product product = coupon.getProduct();
            System.out.println("Product id is " + product.getId() + " , Store id is " + product.getStoreId());

【讨论】:

    猜你喜欢
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 2014-05-11
    相关资源
    最近更新 更多