выбор списка из объекта в JPA - PullRequest
1 голос
/ 18 января 2012

У меня есть объект, который содержит список из его полей, объект отображается в БД.Я пытаюсь создать запрос, который выберет несколько полей из объекта и упомянутого выше списка.

Отображение объекта:

@Entity
@Table(name="buys")
@PrimaryKeyJoinColumn(name="buy_id")
public class Buy extends DomainObject implements Serializable {

        @Column(name = "buy_name")
        private String buyName;

        @OneToMany( cascade = {CascadeType.PERSIST, CascadeType.MERGE})
        @JoinColumn(name="buy_id", referencedColumnName = "buy_id")
        private List<InsersionOrder> insertionOrders;

      //other fields omitted

}

Используемый мной запрос:

"select new com.dtos.domainObjects.BuyDTO(b.id, b.buyName, b.insertionOrders) from Buy b where b.buyGroupId = :groupId and b.isDeleted = false"

При выполнении этого спящего режима (мой поставщик JPA) генерирует ошибочный запрос:

Hibernate: select buy0_.buy_id as col_0_0_, buy0_.buy_name as col_1_0_, . as col_2_0_ from buys buy0_ inner join domain_objects buy0_1_ on buy0_.buy_id=buy0_1_.id inner join insertion_orders insertiono1_ on buy0_.buy_id=insertiono1_.buy_id inner join domain_objects insertiono1_1_ on insertiono1_.io_id=insertiono1_1_.id where buy0_.buy_group_id=? and buy0_1_.is_deleted=0

Поле InsertionOrder также наследуется от DomainObject.

Если я опускаю список и выбираю только «простые» поля из объекта Buy (т. Е. Id, name), запрос работает нормально.

Чего мне не хватает?

Спасибо.

1 Ответ

3 голосов
/ 18 января 2012

Этот синтаксис создает экземпляр BuyDTO из каждой строки набора результатов.Даже если бы это сработало, оно не вернуло бы то, что вы хотите вернуть.Поле коллекции не может быть частью предложения select запроса HQL.

Первое решение: не возвращать DTO, возвращать саму сущность.

Второе решение: выберите сущности и создайте экземпляры DTO самостоятельно:

select b from Buy b 
left join fetch b.insertionOrders i
where b.buyGroupId = :groupId and b.isDeleted = false

for (Buy b : list) {
    dtoList.add(new BuyDTO(b.getId(), b.getBuyName(), b.getInsertionOrders());
}

Третье решение: выберите то, что вы хотите, и соберите DTO самостоятельно:

select b.id, b.buyName, i 
from Buy b 
left join b.insertionOrders i
where b.buyGroupId = :groupId and b.isDeleted = false

В каждой строке результата вы найдете один идентификатор, одно buyName и один inserttionOrder.Таким образом, вам придется создать один DTO при первом знакомстве с новым идентификатором и добавить заказ к уже созданному DTO в следующий раз, когда вы встретите этот идентификатор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...