1

このタイトルで見つけた他の質問はすべて、非 SELECT クエリを扱っています。Java 8、Sql2o 1.5.4、および postgresql 9.5.3 を使用しています。

私の UserService は次のようになります。

public class UserService {
    private final PGService pgService;

    public UserService(PGService _pgs) {
        this.pgService = _pgs;
    }

    public User getUserById(int id) {
        String sql = "SELECT id, firstname, lastname, email, team_id teamId FROM users WHERE id = :id;--";
        User user;
        try (Connection c = pgService.getConnection()) {
            user = c.createQuery(sql)
                    .addParameter("id", id)
                    .executeAndFetchFirst(User.class);
        }
        return user;
    }
}

私のユーザーは次のようになります。

public class User {
    private int id;
    private String firstname;
    private String lastname;
    private String email;
    private String passhash;
    private int teamId;
    /*getters and setters*/
}

私のテストは次のようになります。

public class UserServiceTest {
    private static UserService service;

    @Before
    public void setUp() throws ConfigurationException, IOException {
        this.service = new UserService(new PGService());
    }

    @Test
    public void returnsBiffUser() {
        User biff = service.getUserById(3);
        assertTrue(biff != null && biff.getLastname() == "Biff");
    }
}

データベースに対して SQL を直接実行すると、予想されるレコードが取得されます。この場合、team_id は NULL です。

テストを実行すると、次の例外が発生します。

org.sql2o.Sql2oException: Database error: No results were returned by the query.

    at org.sql2o.Query$ResultSetIterableBase.<init>(Query.java:332)
    at org.sql2o.Query$10.<init>(Query.java:412)
    at org.sql2o.Query.executeAndFetchLazy(Query.java:412)
    at org.sql2o.Query.executeAndFetchFirst(Query.java:480)
    at org.sql2o.Query.executeAndFetchFirst(Query.java:469)
    at services.UserService.getUserById(UserService.java:24)
    at services.UserServiceTest.returnsBiffUser(UserServiceTest.java:25)
Caused by: org.postgresql.util.PSQLException: No results were returned by the query.
    at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:115)
    at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83)
    at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83)
    at org.sql2o.Query$ResultSetIterableBase.<init>(Query.java:328)

なぜこうなった?どうすれば修正できますか?私の PGService テストはパスしており、DBCP2 BasicDataSource から作成されています。詳細が必要な場合はお知らせください。

4

1 に答える 1

2

問題は UserService ではなく、私の PGService クラスにありました。どれが:

public class PGService {
    private final Sql2o connectionPool;

    public PGService() throws ConfigurationException, IOException {
        Config cfg = loadConfig("dbconfig.json");
        if (cfg == null) {
            throw new ConfigurationException("Could not load dbconfig.");
        }
        BasicDataSource bds = new BasicDataSource();
        bds.setUsername(cfg.getUsername());
        bds.setPassword(cfg.getPassword());
        bds.setDriverClassName("org.postgresql.Driver");
        bds.setUrl(cfg.getUrl());
        bds.setInitialSize(1);
        connectionPool = new Sql2o(bds);
    }

    public Connection getConnection() {
        return this.connectionPool.open();
    }
}

Sql2o Google グループからの以下の修正と説明は、私の問題を修正し、postgres 使用時の RETURNING 構文に関するエラーに密接に関連しています。

「RETURNING またはその付近の構文エラー」は、sql2o がデータベースで自動生成されたキーを処理する方法と、postgres jdbc ドライバーとの間の非互換性が原因で発生します。postgres を使用している場合、db にキーが生成されたかどうかを sql2o がチェックするときに、その例外がスローされます。解決策は、キーが生成されることを明示的に期待する場合を除いて、キーをチェックしないことです。

これは、PostgresQuirks クラスによって sql2o で処理されます。そのため、Sql2o インスタンスを作成するときは、Quriks インスタンスをパラメーターとして受け取るコンストラクター オーバーロードの 1 つを使用します。

Sql2o sql2o = new Sql2o(bds, new PostgresQuirks());

それはそれを修正する必要があります!また、クエリの後の「--」を必ず削除してください。

とにかく、これが将来この問題に遭遇した人に役立つことを願っています.

乾杯。

于 2016-06-11T16:59:59.720 に答える