Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Аннотации в JPA?


Автор: oson 2.11.2012, 00:17
В примерах к книге PRO JPA 2 используются аннотации к полям 

Код

  @OneToMany(mappedBy = "department")
    private Collection<Employee> employees;

    public Department()
    {
        employees = new ArrayList<Employee>();
    }

 public void addEmployee(Employee employee)
    {
        if (!getEmployees().contains(employee))
        {
            getEmployees().add(employee);
            if (employee.getDepartment() != null)
            {
                employee.getDepartment().getEmployees().remove(employee);
            }
            employee.setDepartment(this);
        }
    }

    public Collection<Employee> getEmployees()
    {
        return employees;
    }


В примерах к Pro Spring 3 используются аннотации к getter
Код

 private Set<ContactTelDetail> contactTelDetails = new HashSet<ContactTelDetail>();
 @OneToMany(mappedBy = "contact", cascade = CascadeType.ALL, orphanRemoval = true)
    public Set<ContactTelDetail> getContactTelDetails()
    {
        return this.contactTelDetails;
    }


Что лучше использовать - аннотации к полям или к геттерам?
И нужно ли инициализировать Set или List - сам он не проинициализируется благодаря мэппингу?

Автор: Pawl 22.11.2012, 12:14
Цитата(oson @  2.11.2012,  00:17 Найти цитируемый пост)
Что лучше использовать - аннотации к полям или к геттерам?

точно не скажу, сам применял аннотации к полям - все получалось

Цитата(oson @  2.11.2012,  00:17 Найти цитируемый пост)
И нужно ли инициализировать Set или List - сам он не проинициализируется благодаря мэппингу?

сам он проинициализируется, только если в аннотации @OneToMany указать fetch = FetchType.EAGER

Автор: zhz 10.12.2012, 00:31
Согласно спецификации существуют два уровня доступа: доступ по полям(field access)  и доступ по методам(property access).   
пример field access :
Код

@Entity
public class MyEntity {
@Id @GeneratedValue
private Long id;

public Long getId() {....}
}

пример property access:
Код

@Entity
public class MyEntity {
private Long id;

@Id @GeneratedValue
public Long getId() {....}
}

приведенные сущности по сути полностью идентичны. Выбор уровня доступа зависит от предпочтения разработчика. многие используют proprty access считая код более читабельным.  
В спецификации сказано, что совместное использование property access и field access без явного указания уровня доступа недопустимо и может приводит к ошибкам.
При использовании доступа по полям, PersistenceProvider мапит все аттрибуты не помеченные аннотацией @Transient. Тоже самое, только наооборот. при сипользовании доступа по методам, - мапится по геттерам все, что не помечено @Transient.       
Явно уровень доступа можно указать используя аннотацию @javax.persistence.Access:
Код

@Entity
@Access(AccessType.FIELD) 
public class MyEntity {
.........
}

В данном случае мапится будет по полям, и аннотированные  методы будут проигнорированы при мапинге.

Автор: Старовъръ 11.12.2012, 22:02
Проблемы field access:
  • Доступ осуществляется к private членам класса, то бишь в некотором окружении это не допустимо, где конфигурируется строгий SecurityManager.
  • В перемешку с BeanValidation (а его аннотации в некоторых случаях просто нельзя устанавливать на поля), может получиться каша
  • Нет возможности переопределить какое-то поведение, возвращаемое значение. Такая необходимость правда редко возникает.
  • При вызове любого метода, прокси будет инициализироваться. В случае с property-access при вызове getId(), просто возвращается ID. В случае с field-access прокси инициализируется. Это может ударить по производительности в некоторых случаях.
Проблемы property access:
  • Намного сложней помещать какую-то бизнес логику в сущности. Например, свою валидацию, которая зависит от других полей. Когда Hibernate будет устанавливать эти свойства, он это будет делать в алфавитном порядке, соответственно зависимое свойство еще может быть не установлено.
  • Нет возможности возвращать к примеру Collections.unmodifiableCollection(), потому как при работе с Hibernate это приведет к проблемам с производительностью, а в некоторых случаях и просто к исключениям.
  • В двусторонней связи нельзя просто взять и в setXxx(Xxx xxx) устанавливать обратную сторону: xxx.setYyy(this). Поэтому приходится создавать package-private методы исключительно для Хиба, а обычные get-set используются в остальной части приложения.
Я лично предпочитая property-access за его всемогучесть, даже если придется что-то обойти, костыль всегда можно найти. В случае же с field access бывают ситуации, которые просто невозможно обойти (SecurityManager, BeanValidation, getId()).

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)