J'ai travaillé avec JPA (mise en veille prolongée) pour un certain temps connaître et à chaque fois que j'ai besoin de créer des entités de me retrouver aux prises avec des problèmes comme AccessType, immuable propriétés, est égal à/hashCode, ... .
J'ai donc décidé de l'essayer et de trouver la meilleure pratique générale pour chaque question et d'écrire ces vers le bas pour un usage personnel.
Je ne serait pas l'esprit cependant, pour toute personne à faire un commentaire ou de me dire où je me trompe.
Classe D'Entité
-
Sérialisable
Raison: La spécification indique que vous avez, mais certains JPA fournisseurs de ne pas respecter cela. Hibernate comme fournisseur JPA ne pas respecter cela, mais il peut échouer quelque part au fond de son estomac avec ClassCastException, si Serializable n'a pas été mis en œuvre.
Les constructeurs
-
créer un constructeur avec tous les champs de l'entité
La raison: Un constructeur doit toujours laisser l'instance créée dans un état sain.
-
en plus de ce constructeur: avoir un paquet privée constructeur par défaut
Raison: la valeur par Défaut du constructeur est tenu de disposer d'Hibernate initialiser l'entité; privé est autorisée, mais colis privé (ou public) la visibilité est nécessaire pour l'exécution génération de proxy et efficace de récupération de données sans instrumentation du bytecode.
Champs/Propriétés
-
Utiliser le champ de l'accès en général et l'accès à la propriété lorsque nécessaire
La raison: c'est probablement le plus discutable problème puisqu'il n'existe pas de relation claire et convaincante les arguments pour l'une ou l'autre (l'accès à la propriété vs d'accès sur le terrain); cependant, le champ de l'accès semble être générale favori en raison de code plus clair, mieux encapsulation et pas besoin de créer des ouvreurs de immuable champs
Omettre les setters pour immuable champs (non requis pour l'accès type de champ)
- les propriétés peuvent être privés
La raison: une fois, j'ai entendu dire que les protégés de mieux pour (Hibernate) de performance, mais tout ce que je peux trouver sur le web est: Hibernate peut accès public, privé et protégé méthodes d'accès, aussi bien que public, privé et protégé des champs directement. Le choix est à vous et vous pouvez le faire correspondre à votre conception de l'application.
Est égal à/hashCode
- Ne jamais utiliser un id généré si cet id est défini uniquement lorsque la persistance de l'entité
- Par préférence: utilisation des valeurs inaltérables pour former une unique Clé d'Entreprise et de l'utiliser pour tester l'égalité
- si une Entreprise unique Clé n'est pas disponible, utilisez un non-transitoire UUID qui est créé lorsque l'entité est initialisé
- ne jamais se référer à des entités liées (ManyToOne); si cette entité (comme une entité mère) doit faire partie de la Clé d'Entreprise puis de comparer les ID. L'appel de getId() sur un proxy ne sera pas déclencher le chargement de l'entité, aussi longtemps que vous êtes à l'aide de la propriété type d'accès.
Exemple D'Entité
@Entity
@Table(name = "ROOM")
public class Room implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "room_id")
private Integer id;
@Column(name = "number")
private String number; //immutable
@Column(name = "capacity")
private Integer capacity;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "building_id")
private Building building; //immutable
Room() {
// default constructor
}
public Room(Building building, String number) {
// constructor with required field
notNull(building, "Method called with null parameter (application)");
notNull(number, "Method called with null parameter (name)");
this.building = building;
this.number = number;
}
@Override
public boolean equals(final Object otherObj) {
if ((otherObj == null) || !(otherObj instanceof Room)) {
return false;
}
// a room can be uniquely identified by it's number and the building it belongs to
final Room other = (Room) otherObj;
return new EqualsBuilder().append(getNumber(), other.getNumber())
.append(getBuilding().getId(), other.getBuilding().getId())
.isEquals();
//this assumes that Building.id is annotated with @Access(value = AccessType.PROPERTY)
}
public Building getBuilding() {
return building;
}
public Integer getId() {
return id;
}
public String getNumber() {
return number;
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(getNumber()).append(getBuilding().getId()).toHashCode();
}
public void setCapacity(Integer capacity) {
this.capacity = capacity;
}
//no setters for number, building nor id
}
D'autres suggestions à ajouter à cette liste sont plus que bienvenus...