@Test
  public void testUtf8() throws Exception {
    Dao<Foo, Integer> dao = createDao(Foo.class, true);

    Foo foo = new Foo();
    foo.stringField = "اعصاب";
    assertEquals(1, dao.create(foo));

    QueryBuilder<Foo, Integer> qb = dao.queryBuilder();

    List<Foo> results =
        qb.where().like(Foo.STRING_COLUMN_NAME, '%' + foo.stringField + '%').query();
    assertNotNull(results);
    assertEquals(1, results.size());
    assertEquals(foo.id, results.get(0).id);
    assertEquals(foo.stringField, results.get(0).stringField);

    qb.reset();
    results =
        qb.where().like(Foo.STRING_COLUMN_NAME, new SelectArg('%' + foo.stringField + '%')).query();
    assertNotNull(results);
    assertEquals(1, results.size());
    assertEquals(foo.id, results.get(0).id);
    assertEquals(foo.stringField, results.get(0).stringField);
  }
  @Test
  public void testJoinTwoColumns() throws Exception {
    Dao<Foo, Integer> fooDao = createDao(Foo.class, true);
    Dao<StringColumnArg, Integer> scaDao = createDao(StringColumnArg.class, true);

    Foo foo1 = new Foo();
    foo1.val = 123213213;
    foo1.stringField = "stuff";
    fooDao.create(foo1);

    Foo foo2 = new Foo();
    foo2.stringField = "not stuff";
    fooDao.create(foo2);

    StringColumnArg sca1 = new StringColumnArg();
    sca1.str1 = foo1.stringField;
    scaDao.create(sca1);

    StringColumnArg sca2 = new StringColumnArg();
    sca2.str1 = foo2.stringField;
    scaDao.create(sca2);

    StringColumnArg sca3 = new StringColumnArg();
    sca3.str1 = "some other field";
    scaDao.create(sca3);

    QueryBuilder<Foo, Integer> fooQb = fooDao.queryBuilder();
    fooQb.where().eq(Foo.VAL_COLUMN_NAME, foo1.val);

    QueryBuilder<StringColumnArg, Integer> scaQb = scaDao.queryBuilder();
    scaQb.join(StringColumnArg.STR1_FIELD, Foo.STRING_COLUMN_NAME, fooQb);
    List<StringColumnArg> results = scaQb.query();
    assertNotNull(results);
    assertEquals(1, results.size());
    assertEquals(sca1.id, results.get(0).id);

    fooQb.reset();
    fooQb.where().eq(Foo.VAL_COLUMN_NAME, foo2.val);

    scaQb.reset();
    scaQb.join(StringColumnArg.STR1_FIELD, Foo.STRING_COLUMN_NAME, fooQb);
    results = scaQb.query();
    assertNotNull(results);
    assertEquals(1, results.size());
    assertEquals(sca2.id, results.get(0).id);
  }
  @Test
  public void testQueryRawMax() throws Exception {
    Dao<Foo, Object> dao = createDao(Foo.class, true);

    Foo foo1 = new Foo();
    foo1.stringField = "1";
    foo1.val = 10;
    assertEquals(1, dao.create(foo1));
    Foo foo2 = new Foo();
    foo2.stringField = "1";
    foo2.val = 20;
    assertEquals(1, dao.create(foo2));
    Foo foo3 = new Foo();
    foo3.stringField = "2";
    foo3.val = 30;
    assertEquals(1, dao.create(foo3));
    Foo foo4 = new Foo();
    foo4.stringField = "2";
    foo4.val = 40;
    assertEquals(1, dao.create(foo4));

    QueryBuilder<Foo, Object> qb = dao.queryBuilder();
    qb.selectRaw("string, max(val) as val");
    qb.groupBy(Foo.STRING_COLUMN_NAME);
    GenericRawResults<Foo> results =
        dao.queryRaw(qb.prepareStatementString(), dao.getRawRowMapper());
    assertNotNull(results);
    CloseableIterator<Foo> iterator = results.closeableIterator();
    try {
      assertTrue(iterator.hasNext());
      assertEquals(foo2.val, iterator.next().val);
      assertTrue(iterator.hasNext());
      assertEquals(foo4.val, iterator.next().val);
      assertFalse(iterator.hasNext());
    } finally {
      iterator.close();
    }
  }
  @Test
  public void testLeftJoinTwoColumns() throws Exception {
    Dao<Foo, Integer> fooDao = createDao(Foo.class, true);
    Dao<StringColumnArg, Integer> scaDao = createDao(StringColumnArg.class, true);

    Foo foo1 = new Foo();
    foo1.val = 123213213;
    foo1.stringField = "stuff";
    fooDao.create(foo1);

    StringColumnArg sca1 = new StringColumnArg();
    sca1.str1 = foo1.stringField;
    scaDao.create(sca1);

    StringColumnArg sca2 = new StringColumnArg();
    sca2.str1 = "something eles";
    scaDao.create(sca2);

    QueryBuilder<Foo, Integer> fooQb = fooDao.queryBuilder();
    QueryBuilder<StringColumnArg, Integer> scaQb = scaDao.queryBuilder();
    scaQb.join(StringColumnArg.STR1_FIELD, Foo.STRING_COLUMN_NAME, fooQb);
    List<StringColumnArg> results = scaQb.query();
    assertNotNull(results);
    assertEquals(1, results.size());
    assertEquals(sca1.id, results.get(0).id);

    scaQb.reset();
    scaQb.join(
        StringColumnArg.STR1_FIELD,
        Foo.STRING_COLUMN_NAME,
        fooQb,
        JoinType.LEFT,
        JoinWhereOperation.AND);
    results = scaQb.query();
    assertNotNull(results);
    assertEquals(2, results.size());
    assertEquals(sca1.id, results.get(0).id);
    assertEquals(sca2.id, results.get(1).id);
  }