Het PostgreSQL-dialect van Hibernate is niet erg helder. Het is niet op de hoogte van uw reeksen per SERILE, en gaat ervan uit dat er een wereldwijde reeks voor de hele database is genaamd "hibernate_sequence" die het kan gebruiken.
(UPDATE :Het lijkt erop dat nieuwere Hibernate-versies de standaardreeksen per tabel kunnen gebruiken wanneer GenerationType.IDENTITY
is gespecificeerd. Test uw versie en gebruik deze in plaats van de onderstaande als deze voor u werkt.)
U moet uw toewijzingen wijzigen om elke reeks expliciet te specificeren. Het is vervelend, repetitief en zinloos.
@Entity
@Table(name = "JUDGEMENTS")
public class Judgement implements Serializable, Cloneable {
private static final long serialVersionUID = -7049957706738879274L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="judgements_id_seq")
@SequenceGenerator(name="judgements_id_seq", sequenceName="judgements_id_seq", allocationSize=1)
@Column(name = "JUD_ID")
private Long _judId;
...
De allocationSize=1
is best belangrijk. Als u het weglaat, gaat Hibernate er blindelings vanuit dat de reeks is gedefinieerd met INCREMENT 50
dus als het een waarde krijgt van een reeks, kan het die waarde gebruiken en de 49 waarden eronder als unieke gegenereerde sleutels. Als uw databasereeksen met 1 toenemen - de standaardwaarde - dan resulteert dit in unieke schendingen wanneer Hibernate probeert bestaande sleutels opnieuw te gebruiken.
Merk op dat het verkrijgen van één sleutel per keer zal resulteren in een extra heen- en terugreis per inzetstuk. Voor zover ik weet is Hibernate niet in staat om INSERT ... RETURNING
te gebruiken om gegenereerde sleutels efficiënt te retourneren, noch kan het blijkbaar de JDBC-interface voor gegenereerde sleutels gebruiken. Als je hem vertelt een reeks te gebruiken, roept hij nextval
. aan om de waarde te krijgen, insert
dat expliciet, resulterend in twee retourvluchten. Om de kosten hiervan te verlagen, kunt u een grotere toename instellen op toetsenreeksen met veel invoegingen, en eraan denken om dit in te stellen op de mapping en de onderliggende databasevolgorde. Dat zorgt ervoor dat Hibernate nextval
. aanroept minder vaak en cacheblokken met sleutels om uit te delen als het gaat.
Ik weet zeker dat je uit het bovenstaande kunt zien dat ik het niet eens ben met de Hibernate-ontwerpkeuzes die hier zijn gemaakt, althans vanuit het perspectief van het gebruik ervan met PostgreSQL. Ze zouden getGeneratedKeys
moeten gebruiken of met INSERT ... RETURNING
met DEFAULT
voor de sleutel, door de database dit te laten regelen zonder dat Hibernate zich zorgen hoeft te maken over de namen van de sequenties of expliciete toegang ertoe.
Trouwens, als je Hibernate met Pg gebruikt, wil je mogelijk ook een oplock-trigger voor Pg om de optimistische vergrendeling van Hibernate veilig te laten werken met normale databasevergrendeling. Zonder dit of iets dergelijks zullen uw Hibernate-updates de neiging hebben om wijzigingen aan te brengen die via andere reguliere SQL-clients zijn gemaakt. Vraag me hoe ik dat weet.