2009-06-01 2 views
4

У меня возникли проблемы с получением спящего режима для возврата графа правильно заполненного объекта, когда в элементе содержится объединение во многих коллекциях.Hibernate - выбор по нескольким объединениям с коллекциями

Например:

String sql = "select distinct changeset " + 
      "from Changeset changeset " + 
      "join fetch changeset.changeEntries as changeEntry " + 
      "join fetch changeEntry.repositoryEntity as repositoryEntity " + 
      "join fetch repositoryEntity.repository as repository " + 
      "where repository.connectionName = :connectionName"; 
  • набор изменений имеет много ChangeEntries
  • ChangeEntry имеет один RepositoryEntity
  • RepositoryEntity имеет одно хранилище

выше оператор возвращает правильные данные, но граф объекта неправильно заполнен - ​​то есть, каждый набор изменений содержит каждое изменение и не только это собственные дети.

Вот соответствующие фрагменты этих двух классов:

public class Changeset { 

    @NotNull 
    @OneToMany(mappedBy="changeset", targetEntity=ChangeEntry.class, cascade={CascadeType.ALL }, fetch=FetchType.EAGER) 
    private Set<IChangeEntry> changeEntries; 

И ...

public class ChangeEntry { 

    @NotNull 
    @ManyToOne(targetEntity=Changeset.class) 
    @ForeignKey(name="FkChangeEntryChangeset") 
    private IScmChangeset changeset; 

    @NotNull 
    @ManyToOne(targetEntity=RepositoryEntity.class, cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
    @ForeignKey(name="FkChangeEntryRepoEntity") 
    private IRepositoryEntity repositoryEntity; 

Любая помощь очень ценится

С уважением

Marty

+0

Вы добавили информацию о сопоставлении для репозитория, а не для ChangeSet в ChangeEntry. – rudolfson

+0

Спасибо - я добавил Changeset –

ответ

1

Marty:

У меня была такая же проблема, и я не нашел подходящего решения. Вы можете использовать простые результирующих трансформаторы для управления количеством объектов, которые возвращаются:

CriteriaSpecification.ROOT_ENTITY 
CriteriaSpecification.DISTINCT_ROOT_ENTITY 

Но объекты всегда будут содержать полные результаты для своих детей. Я столкнулся с отличной статьей, в которой используется шаблон DTO вместе с проекциями и трансформатор aliasToBean.

Вот оно: http://swik.net/Hibernate/Hibernate+GroupBlog/Hibernate+3.2:+Transformers+for+HQL+and+SQL/cmxs

Это работает хорошо для меня. Самая большая проблема заключается в том, что вам нужно создавать эти сплющенные объекты DTO. Для меня это не так уж важно, потому что мои специализированные объекты DTO используются в результатах поиска и очень многократно используются, и мне не понадобятся многие из них.

Я знаю, что это напрямую не касается вашей проблемы, если вы найдете способ достижения своей цели, пожалуйста, обновите сообщение, как мне хотелось бы видеть решение.

0

Выполняет ли загрузка одного объекта по его идентификатору правильно? Если нет - читайте дальше. :-)

Я не уверен, что достаточно использовать @ForeignKey. Попробуйте добавить @JoinColumn во многие стороны вашего отношения. Например.

@NotNull 
@ManyToOne(targetEntity=RepositoryEntity.class, cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
@ForeignKey(name="FkChangeSet") 
@JoinColumn(name = "CHANGESET_ID", referencedColumnName = "ID") 
private Changeset changeset; 

Примечание: Я только что видел, что вы показываете информацию отображения для Repository, но я предполагаю, что один за Changeset похож.

+0

Спасибо за ответ ... да, загрузка одного объекта по его идентификатору действительно работает. @JoinColumn не обязательно, поскольку Hibernate может работать с targetEntity @ManyToOne. Аннотирование @ForeignKey существует только для того, чтобы дать иностранному ключу имя, поэтому я могу получить осмысленные ошибки, когда все пойдет наперекосяк (как это часто бывает! :) –

+0

Что касается @ForeignKey - вот что я догадался. Concering @JoinColumn - Вам не нужно указывать имя столбца внешнего ключа. Исходный столбец может быть разрешен из целевого объекта, это правильно. Но колонка внешнего ключа? – rudolfson

Смежные вопросы