Quelle est la meilleure pratique d'Hibernate lorsque vous devez annuler des relations de clés étrangères, mais ne voulez pas rejeter la transaction (par exemple, continuer à enregistrer d'autres données)? Si je viens de passer l'exception sauvegarder la pile ou ne pas faire cette annulation, alors j'atteindrai une erreur quand j'essaye d'enregistrer les autres données (Null ou l'objet Passient passé à persister) comme les BookingLines sont déjà persisté.Annulation des relations de clé étrangère avec Hibernate
Je manipulons actuellement la rollback en ajoutant les nouvelles entités à une carte, puis les retirer des listes d'entités en cas d'échec comme suit:
/* Method that will try to create an invoice but won't roll back the transaction if
* a currency rate can't be found.
*/
public void createInvoiceFromBooking(Booking booking) {
Invoice invoice = new Invoice();
//Map to hold entities that I want to roll back
Map<BookingLine, InvoiceLine> addedLines = new HashMap<BookingLine, InvoiceLine>();
try {
for(BookingLine bookingLine : booking.getBookingLines()) {
InvoiceLIne invoiceLIne = new InvoiceLIne();
//do stuff that can throw exception
applyCurrencyRate(invoiceLine);
bookingLine.getInvoiceLines().add(invoiceLine);
invoice.getInvoiceLines().add(invoiceLine);
//add to the "rollback" map
addedLines.put(bookingLine, invoiceLine);
}
} catch (Exception e) {
//remove the InvoiceLines from the related entities
for(BookingLine bookingLine : addedLines.keySet()) {
bookingLine.getInvoiceLines().remove(addedLines.get(bookingLine));
}
}
Cela fonctionne, mais se sent mal. Y a-t-il un meilleur moyen?
Un bookingLine.clear()
n'est pas bon car il peut avoir d'autres liens InvoiceLine déjà enregistrés.
Merci.
Ce que vous faites est appelé «transaction de compensation». Dans votre cas, vous souhaitez rester avec la transaction en cours tout en annulant des parties de celui-ci. Fondamentalement, vous agissez comme si le commit/rollback n'est pas disponible mais vous restez dans les limites d'une seule transaction. Cela ne me poserait aucun problème étant donné que vous ne pouvez pas utiliser commit/rollback pour accomplir la même chose. – topchef