Patterns - TecostNetwork/Network GitHub Wiki
Les entités ayant besoin d'un tri doivent implémenter ISortKeyEntity
.
Le getter getSortKey()
doit être non-nullable.
L'unicité de la sortKey doit être garantie. Certaines entités sont organisées hiérarchiquement et ont un parent (qui peut être une fk vers cette même entité ou vers une autre entité). La contrainte d'unicité ici doit tenir compte du parent car on ne veut pas deux mêmes sortKeys pour un même parent, par contre on autorise deux mêmes sortKeys sur deux parents différents.
Cas non hiérarchique : NOT-NULL et UNIQUE
@Column(nullable = false, unique = true) //Toujours non-null et unique
getSortKey(){...}
Cas hiérarchique : NOT-NULL et UNIQUE par parent
@Entity
@Table(uniqueConstraints = {
@UniqueConstraint(name = "sort_key_parent_fk_ux", columnNames = { "sort_key", "parent_fk" }) //Unique par parent
})
public class MyEntity extends EntityBase<MyEntity> implements ISortKeyEntity<MyEntity> {
@Column(nullable = false) //Toujours non-null
getSortKey(){...}
}
Comme dit ci-dessus, la sortKey est en principe NON NULL. Toutefois, dans le cas exceptionnel où il faut permettre qu'elle soit nulle, on doit vérifier deux choses : si elle est unique si non nulle, et si elle est non nulle en fonction d'une règle. L'exemple ci-dessous peut servir pour ce genre de cas, mais il faut absolument les éviter.
@ExprIndex(name = "unique_sort_key", unique = true, where = "sort_key IS NOT NULL") //Unique si non-null
@Check(constraints = "(active = sort_key IS NOT NULL)") //Non-null si active
getSortKey(){...}
Valable aussi ? TODO à voir avec MW ou NJ - est-ce que ça permet d'avoir plusieurs nulls ? Il semblerait que oui
@Column(nullable = true, unique = true)
- Sur un
Controller
qui nécessite d'être loggué :@Security(roles = RoleType.XXX)
- Sur un
ModalController
qui nécessite d'être loggué :@StandardUserPage
- Sur un
Controller
ouModalController
qui doit être accessible sans être loggué :@SkipSecurity
- Sur un
FragmentController
: aucune annotation - Sur un
ComponentController
: aucune annotation
Lorsqu'il faut exporter des documents :
- La méthode d'export qui fabrique le fichier doit se trouver dans un service.
- Elle prend en paramètre un OutputStream.
- L'appelant (au niveau contrôleur ou helper) doit ouvrir le stream via un try-with-resource. Cela permet de fermer le stream quoiqu'il arrive, même en cas d'exception.
- L'appelant doit mettre un catch Exception, afficher un message générique et générer un rapport d'erreur. Cela permet de ne pas bloquer l'utilisateur, de lui mettre un message compréhensible, et de récupérer un rapport d'erreur chez nous quand-même.
Pour formater des dates en Java, utiliser le DateUtils.dateFormat().format(maDate)
.
- Il existe plusieurs méthodes du même genre pour le formatage :
-
DateUtils.dateFormat().format(maDate);
Date seule sans les heures (le plus courant lorsqu'on a des dates et que les heures ne nous intéressent pas). -
DateUtils.dateTimeFormat().format(maDate);
Date et heure avec les minutes et secondes (quasi jamais utilisé). -
DateUtils.dateTimeMinFormat().format(maDate);
Date et heure avec les minutes (le plus courant si on a besoin des heures).
-
- Ne pas utiliser SimpleDateFormat ou d'autres techniques qui nécessitent de définir à chaque fois un pattern. L'idée est que les patterns qu'on utilise sont standards et qu'on ne veut pas devoir les adapter partout le jour où on change (même si c'est peu probable). En plus, c'est plus simple à faire avec DateUtils.
Ci-dessous : à gauche c'est bon, à droite c'est pas bon :
- Utiliser de préférence des traductions absolues (commencent par "
/maCléDeTraduction
") qui évitent d'avoir à refaire les traductions pour chaque page. - Pour les enums IRootTranslationOnly, utiliser
#{myEntity.myEnumStatus.translation}
. Ne pas essayer de construire la clé de traduction#{_[/MyEnumStatus]}
ou d'autres dérivés.
Pour les ThreeStates dans les pages XHTML, il y a maintenant la possibilité de récupérer les valeurs traduites génériques, ce qui évite de retraduire pour chaque page. Aussi, l'ancienne méthode posait problème lorsqu'elle était utilisée dans une popup qui s'affiche sur plusieurs pages car la traduction doit être faite pour chaque page, et peut varier d'une page à l'autre pour notre popup ce qui n'est pas très cohérent.
- threeState.values (comme avant, il faut faire la traduction propre à la page, à n'utiliser que s'il vous faut des valeurs autres que oui/non).
- threeState.valuesYesNo (oui, non et vide pour les utilisations dans les éditeurs).
- threeState.valuesYesNoStar (oui, non et * pour les utilisations dans les filtres).