Ruhezustand-Problem mit Oracle-Trigger zur Erzeugung id aus einer Sequenz
Wir haben ein before-insert-trigger, der bekommt den nächsten Wert aus der Sequenz. Wenn das Objekt persistiert wird mit save () - Methode, hibernate, bekommt den Wert aus der Sequenz und fügt es an das Objekt. und wenn für die Transaktion von Spring-service-layer, den ID-Wert ist wieder gestiegen auf die Datenbank. wie kann ich vermeiden, nextval() wenn das Objekt bereits über ein id..
Hier ist, was ich ma versuchen zu tun..
UserDao
public User saveUser(User user){
session.getCurrentSession.save(user);//line2
return user;//line3
}
UserService
public void saveUserAndWriteToAudit(User user, UserAudit userAudit){
userDao.saveUser(user);//line1
userAudit.setUserId(user.getId);//line4
userAudit.saveUserAudit(userAudit);//line5
}
Und der User-Klasse
@Entity
public class User{
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="a1")
@SequenceGenerator(name="a1", sequenceName="usersequence")
private Long id;
/////////////////
}
Erreicht der cursor line1 und line2 Benutzer-Objekt null-Wert im Attribut id. nach line2, es hat nextval from sequence - sagen wir 1. auf line4, habe ich Hinzugefügt, Benutzer-id=1 zu useraudit Objekt.. wenn die Transaktion ein commit ausgeführt wird, nachdem die Linie 5, 2 eingefügt wird, die Benutzer-id-Spalte und 1 in UserAudit die userId-Spalte. Dieser dient keinem Zweck zu mir 🙁 Wie kann ich dieses Problem vermeiden? Danke!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einfach aktualisieren Sie Ihre trigger nur ausgelöst wird, wenn nicht eine id.
@GeneratedValue
und@SequenceGenerator
Anmerkungen in Person.Die oben genannte Lösung ist Super, es hat mich gerettet eine Menge Kopfschmerzen auf dieses problem.
Meine einzige gripe ist, öffnet es die Tür zu Benutzer/codes einfügen ID-Wert, ohne tatsächlich anfragenden die Folge.
Habe ich die folgende Lösung gefunden, funktioniert auch. Sie können den Ruhezustand finden Sie die max ID und es erhöht jedes mal, wenn eine insert-Anweisung ausgeführt wird. Aber wenn es Sie trifft der Datenbank, die ID wird ignoriert und ersetzt durch die man erzeugt, indem der auslösen, so gibt es keine Einzigartigkeit in einer cluster-problem:
Der größte Nachteil ist @GenericGenerator ist ein Hibernate-annotation, so verlieren Sie JPA-Portabilität. Es ist auch nicht klar, die Programmierer, die diese ID wird tatsächlich verknüpft mit einer Sequenz, während in der Tat, es ist einer der engsten gekoppelten Lösungen, die eine Sequenz verwenden.
Im Idealfall würde Sie entfernen, BEVOR der INSERT-TRIGGER. Wenn Sie nicht, Hibernate hat keine Möglichkeit zu wissen, den Primärschlüssel, und es wirklich braucht, dass Informationen. Wenn Sie kümmern sich nicht um das Objekt nach dem EINFÜGEN das mag OK sein (2nd-level-cache ist immer noch ein Problem), aber wenn Sie benötigen, es sofort zu verwenden, es ist ein echtes problem. Im letzteren Fall könnten Sie versuchen, diese fiesen Ansatz:
dies ist etwas wirklich falsch aus der Datenbank-Welt.
Bedenkt man oben genannte Lösung, sagen sa.my_sequence.nextval ist 51 und Ihre hibernate framework wird ohne Probleme funktionieren. Aber wenn jemand den direkten jdbc-legen Sie mit Ihren Primärschlüssel als 66 überschreiben der Sequenz (sagen, aktuellen Wert als 52), ausgelöst wird, legen Sie Sie einfach.
Das eigentliche Problem ist, wenn Sequenz-Wert erhöht auf 66, die zu einer Ausnahme in der trigger-Endung zurücksetzen der Sequenz-Wert. Das wirklich Ende in eine schlechte Struktur von schema-design von Datenbank-Seite.