2010-05-12 24 views
11

Ich versuche, einige grundlegende Entitäten mit Hibernate/JPA zu implementieren. Anfangs wurde der Code auf MySQL implementiert und funktionierte gut. Jetzt portiere ich es, um PostgreSQL zu verwenden. In MySQL, meine Entitätsklasse ihren Primärschlüssel als automatische Erhöhung long-Wert mit der folgenden Syntax definiert:Hibernate/JPA und PostgreSQL - Primärschlüssel?

jedoch
@Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

, habe ich festgestellt, dass ich Fehler mit PostgreSQL, wenn ich versuche und zahlreiche Datensätze in einer einfügen Zeit. Was benötige ich, um meinen Primärschlüssel mit Anmerkungen zu versehen, um das gleiche automatische Inkrementierungsverhalten in PostgreSQL zu erhalten wie bei MySQL? Vielen Dank für Ihre Hilfe!

+1

GenerationType.AUTO sollte kein Problem mit einer Datenbank verursachen. Können Sie die Ausnahme und/oder Ihren Einfügecode posten? Es ist erwähnenswert, dass GenerationType.AUTO bei MySQL in den Inkrementtyp konvertiert wird, während es bei PostgreSQL standardmäßig die Sequenz verwendet. Sehen Sie das Dokument hier http://docs.jboss.org/hibernate/core/3.5/reference/en/html/mapping.html#mapping-declaration-id für eine Beschreibung – ig0774

+0

Ich werde das noch einmal versuchen und dann die Post Ausnahme bekomme ich. Die Art, wie ich meine Entity-Klassen eingerichtet habe, besteht darin, eine abstrakte Basisklasse mit der angegebenen ID und der Annotation @MappedSuperclass zu haben und dann den Rest meiner Entitäten von dort abzuleiten. Glaubst du, dass das ein Problem in PostgreSQL verursachen wird? – Shadowman

+0

Fügen Sie mit JPA 'persist()' und 'merge()' oder direkte SQL ein? 'GenerationType.AUTO' bedeutet" der Persistenzanbieter sollte eine geeignete Strategie auswählen "(JPA 2.0 Final Release, Abschnitt 11.1.17). Es bedeutet nicht notwendigerweise eine Sequenzbeziehung. Nur 'GenerationType.SEQUENCE' zwingt den JPA-Provider zur Verwendung einer Sequenz. Die Frage ist derzeit zu vage, um sicher zu sein, aber vielleicht hat Hibernate entschieden, 'id' mit einer Tabelle unter Postgres zu generieren und vielleicht führen Sie SQL aus und erwarten einen nicht existierenden Standardsequenzwert für die Spalte 'id'. Bitte zeigen Sie die Postgres-Relationen an (psql's \ d'). –

Antwort

10

Ich habe das Problem gelöst. Zuvor - in meiner MySQL-Implementierung - machte ich Gebrauch von einer abstrakten Basisklasse mit der folgenden Signatur:

@MappedSuperclass 
public abstract class AbstractDomainEntity implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id = null; 

     ... 
} 

... und dann dehnte ich dies in jedem meiner verbleibenden Einheiten. Seitdem habe ich dieses Attribut in die Entitäten selbst verschoben und den @GenerationType als SEQUENCE konfiguriert. Zum Beispiel:

public class UserProfileBean extends AbstractIdentifiedDomainEntitiy { 

    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "profile_seq") 
    @SequenceGenerator(name = "profile_seq", sequenceName = "profile_seq") 
    private Long id = null; 

     ... 
} 

Dadurch werden die richtigen Sequenzen in Hibernate/JPA und PostgreSQL erzeugt und genutzt werden. Vorher, auch wenn ich den GenerationType als Sequence deklariert habe, wurde keiner erstellt. Vielen Dank für Ihre Hilfe und Ihren Rat in dieser Angelegenheit!

+0

Manchmal wird benötigt, um die Namen zu entziehen und Zitate wie: name = "\" profile_seq \ "" –

17

GenerationType.IDENTITY

+0

Das ist der Trick! Vielen Dank. –

+0

Was für eine Legende! Das funktionierte für mich auf meiner @MappedSuperclass :) –

+0

Viel besser als das akzeptiert. Während dieser wahrscheinlich funktioniert, erfordert dies keine benutzerdefinierten Generatordefinitionen. Vielen Dank! – nerdwaller

Verwandte Themen