У меня проблема с отображением полученных данных через JDBi3 с использованием запроса PostgreSQL в моем интерфейсе DAO. В моем приложении Dropwizard у меня есть класс Book DTO, который имеет отношение «многие ко многим» с классами Author и Category DTO и имеет проблему с отображением запрашиваемых строк в классе BookDTO. Вот фрагменты кода классов DTO:
class BookDTO {
private Long bookId;
// other fields are left for code brevity
private List<Long> authors;
private List<Long> categories;
// empty constructor + constructor with all fields excluding Lists + getters + setters
}
class AuthorDTO {
private Long authorId;
// other fields are left for code brevity
private List<Long> books;
// empty constructor + constructor with all fields excluding List + getters + setters
}
class CategoryDTO {
private Long categoryId;
// other fields are left for code brevity
private List<Long> books;
// empty constructor + constructor with all fields excluding List + getters + setters
}
... и поскольку я использую интерфейсы DAO JDBi3 для выполнения операций CRUD, мой метод запроса всех книг в базе данных выглядит следующим образом:
@Transaction
@UseRowMapper(BookDTOACMapper.class)
@SqlQuery("SELECT book.book_id AS b_id, book.title, book.price, book.amount, book.is_deleted, author.author_id AS aut_id, category.category_id AS cat_id FROM book " +
"LEFT JOIN author_book ON book.book_id = author_book.book_id " +
"LEFT JOIN author ON author_book.author_id = author.author_id " +
"LEFT JOIN category_book ON book.book_id = category_book.book_id " +
"LEFT JOIN category ON category_book.category_id = category.category_id ORDER BY b_id ASC, aut_id ASC, cat_id ASC")
List<BookDTO> getAllBooks();
... и это map
метод класса BookDTOACMapper
выглядит следующим образом:
public class BookDTOACMapper implements RowMapper<BookDTO> {
@Override
public BookDTO map(ResultSet rs, StatementContext ctx) throws SQLException {
final long bookId = rs.getLong("b_id");
// normally retrieving values by using appropriate rs.getXXX() methods
Set<Long> authorIds = new HashSet<>();
Set<Long> categoryIds = new HashSet<>();
long authorId = rs.getLong("aut_id");
if (authorId > 0) {
authorIds.add(authorId);
}
long categoryId = rs.getLong("cat_id");
if (categoryId > 0) {
categoryIds.add(categoryId);
}
while (rs.next()) {
if (rs.getLong("b_id") != bookId) {
break;
} else {
authorId = rs.getLong("aut_id");
if (authorId > 0) { authorIds.add(authorId); }
categoryId = rs.getLong("cat_id");
if (categoryId > 0) { categoryIds.add(categoryId); }
}
}
final List<Long> authorIdsList = new ArrayList<>(authorIds);
final List<Long> categoryIdsList = new ArrayList<>(categoryIds);
return new BookDTO(bookId, title, price, amount, is_deleted, authorIdsList, categoryIdsList);
}
}
Проблема, с которой я сталкиваюсь, заключается в том, что при вызове моего метода GET (определенного в классе Resource, который вызывает метод getAllBooks()
из BookDAO класс) отображает противоречивые результаты , а сам запрос возвращает правильные результаты .
Многие вопросы, которые мне удалось найти в Stackoverflow, официальном API Документов JDBi3 и Группах Google рассматриваем отношение один-ко-многим и используем аннотацию @UseRowReducer
, которая содержит класс, который реализует LinkedHashMapRowReducer<TypeOfEntityIdentifier, EntityName>
, но для этого случая я не смог найти способ его реализовать. Любой пример / предложение приветствуется. :) Заранее спасибо.
Версии подержанных инструментов : Фреймворк Dropwizard 1.3.8 PostgreSQL 11,7 Java8