Не удается получить доступ к отложенной аннотированной, но инициализированной коллекции гибернации из JSF2 - PullRequest
2 голосов
/ 11 июля 2010

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

Hibernate.initialize(artist.getEvents());

. Тест в чистом Java работает нормально, и я могу получить доступ к событиям и его свойствам впоследствии.

Но на странице .xhtml, представляющей результат, я могу получить доступ только к свойствам художника и проверить, доступны ли какие-либо события, Artist - это базовый компонент, getData () возвращает Artist, следующая строка все еще работает:

<h:outputText value="No events available" rendered="#{empty artist.data.events}"/>

Но когда я хочу получить доступ к свойствам событий в таблице данных, используя

<h:dataTable value="#{artist.data.events}" var="event" rendered="#{not empty artist.data.events}">
  <h:column>
    <h:outputText value="#{event.title}"/>
  </h:column>
</h:dataTable>

, я получаю исключение followig:

/artist.xhtml @48,63 value="#{event.title}": The class 'org.hibernate.collection.PersistentSet' does not have the property 'title'.

Сначала я подумал, что HibernateМетод initialize не работает вместе с JSF2, но событие, когда я меняю FetchType с LAZY на EAGER, я получаю в результате того же результата.

Класс Event выглядит следующим образом, для краткости я включил только части, относящиеся к свойству title:

@Entity()
@Table(name="Events")
@SequenceGenerator(name="events_id", sequenceName="event_seq", initialValue=1, allocationSize=1)
public class EventData implements Serializable {

    private String title;
    // other private variables

    public EventData() {}

    public EventData(String title, ...) {
        this.title = title;
        // ...
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    // other setters/getters, equals/getHashCode overrides    

}

Ответы [ 2 ]

6 голосов
/ 11 июля 2010

UIData компоненты могут повторяться только для T[], List<E> или DataModel<E>, но не более Set<E>, поскольку невозможно идентифицировать элемент в Set<E> по index , в то время как это требуется в UIData компонентах.

@ Божо написал блог , описывающий один из способов его обхода. Другие способы - настроить JPA для использования List<E> вместо этого или добавить метод получения, который обернет его в List<E> или DataModel<E>, и использовать его вместо этого в UIData компоненте. Э.Г.

public DataModel<Event> getEventModel() {
    return new ArrayDataModel<Event>(events.toArray(new Event[events.size()]));
}

Это, кстати, использует одинаковые экземпляры (не копирует / не клонирует / воссоздает их), поэтому все изменения будут отражены в нужных экземплярах.


Обновление : в следующей версии JSF 2.2 UIData будет, наконец, поддерживать Collection<E>, что, таким образом, включает Set<E>. Другой способ - создать пользовательский распознаватель EL, ответив здесь: Как использовать java.util.Set с UIData в JSF. Конкретно ч: датируемый?

0 голосов
/ 11 июля 2010

Вуду необходимо выставить любой боб на объект # {...}.Самое простое - использовать CDI, если ваш веб-контейнер поддерживает его, но в противном случае посмотрите аннотацию @ManagedBean в JSF2.

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