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.
Welche Version des PostgreSQL JDBC-Treibers verwenden Sie? –
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
@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