2009-08-26 12 views
2

Ich sehe seltsames Verhalten bei der Verwendung von PostgreSQL in einer Hibernate/JPA-Umgebung mit einer einzelnen Tabelle Vererbungshierarchie.PostgreSQL-Identität in JPA Single-Tabellen-Hierarchie

Erstens meine Umgebung:

  • PostgreSQL 8.3
  • Frühling 2.5.6SEC01
  • Hibernate-EntityManager 3.4.0.GA (installiert von Glassfish-Update-Tool)
  • Hibernate-Verteilung 3.3.1 .GA (installiert vom Glassfish-Aktualisierungstool)
  • Glassfish V2
  • Mac OS X 10.5.x

Ich habe ein Problem bei der Verwendung einer GenerationType von IDENTITY mit einer einzigen Tabelle Vererbungshierarchie.

Hier sind meine zwei Entitäten:

Parent.java

@Entity 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="generation", discriminatorType=DiscriminatorType.STRING) 
@DiscriminatorValue("Parent") 
public class Parent implements Serializable { 
    private static final long serialVersionUID = 1L; 

    private Long id; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 
} 

Child.java

@Entity 
@DiscriminatorValue("Child") 
public class Child extends Parent { 
    private String babyName; 

    /** 
    * @return the babyName 
    */ 
    public String getBabyName() { 
     return babyName; 
    } 

    /** 
    * @param babyName the babyName to set 
    */ 
    public void setBabyName(String babyName) { 
     this.babyName = babyName; 
    } 
} 

DDL

create table Parent (generation varchar(31) not null 
        ,id bigserial not null 
        ,babyName varchar(255) 
        ,primary key (id) 
        ); 

Wenn ich versuche, ein neues Elternteil einfügen bekomme ich einen Fehler:

org.postgresql.util.PSQLException: Bad value for type long : Parent 

ich die Protokollierung aktiviert bis TRACE und dies ist die Ausgabe:

 
TRACE TransactionSynchronizationManager - Bound value [[email protected]] for key [[email protected]] to thread [httpSSLWorkerThread-8080-0] 
Hibernate: insert into Parent (generation) values ('Parent') 
SQL Error: 0, SQLState: 22003 
Bad value for type long : Parent 
TRACE TransactionInterceptor - Completing transaction for [com.xxx.yyy.service.MoveService.saveHuman] after exception: javax.persistence.PersistenceException: org.hibernate.exception.DataException: could not insert: [com.xxx.yyy.temp.Parent] 
TRACE RuleBasedTransactionAttribute - Applying rules to determine whether transaction should rollback on javax.persistence.PersistenceException: org.hibernate.exception.DataException: could not insert: [com.xxx.yyy.temp.Parent] 

Wenn ich den Diskriminatorwert ändern etwas zu sein, das als langes z 123 der Einfügevorgang ist erfolgreich. Hibernate scheint jedoch zu glauben, dass dieser Diskriminatorwert die ID ist. So ist der folgende Code:

Parent p = new Parent(); 
service.saveHuman(p); 

add(new Label("p", "p id is" + p.getId())); 

Zeigt die ID als 123 statt der Primärschlüsselwert, der 1.

ist Wenn ich die Generation Typ AUTO eine einzelne Sequenz ändern wird erstellt und der Einsatz scheint zu funktionieren OK. Wenn ich es in SEQUENCE ändere und die Sequenz mit einer Annotation auf Klassenebene erneut deklariere, funktioniert es. Nach der Dokumentation, die ich gelesen habe, unterstützt PostgreSQL jedoch beide Generationstypen.

Ich habe auch den exakt gleichen Code ausprobiert und die Datenbank mit MySQL 5.0.51b abgeschaltet. Dies scheint gut zu funktionieren.

Also ist das ein Fehler in meinem Code, der Dialekt, Hibernate oder der PostgreSQL JDBC-Treiber? Irgendwelche Ideen, wie ich das Problem eingrenzen kann? Jeder, der dieses Problem reproduzieren kann, weil ich versucht habe zu suchen und dieses genaue Problem noch nicht gesehen habe.

Hinweis: Ich habe auch die Frage auf der Hibernate Forums gestellt. Natürlich werde ich alle Antworten auf beide Seiten zurücksenden.

+0

Welche Version des PostgreSQL JDBC-Treibers verwenden Sie? –

+0

Es ist postgresql-8.4-701.jdbc4.jar. Das ist ein guter Punkt - ich werde eine andere Version versuchen, um zu sehen, ob das einen Unterschied macht. – Stephen

+0

@Matt Solnit Gerade versuchte postgresql-8.3-605.jdbc4 und es funktioniert ok! Vielen Dank. Wenn du das als Antwort aufschreiben willst, werde ich es dir zuweisen. – Stephen

Antwort

1

Ich bin nur "portieren" diese Lösung aus den Kommentaren oben ... verwenden Version 8.3 des PostgreSQL JDBC-Treibers :-).