Явный конструктор, использующий Lombok?

Я переписываю какой-то грязный код, который управляет базой данных, и увидел, что оригинальный программист создал класс, сопоставленный с базой данных, примерно так:

(Я удалил ненужный код, который не имеет смысла в этом вопросе)

@Entity
@Data
@EqualsAndHashCode(callSuper = false, of = { "accessionCode", "header", "date" })
@SuppressWarnings("PMD.UnusedPrivateField")
public class PDBEntry implements Serializable {
    @Id
    @NaturalId
    @NotEmpty
    @Length(max = 4)
    private String accessionCode;

    @NaturalId
    @NotEmpty
    private Date date;

    @NaturalId
    // We allow for the header to be 'null'
    private String header;

    private Boolean isValidDssp;

    @Temporal(TemporalType.TIMESTAMP)
    private Date lastUpdated = new Date(System.currentTimeMillis());

    protected PDBEntry(){}

    public PDBEntry(String accessionCode, String header, Date date){
        this.accessionCode = accessionCode;
        this.header = header;
        this.date = date;
    }
}

Я все еще новичок в Hibernate и использую Lombok, но разве это не сделает то же самое, и Lombok автоматически не создаст для вас нужный конструктор?

@Entity
@Data
@SuppressWarnings("PMD.UnusedPrivateField")
public class PDBEntry implements Serializable {
    @Id
    @NaturalId
    @NotEmpty
    @NonNull
    @Length(max = 4)
    private String accessionCode;

    @NaturalId
    @NotEmpty
    @NonNull
    private Date date;

    @NaturalId
    // We allow for the header to be 'null'
    private String header;

    private Boolean isValidDssp;

    @Temporal(TemporalType.TIMESTAMP)
    private Date lastUpdated = new Date(System.currentTimeMillis());
}

Кроме того, оригинальный программист этого кода говорит, что он допускает, чтобы заголовок был "нулевым", но он явно создал конструктор, которому нужно значение для заголовка. Я что-то упустил или это немного противоречиво?

4 ответа

Решение

Посмотри на @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor,

Поведение конструктора @Data как @RequiredArgsConstructor:

@RequiredArgsConstructor генерирует конструктор с 1 параметром для каждого поля, которое требует специальной обработки. Все конечные поля получают параметр, а также любые поля, помеченные как @NonNull, которые не инициализированы там, где они объявлены.

Учитывая, что ни одно из ваших полей не final или же @NonNull это приведет к появлению конструктора без аргументов. Однако это не самый выразительный способ добиться такого поведения.

В этом случае вы, вероятно, захотите @NoArgsConstructor (опционально в сочетании с @AllArgsConstructor), чтобы четко сообщить предполагаемое поведение, как также указано в документации:

Для некоторых конструкций Java, таких как hibernate и интерфейс Service Provider, требуется конструктор без аргументов. Эта аннотация полезна прежде всего в сочетании с @Data или одним из других конструкторов, генерирующих аннотации.

Если вы используете @Data с полем @NonNull и по-прежнему хотите использовать конструктор noargs, вы можете попробовать добавить все три аннотации вместе

@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor

Очевидно старая ошибка intelliJ, которую я повторил в Eclipse Kepler и lombok v0.11.4

Этот бит противоречив, вы правы. Я не использовал Lombok раньше, но с hibernate, если вы хотите иметь возможность создавать bean-компонент и сохранять его, вам нужен конструктор по умолчанию, как указано выше, насколько я знал. Он использует Constructor.newInstance() для создания новых объектов.

Вот некоторая документация гибернации, которая идет в более подробно.

Hibernate Документация

@NoArgsConstructor, 
@RequiredArgsConstructor, 
@AllArgsConstructor

Генерируйте конструкторы, которые не принимают аргументов, один аргумент в конечном / ненулевом поле или один аргумент для каждого поля. Читать этот ломбок-проект

@Data
@RequiredArgsConstructor /*Duplicate method Someclass() in type Someclass*/
@NoArgsConstructor(access=AccessLevel.PRIVATE, force=true)  /*Duplicate method Someclass() in type Someclass*/
@Entity
public class Someclass {      
    @Id
    private  String id;
    private  String name;
    private  Type type; 

    public static enum Type { X , Y, Z}
}

Исправлено, делая переменные-члены окончательными

@Data
@RequiredArgsConstructor 
@NoArgsConstructor(access=AccessLevel.PRIVATE, force=true)
@Entity
public class Someclass {

    @Id
    private final String id;
    private final String name;
    private final Type type; 
    public static enum Type { X , Y, Z}
}
Другие вопросы по тегам