JHipster не использует lombok. Почему?

Первоначально опубликовано на renanfranca.github.io

После первого запуска генератора JHipster я понял, что back end, реализованный с помощью spring boot, не использует Lombok. Поэтому я решил настроить сгенерированный код на использование lombok, но потом понял, что это не лучший способ использования JHipster.

Настройка JHipster

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

  • Добавить Lombok — @lombok
  • Скрыть комментарий — @noCodeComment
  • Изменить схему базы данных — @schema
  • Добавить Id GeneratedValue к сущности — @generatedValue(identity)
  • Определить имя столбца базы данных — @column(ds_field)
  • Использовать неподдерживаемые типы — @newFieldTypeImport(import_class_package_type) и @newFieldType(type).

Я открыл исходный код моего чертежа, который настраивает код на стороне сервера:

  • generator-jhipster-custom-server-side-blueprint-private
  • Вот класс, который реализует эти опции пользовательских аннотаций: https://github.com/renanfranca/generator-jhipster-custom-server-side-blueprint-private/blob/custom-annotations-options/generators/entity/index.js.

Вот пример jdl файла, который использует мой blueprint:

@lombok  
@schema(MyProject)  
@noCodeComment 
entity RenanClasse (RenanOk) {  
@generatedValue(identity)  
id Long  
@column(ds_name)  
name String
@newFieldTypeImport(java_time_LocalDateTime)  
@newFieldType(LocalDateTime)  
birthday ZonedDateTime
}  

// Use Data Transfer Objects (DTO)  
dto * with mapstruct  

// Service layer  
service all with serviceClass  
Вход в полноэкранный режим Выход из полноэкранного режима

JHipster не использует Lombok

Я нашел проблему в проекте jhipster generated project, в которой перечислены причины, по которым не следует использовать lombok. Я процитирую некоторые из них:

  1. В одном проекте новая версия плагина Lombok вызвала крах IDE (я думаю, это был Intellij). Поэтому никто больше не мог работать.

  2. В другом проекте Lombok вызвал крах CI-сервера (и, вероятно, вызвал бы крах производственного сервера), поскольку он вызвал ошибку в JVM.

  3. В третьем проекте мы добились 30% прироста производительности за счет перекодирования equals/hashcode из Lombok.

  4. Что касается JHipster, то история такова, что мы не можем просить людей установить плагин на их IDE:

    • 1-я цель — это плавный опыт: вы создаете приложение, и оно работает в вашей IDE по умолчанию.

    • Вторая цель — чтобы вы могли использовать любую IDE, какую захотите. А у некоторых людей есть очень экзотические вещи, например, я только что попробовал https://codenvy.com/ -> для этого, конечно, нет плагина.

Реализация сущности

В следующем примере вы можете видеть, что JHipster реализует ручные sets и gets. Кроме того, вы можете видеть, что он реализует так называемый fluent метод, как я узнал из исходного кода генератора JHipster и из этого выпуска, где обсуждается реализация fluent setters в jhipster.

@Entity
@Table(name = "nap")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Nap implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
    @SequenceGenerator(name = "sequenceGenerator")
    @Column(name = "id")
    private Long id;

    @Column(name = "start")
    private ZonedDateTime start;

    @Column(name = "jhi_end")
    private ZonedDateTime end;

    @Enumerated(EnumType.STRING)
    @Column(name = "place")
    private Place place;

    @ManyToOne
    private BabyProfile babyProfile;

    @ManyToOne
    private Humor humor;

    // jhipster-needle-entity-add-field - JHipster will add fields here

    public Long getId() {
        return this.id;
    }

    public Nap id(Long id) {
        this.setId(id);
        return this;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public ZonedDateTime getStart() {
        return this.start;
    }

    public Nap start(ZonedDateTime start) {
        this.setStart(start);
        return this;
    }

    public void setStart(ZonedDateTime start) {
        this.start = start;
    }

    public ZonedDateTime getEnd() {
        return this.end;
    }

    public Nap end(ZonedDateTime end) {
        this.setEnd(end);
        return this;
    }

    public void setEnd(ZonedDateTime end) {
        this.end = end;
    }

    public Place getPlace() {
        return this.place;
    }

    public Nap place(Place place) {
        this.setPlace(place);
        return this;
    }

    public void setPlace(Place place) {
        this.place = place;
    }

    public BabyProfile getBabyProfile() {
        return this.babyProfile;
    }

    public void setBabyProfile(BabyProfile babyProfile) {
        this.babyProfile = babyProfile;
    }

    public Nap babyProfile(BabyProfile babyProfile) {
        this.setBabyProfile(babyProfile);
        return this;
    }

    public Humor getHumor() {
        return this.humor;
    }

    public void setHumor(Humor humor) {
        this.humor = humor;
    }

    public Nap humor(Humor humor) {
        this.setHumor(humor);
        return this;
    }

    // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Nap)) {
            return false;
        }
        return id != null && id.equals(((Nap) o).id);
    }

    @Override
    public int hashCode() {
        // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
        return getClass().hashCode();
    }

    // prettier-ignore
    @Override
    public String toString() {
        return "Nap{" +
            "id=" + getId() +
            ", start='" + getStart() + "'" +
            ", end='" + getEnd() + "'" +
            ", place='" + getPlace() + "'" +
            "}";
    }
}
Вход в полноэкранный режим Выход из полноэкранного режима

источник: Nap.java

Таким образом, вы можете создать этот объект, как при использовании паттерна builder, но он не является неизменяемым.

Nap nap = new Nap().id(1l).start(ZonedDateTime.now()).end(ZonedDateTime.now().plusHours(1));
Вход в полноэкранный режим Выход из полноэкранного режима

Мне понравилась эта реализация, и этого достаточно для того, чтобы мой код был менее многословным.

Это способ

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

Оцените статью
devanswers.ru
Добавить комментарий