Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Hibernate Set вместо List, Хороший тон в программировании 
:(
    Опции темы
eugeneu
  Дата 4.4.2011, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 25.3.2011

Репутация: нет
Всего: нет



Здравствуйте. Недавно стал использовать Hibernate3 в связке со Spring 3 в своем проекте.
Я использую аннотации для указания связей между сущностями и каждый раз делаю lazy initialization дабы не тянуть лишний раз данные. А если же они нужны то я делаю специальный HQL-запрос.
Рассмотрим следующий пример:


Имеется сущность "Сотрудник"
Код

@Entity
@Table(name = "employees")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "employee_id", nullable = false)
    private Long employeeId;

    @Column(name = "login", nullable = false)
    private String login;

    
    @ManyToMany(cascade = CascadeType.ALL,targetEntity=Authority.class, fetch=FetchType.LAZY)
    @JoinTable(name = "granted_authorities",  joinColumns = { @JoinColumn(name = "employee_id") },
               inverseJoinColumns = { @JoinColumn(name = "authority_id")})
    private List<Authority> authorities;


    public Employee() {
    }


    public Long getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(Long employeeId) {
        this.employeeId = employeeId;
    }

     

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }


    public List<Authority> getAuthorities() {
        
      
        return authorities;

    }

    public void setAuthorities(List<Authority> authorities) {

        this.authorities = authorities;

    }


}


Имеется сущность - "Разрешение"

Код

@Entity
@Table(name = "authorities")
public class Authority {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long authorityId;

    @Column(name = "name", nullable = false)
    private String authority;

    public String getAuthority() {
        return authority;
    }

    public void setAuthority(String authority) {
        this.authority = authority;
    }

    public Long getAuthorityId() {
        return authorityId;
    }

    public void setAuthorityId(Long authorityId) {
        this.authorityId = authorityId;
    }

}


Далее есть метод в котором я собственно получаю данные через HQL запрос:

Код

class EmployeeDAOImpl {

    public Employee getAuthorities(String login) throws HibernateException {
                
        Query query = sessionFactory.getCurrentSession().createQuery("from Employee e left join fetch e.authorities where e.login = ?");
        query.setString(0, login);
        
        List<Employee> employeeList = query.list();
        
        return employeeList.get(0);
    
    }
}


Много раз слышал, что получение List<> сущностей не есть хороший тон программирования - а хорошим тоном является получения Set<>.
Посути мне List не нужен - достаточно получить Set<Employee>.
Но не понятно как через HQL-запрос получить Set<Employee>, не брибегая к преобразованию List в Set.
Подскажите пожалуйста. заранее спасибо. 


Это сообщение отредактировал(а) eugeneu - 4.4.2011, 18:35
PM MAIL   Вверх
tux
Дата 4.4.2011, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 74
Всего: 132



eugeneu, никак нельзя. В результатах запроса могут быть дубликаты, которые могут быть нужны приложению, поэтому org.hibernate.Query поддерживает только возврат списка. Возможно было бы полезным иметь какой-то convenient метод, который возвращал бы Set, но ведь преобразовать легко и самому:
Код

Set<Employee> employeeList = new HashSet(query.list());


PM MAIL Skype GTalk Jabber YIM   Вверх
Samotnik
Дата 4.4.2011, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Цитата(eugeneu @  4.4.2011,  18:32 Найти цитируемый пост)
Много раз слышал, что получение List<> сущностей не есть хороший тон программирования - а хорошим тоном является получения Set<>.

оригинально, а немного обоснования можно почему, чтобы это не выглядело голословно ? smile 
PM MAIL   Вверх
Старовъръ
Дата 4.4.2011, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.5.2008

Репутация: 1
Всего: 10



Наоборот, работа с Set подразумевает много сложностей, связанных с реализацией equals() & hashCode(), так что я бы советовал везде использовать List вместо Set.
PM MAIL WWW   Вверх
dobrolub
Дата 4.4.2011, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 385
Регистрация: 18.12.2009
Где: Vancouver, Canada

Репутация: 4
Всего: 16



Set – подразумевает уникальность каждого елемента.
PM   Вверх
Samotnik
Дата 4.4.2011, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



dobrolubСтаровъръ, в этом то и дело, на мой взгляд, утверждение:
Цитата(eugeneu @  4.4.2011,  18:32 Найти цитируемый пост)
получение List<> сущностей не есть хороший тон программирования - а хорошим тоном является получения Set<>

не совсем верно, потому что, это зависит от конкретной задачи. Когда нужен List, а когда Set.
PM MAIL   Вверх
dobrolub
Дата 4.4.2011, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 385
Регистрация: 18.12.2009
Где: Vancouver, Canada

Репутация: 4
Всего: 16



Конечно. Set, например, подразумевает неупорядоченность элементов. В то время как List – упорядоченность. Тип должен улучшать читаемость программы, имно.

Это сообщение отредактировал(а) dobrolub - 4.4.2011, 22:41
PM   Вверх
eugeneu
Дата 5.4.2011, 06:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 25.3.2011

Репутация: нет
Всего: нет



Постараюсь аргументировать...
В данном примере у "Сотрудника" может быть набор ролей - каждая из которых уникальна, если отслеживать уникальность "Ролей" при добавлении их "Сотруднику" то дубликатов быть не должно...
Если использовать List то мы тратим память на порядок записи в списке, а в данном случае это не требуется, достаточно просто получить массив. 
Вы правы в некоторых случаях действительно нужен List когда нужен порядок записей - в этом случае и буду использовать HQL.
Но если уйти от CreateQuery с HQL то как можно принудительно инициализовать набор "Разрешений" для "Сотрудника" получив при этом Set?

PM MAIL   Вверх
emmanuil
Дата 5.4.2011, 08:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 380
Регистрация: 9.1.2007

Репутация: нет
Всего: 3



Немного отойду от темы.
eugeneu, в вашем примере, лучше возвращать unique, а не список, при получении Employee, так как логин уникальный.
Я в основном маппинг делаю через файл, замапьте authorities через set и хибер вернет вам set. Или если через аннотации, то укажите тип Set<>, должен вернуть set.
Еще чтобы получить set, можно у query через iterable и scroll самому вставлять объекты в свою коллекцию.
И еще у хибера есть класс Hibernate или HibernateUtils, в нем должен быть метод initialize, который инициализирует lazy свойства, если я не спутал.


Это сообщение отредактировал(а) emmanuil - 5.4.2011, 08:27
PM MAIL   Вверх
eugeneu
Дата 5.4.2011, 09:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 25.3.2011

Репутация: нет
Всего: нет



Спасибо, попробую!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0782 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.