@Column length,区别TopLink与Hibernate的JPA实现
学习JPA时,一直用的是Oracle的TopLink实现。
对于@Column中的length,JPA官方是这样解释的
length 可选默认值: 255默认情况下,JPA 持续性提供程序假设所有列在用于保存 String 值时的最大长度为 255 个字符。如果该列不适合于您的应用程序或数据库,请将 length 设置为适合于您的数据库列的 int 值。
?
TopLink中的实现好像并非以字符为单位,若length为255,TopLink在数据库的映射貌似是255个字节,并非Java里面String类型的255个字符。
?
不多说了,下面还是看看例子吧,这里的数据库为Oracle 10G XE。
?
实体类UserEO
package edu.dlut.entity;import javax.persistence.*;@Entity@Table(name="t_user")public class UserEO {private int id;private String name;@Idpublic int getId() {return id;}public void setId(int id) {this.id = id;}@Column(length=3)public String getName() {return name;}public void setName(String name) {this.name = name;}public UserEO() { }}如果在persistence.xml中加上这样一条
<property name="toplink.ddl-generation" value="create-tables" />
让TopLink自己去生成Table,结果如下
create table "SCOTT"."T_USER"( "ID" NUMBER(10) not null, "NAME" VARCHAR2(3), constraint "SYS_C004185" primary key ("ID") ); create unique index "SCOTT"."SYS_C004185" on "SCOTT"."T_USER2"("ID");?
注意NAME字段,是VARCHAR(30),表示的是3个字节,而UserEO中name长度设为3,在Java当中表示3个字符。也就是说映射到Oracle数据库中去,若类型为VARCHAR2,那长度至少得为6个字节,即VARCHAR2(6)(实现是VARCHAR(12))。TopLink这样的实现,那么下面的Java代码显示是会报错的
package edu.dlut.entity.test;import edu.dlut.entity.*;public class UserEOTest {public static void main(String[] args) {UserEO user = new UserEO();user.setId(3);user.setName("周星星");EntityManagerHelper.beginTransaction();EntityManagerHelper.getEntityManager().persist(user);EntityManagerHelper.commit();EntityManagerHelper.closeEntityManager();}}在我这儿,异常如下
Internal Exception: java.sql.SQLException: ORA-12899: 列 "SCOTT"."T_USER"."NAME" 的值太大 (实际值: 9, 最大值: 3)?
TopLink这样的结果,显然不是我们想要的。
?
同样的实体类UserEO,我们用Hibernate去生成Table,结果却是这样
create table "SCOTT"."T_USER"( "ID" NUMBER(10) not null, "NAME" VARCHAR2(12), constraint "SYS_C004183" primary key ("ID") ); create unique index "SCOTT"."SYS_C004183" on "SCOTT"."T_USER"("ID");这样的结果, 却正是我们需要的,而之前想要插入的"周星星",定是会成功的。但是如果插入"javae",却不能成功。
这样好像在一定的程序上证明Hibernate的JPA实现中,@Column中的length,正好是与Java中String类型的length()方法得结果是相等的。而TopLink的实现,似乎不是我们想要的结果。
1 楼 goodnight 2009-03-25 一般我在不同的数据库使用JPA的时候,遇到我自己不确定的Column的生成类型,我会使用columnDefinition来明确生成的类型。例如: