2

これは私をとても困惑させました。何が起こっていたのかを理解するだけですが、他の人の助けになる場合に備えて、ドキュメンテーションについて自分の質問に答えます。

次のコードがあります。

MyClass.java

    public List<Integer> 
    getPersonIdsByPrograms(Collection<Integer> programIds, boolean getFirst) {
      String sql = "SELECT p.PERSON_ID FROM PERSON p " + 
                   "WHERE p.PROGRAM_ID in (?programIds)";
      sql = sql.replaceAll("\\?programIds", StringUtils.join(programIds, ","));
      Query query = entityManager.createNativeQuery(sql);

      //EntityManager returns scalar values, in this case, BigDecimal
      List<BigDecimal> queryResults = query.getResultList();

      // !! This is the toggle that makes or breaks the tests !!
      // !! !! UPDATE: Red herring. This had no impact.  See answer for why !! !!
      if (getFirst) {
        Object firstObj = queryResults.get(0); //This makes the test pass!?!
        //This is always true
        System.out.println("Is firstObj a BigDecimal? Answer: " 
               + (firstObj instanceof BigDecimal));
      }

      //Returns list of BigDecimal, so need to convert to Integer
      List<Integer> result = Lists.transform(queryResults, new Function<BigDecimal, Integer>() {
        public Integer apply(BigDecimal n) {
            return Integer.valueOf(n.intValue());
        }
    });
    return result;
}

警告 さて、ここで答えが出てきて、以下のテストを無効にします。最初のアサーションは合格し、2 番目のアサーションは失敗すると思っていました。これは事実ではありませんでした.最初のものはいくつかの状況で失敗しました.

MyClassTest.java

@Test
public void getPersonIdsByProgramsTest_BigDecimalOrInteger() {
    ArrayList<Integer> programs = Lists.newArrayList(131,141,161,162,0,113,110,26,5,28,50,58,51,29,121,31,101,41,27);
    List<?> personsByPrograms = userDao.getPersonIdsByPrograms(programs, true);
    TestingUtils.assertNotNullOrEmpty(personsByPrograms);
    Object shouldBeInteger = personsByPrograms.get(0);
    assertTrue(shouldBeInteger instanceof Integer);

    personsByPrograms = userDao.getPersonIdsByPrograms(programs, false);
    TestingUtils.assertNotNullOrEmpty(personsByPrograms);
    shouldBeInteger = personsByPrograms.get(0);
    assertTrue(shouldBeInteger instanceof Integer);
}
4

1 に答える 1

1

回答: データベースが異なれば、返されるスカラー型も異なる場合があります。

私の問題は、@RunWith(Parameterized.class)2 つの異なるデータベース (Oracle と MS SQL Server) に対して実行された単体テストを使用した結果でした。列がどのように定義されたかに関係している可能性があります (私は調べていません) が、基本的な要点は、データベースを切り替えるときに JPA がキャストする特定のオブジェクト型に依存できない可能性があるということです。安全を期すために、 と仮定したいだけかもしれませんList<? extends Number>

于 2012-09-14T17:25:01.553 に答える