2010-10-05 26 views
13

estoy reescribiendo algo de código desordenado que gestiona una base de datos, y vio que el programador original creado una clase asignada a la base de datos de este modo:¿Constructor explícito usando Lombok?

(código innecesario He quitado que no tiene ningún propósito en esta pregunta)

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

todavía soy un principiante en el uso de Hibernate y Lombok, pero ¿no sería esto hacer lo mismo y me Lombok no crear automáticamente el constructor sea necesario para usted?

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

Además, el programador original de este código dice que se permite la cabecera para ser 'nulo', sin embargo, creados explícitamente un constructor que necesita un valor de cabecera. ¿Me estoy perdiendo algo o es esto un poco contradictorio?

Respuesta

12

Tenga una mirada en @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor.

El comportamiento constructor de @Data es como @RequiredArgsConstructor:

@RequiredArgsConstructor genera un constructor con 1 parámetro para cada campo que requiere un manejo especial. Todos los campos finales obtienen un parámetro, como , así como los campos que están marcados como @NonNull que no están inicializados donde están declarados.

Dado que ninguno de sus campos son bien final o @NonNull, esto se traducirá en un constructor sin argumentos. Sin embargo, esta no es la forma más expresiva de lograr este comportamiento.

Lo que es probable que desee en este caso es un @NoArgsConstructor (opcionalmente en combinación con un @AllArgsConstructor), para comunicar claramente el comportamiento previsto, como también se indica en la documentación:

Ciertas construcciones de Java, tales como hibernate y la interfaz del proveedor de servicios requiere un constructor sin argumentos . Esta anotación es útil principalmente en combinación con @Data o uno de los otros generadores de anotaciones.

+0

Sí, leí sobre @RequiredArgsConstructor, pero como es estándar en @Data, no lo agregué. Mi pregunta era si utilicé las anotaciones correctamente ya que el programador original usó Lombok pero no usó anotaciones @NonNull, sino que usó constructores explícitos. Usted dice que ninguno de mis campos es @NonNull, pero mire de cerca mi código (el segundo recuadro), anoté los campos accessionCode y date con @NonNull. Ahora que Hibernate parece necesitar un constructor sin args, ¿sería un buen estilo? @Data @NoArgsConstructor (acceso = AccessLevel.PROTECTED) @RequiredArgsConstructor – FinalArt2005

+0

Sí, ese sería el camino a seguir .. – Tim

+3

bien, simplemente para cualquier persona que también está empezando a utilizar Lombok, acabo de escuchar que no es @RequiredArgsConstructor muy robusto, toma el orden de los campos en su clase para construir el constructor, por lo que si alguien más cambia esta orden, su código que llama al constructor deja de funcionar, por lo que resulta que el constructor explícito sigue siendo la mejor opción. Sin embargo, el @NoArgsConstructor (access = AccessLevel.PROTECTED) parece ser útil si está utilizando Hibernate. Gracias a todos por su ayuda. – FinalArt2005

1

Ese bit es contradictorio, tienes razón. No he usado Lombok antes, pero con Hibernate, si quieres poder crear un bean y persistir, necesitas el constructor predeterminado como se indicó anteriormente, hasta donde yo sabía. Utiliza Constructor.newInstance() para crear instancias de objetos nuevos.

Aquí hay alguna documentación de hibernación que entra en más detalles.

Hibernate Documentation

+0

La anotación @Data justo encima de la clase def creará este constructor predeterminado hasta donde yo sé, y por lo que he aprendido hasta ahora las anotaciones @NonNull sobre los campos harán que Lombok haga estos parámetros de campos en ese constructor para que tenga que dar valores para ellos, y también comprobará si son nulos. Pero como soy nuevo en esto, me preguntaba si solo soy yo o si el programador original cometió algunos pequeños errores aquí. – FinalArt2005

1

Si está utilizando @Data con un campo @NonNull y todavía quiere una noargs-constructor, es posible que quieras tratar de añadir los 3 juntos anotación

@NoArgsConstructor 
@RequiredArgsConstructor 
@AllArgsConstructor 

parecer un viejo intelliJ error que hice replicar en Eclipse Kepler y lombok v0.11.4

Cuestiones relacionadas