11
votes

Mappage des propriétés calculées avec JPA

Y a-t-il un moyen de cartographier une propriété calculée à l'aide de JPA?

En supposant que j'ai une facture objet avec un ou plusieurs InvoicelineItems En lui, je veux avoir Une propriété calculée persistante sur la classe de la classe qui me donne le montant total: xxx

maintenant, je pourrais créer un no-op protégé SetoTalamount Méthode pour rendre JPA Heureux, mais je me demandais s'il y a un moyen de laisser le JPA sache que la cartographie est unique et d'éviter de créer une méthode de setter superflu.

Merci, Aleks


0 commentaires

3 Réponses :


10
votes

Ce que vous avez décrit n'est pas une propriété calculée en JPA Sense. Vous le calculez vous-même dans votre méthode - il suffit de marquer cette méthode comme @Transient code> et JPA l'ignorera.

Si vous avez vraiment besoin d'une propriété calculée (un moyen "calculé" "calculé via SQL Expression "), vous devrez l'annoter selon votre fournisseur JPA. Pour Hibernate, vous le feriez via @formula code> Annotation: P>

@Formula("col1 * col2")
public int getValue() {
 ...
}


4 commentaires

Propriété de marquage comme @Transient ne m'aidera pas. Je ne veux pas que JPA l'ignore - je veux que le montant total persiste dans une base de données afin que je puisse y interroger directement sans avoir à agréger les informations de la table enfant. Donc, ce que je demande, c'est comment persister une propriété calculée (en Java Sense, complètement sans rapport avec la persistance) sans avoir à mettre en œuvre un setter inutile pour cela.


Votre exemple est plutôt étrange alors. Si vous êtes Stockage cette valeur et interrogez-vous pourquoi vous la recalculez dans votre getter? Toutefois, la ligne finale est que si vous annotant la méthode de getter (par opposition à la propriété), vous devez disposer d'un seigteur correspondant (il peut être privé) pour que JPA renonce à peupler cette valeur sur votre entité.


L'exemple que j'ai donné est la simplification excessive du modèle de domaine avec lequel je travaille avec plusieurs niveaux dans de nombreuses relations, avec des biens calculés à chaque niveau qui dépend des enfants. La valeur de calcul en Java si nécessaire est nettement plus facile que d'essayer de mettre à jour le total des objets d'enfant dans une hiérarchie (profond), enlevé ou modifié, c'est pourquoi je la recalcule.


Cependant, le montant total persistant fait des requêtes basées sur la quantité contre la table qui stocke de manière significative les objets racines, ce que je veux le persister lorsque je sauvegarder mes objets, mais je ne veux pas vraiment le charger de nouveau (c'est pourquoi Je n'ai pas besoin et je ne me soucie pas de moins sur le setter). C'est pourquoi j'espérais qu'il y avait un moyen de dire à la JPA de traiter une propriété en écriture uniquement à partir d'une perspective de persistance. En tout cas, merci de votre réponse, je suppose que je devrais partir avec des setters qui ne servent pas d'autre but autre que de rendre JPA Happy :-(



4
votes

Peut-être que l'annotation répareuse peut être utilisée pour cela.

@Column(name = "TOTAL_AMOUNT")
private BigDecimal totalAmount;

@PrePersist
public void updateTotalAmount() {
    BigDecimal amount = BigDecimal.ZERO;
    for (InvoiceLineItem lineItem : lineItems) {
        amount = amount.add(lineItem.getTotalAmount());
    }
    this.totalAmount = amount;
}


2 commentaires

Ceci est définitivement agréable de savoir, merci. Cependant, j'ai besoin du total pour être mis à jour chaque fois que je le regarde, non seulement avant qu'il ne soit persisté, il ne fonctionnera donc pas dans mon cas particulier.


Braaaains ... Je veux dire, pourquoi n'aurais-tu pas d'une méthode de la méthode privée updateTotalMount () et d'appeler à partir du gettotalamount () accesseur, ainsi que @Preppersist ? N'est-ce pas ce qu'est un getter?



5
votes

Je sais que je suis Necro-ing sur ce fil, mais peut-être que cela pourrait aider quelqu'un à sortir.

Si vous souhaitez calculer la valeur en lecture, le @postoDload L'annotation peut être ce que vous voulez Vous voulez: xxx


1 commentaires

Pas réellement la réponse à la question de l'OPS, mais incidemment, juste la bonne réponse à ma question car je veux quelque chose de légèrement différent de l'OP ... alors merci de l'avoir posté ici! +1