在具有单个表继承层次结构的 Hibernate/JPA 环境中使用 PostgreSQL 时,我看到了奇怪的行为。
首先是我的环境:
- PostgreSQL 8.3
- 春季2.5.6SEC01
- Hibernate-entitymanager 3.4.0.GA(从Glassfish更新工具安装)
- Hibernate-distribution 3.3.1.GA(通过 Glassfish 更新工具安装)
- 玻璃鱼V2
- Mac OS X 10.5.x
我在使用时遇到问题GenerationType
of IDENTITY
具有单个表继承层次结构。
这是我的两个实体:
父类.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;
}
}
孩子.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)
);
如果我尝试插入新的父级,则会收到错误:
org.postgresql.util.PSQLException: Bad value for type long : Parent
我将日志记录打开到 TRACE,这是输出:
TRACE TransactionSynchronizationManager - Bound value [org.springframework.orm.jpa.EntityManagerHolder@485e0366] for key [com.sun.enterprise.util.EntityManagerFactoryWrapper@a6e312b] 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]
如果我将鉴别器值更改为解析为长的值,例如123
插入成功。然而 Hibernate 似乎认为这个鉴别器值是 id。所以下面的代码:
Parent p = new Parent();
service.saveHuman(p);
add(new Label("p", "p id is" + p.getId()));
将 id 显示为123
而不是主键值 1。
如果我将生成类型更改为AUTO
创建了一个序列,并且插入似乎工作正常。如果我把它改成SEQUENCE
并用类级注释声明序列,它再次起作用。但是根据我读过的文档,PostgreSQL 支持这两种生成类型。
我还尝试了完全相同的代码,并使用 MySQL 5.0.51b 切换了数据库。这似乎运行良好。
那么这是我的代码、方言、Hibernate 或 PostgreSQL JDBC 驱动程序中的错误吗?有什么想法可以缩小问题范围吗?任何人都可以重现这个问题,因为我已经尝试搜索但还没有看到这个确切的问题。
Note:我也问过这个问题。当然,我会将任何回复反馈给这两个网站。