Pergunta

Estou reescrevendo um código confuso que gerencia um banco de dados e vi que o programador original criou uma classe mapeada para o banco de dados assim:

(Removi código desnecessário que não tem propósito nesta questão)

@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;
    }
}

Ainda sou iniciante no Hibernate e uso o Lombok, mas isso não faria a mesma coisa e o Lombok não criaria automaticamente o construtor necessário para você?

@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());
}

Além disso, o programador original deste código diz que permite que o cabeçalho seja 'nulo', mas criou explicitamente um construtor que precisa de um valor para o cabeçalho.Estou faltando alguma coisa ou isso é um pouco contraditório?

Foi útil?

Solução

Dê uma olhada em @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor.

O comportamento do construtor de @Data é como @RequiredArgsConstructor:

O @ReQuiredargSconstructor gera um construtor com 1 parâmetro para cada campo que requer manuseio especial. Todos os campos finais obtêm um parâmetro, bem como quaisquer campos marcados como @Nonnull que não são inicializados onde são declarados.

Dado que nenhum dos seus campos é final ou @NonNull, isso resultará em um construtor sem argumento. No entanto, essa não é a maneira mais expressiva de alcançar esse comportamento.

O que você provavelmente vai querer neste caso é um @NoArgsConstructor (opcionalmente combinado com um @AllArgsConstructor), para comunicar claramente o comportamento pretendido, como também é indicado na documentação:

Certas construções de Java, como o hibernato e a interface do provedor de serviços, requerem um construtor de não-ARGs. Esta anotação é útil principalmente em combinação com as anotações @Data ou de um outro construtor que gera.

Outras dicas

Essa parte é contraditória, você está certo. Eu não usei o Lombok antes, mas com o Hibernate, se você quiser poder criar um feijão e persistir, precisa do construtor padrão, conforme dado acima, até agora eu estava ciente. Ele usa o construtor.NewInstance () para instanciar novos objetos.

Aqui está uma documentação de hibernação que entra em mais detalhes.

Documentação de hibernação

Se você estiver usando @data com um campo @Nonnull e ainda quiser um constitutor de noargs, você pode tentar adicionar todas as 3 anotações juntas

@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor

Aparentemente, um velho Intellij Bug, que eu repliquei no Eclipse Kepler e Lombok v0.11.4

@NoArgsConstructor, 
@RequiredArgsConstructor, 
@AllArgsConstructor

Gere construtores que não aceitam argumentos, um argumento por campo final/não nulo ou um argumento para cada campo.Leia isso projeto lombok

@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}
}

Corrigido tornando as variáveis ​​de membro finais

@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}
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top