Question

Je réécriture du code de désordre qui gère une base de données, et vu que le programmeur d'origine a créé une classe mis en correspondance avec la base de données comme ceci:

(je l'ai supprimé le code inutile qui n'a pas de but dans cette question)

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

Je suis encore un débutant à Hibernate et en utilisant Lombok, mais ne serait-ce faire la même chose et ne Lombok créer automatiquement le constructeur nécessaire pour vous?

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

En outre, le programmeur d'origine de ce code, dit-il permet de l'en-tête d'être « nul », mais il a créé explicitement un constructeur qui a besoin d'une valeur pour en-tête. Suis-je manque quelque chose ou est-ce un peu contradictoire?

Était-ce utile?

La solution

Jetez un oeil à @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor .

Le comportement du constructeur de @Data est comme @RequiredArgsConstructor:

  

@RequiredArgsConstructor génère un   constructeur avec 1 paramètre pour chaque   champ qui nécessite un traitement spécial.   Tous les champs finaux obtiennent un paramètre, comme   ainsi que tous les champs qui sont marqués comme   @NonNull qui ne sont pas initialisés où   ils sont déclarés.

Étant donné qu'aucun de vos champs sont soit final ou @NonNull, cela se traduira par un constructeur sans argument. Cependant, ce n'est pas la façon la plus expressive pour atteindre ce comportement.

Ce que vous voudrez probablement dans ce cas est un @NoArgsConstructor (éventuellement combiné avec un @AllArgsConstructor), de communiquer clairement le comportement prévu, comme cela est indiqué aussi dans la documentation:

  

Certaines constructions de Java, telles que   Mise en veille prolongée et le fournisseur de services   Interface besoin d'un non-args   constructeur. Cette annotation est utile   principalement en combinaison avec l'   @Data ou une de l'autre constructeur   annotations de production.

Autres conseils

Ce bit est contradictoire que vous avez raison. Je n'ai pas utilisé Lombok avant mais avec mise en veille prolongée si vous voulez être en mesure de créer un haricot et vous devez persister le constructeur par défaut comme indiqué ci-dessus en ce que je savais. Il utilise Constructor.newInstance () pour instancier de nouveaux objets.

Voici quelques documents de mise en veille prolongée qui va plus en détail.

Hibernate Documentation

Si vous utilisez @data avec un champ @NonNull et veulent toujours un noargs constructeur, vous voudrez peut-être essayer d'ajouter les 3 annotations ensemble

@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor

Apparemment, un vieux IntelliJ bug qui Je l'ai répliquée Eclipse Kepler et lombok v0.11.4

@NoArgsConstructor, 
@RequiredArgsConstructor, 
@AllArgsConstructor

Générer des constructeurs qui ne prennent aucun argument, un argument par final / champ non nul, ou un argument pour tous les domaines. Lisez cette lombok-projet

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

Correction d'elle en faisant des variables membres finale

@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}
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top