hibernate如何自定义自增长的主键值?
来源:互联网 发布:javascript常用对象 编辑:程序博客网 时间:2024/06/05 09:06
昨天在某个网站上(http://sunny.blog.51cto.com/182601/31605)看到关于自定义增长的sequence主键值的定义,之所以会有自定义主键的原因是希望通过自定义自增长的主键值到达数据库中的表的主键使用的是前缀字符 + 序列。也就是说我们每个对象的主键值都不是纯数字。那么hibernate怎样将这个主键写入数据库呢。
通过阅读该网站可以知道,对于这种特殊的要求,hibernate本身并没有提供这种主键生成策略。而hibenate的帮助手册中也提到:
所有的主键生成器都实现org.hibernate.id.IdentifierGenerator
接口。这是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。当时如果我们直接实现该接口就会十分的麻烦,于是,在该网站中使用的使用的是通过继承import org.hibernate.id.SequenceGenerator类并重写generate方法来实现。如下是我的domain对象的配置信息:
package com.lgh.hibernate.mode;public class SequenceTest {private String id;private String name;package com.lgh.hibernate.mode;public class SequenceTest {private String id;private String name;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}}
SequenceTest.hbm.xml文件配置信息如下:
<class name="SequenceTest" table="t_seq"><id name="id" type="java.lang.String"> <column name="USERID" length="20" /> <generator class="com.lgh.hibernate.mode.IdGenerator"> --》自定义生成器 <param name="sequence">s_userid</param> --》表示数据库生成的序列名 </generator> </id><property name="name"/></class>
此为我自定义的主键生成器:
public class IdGenerator extends SequenceGenerator {@Overridepublic Serializable generate(SessionImplementor session, Object object)throws HibernateException {Serializable s = super.generate(session, object);System.out.println(s);return s+"a";}
本以为一切是如此的easy,没想到我运行的时候出现了如下错误:
Exception in thread "main" org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String 报的错误是Stirng是不能识别的集成的数据类型。at org.hibernate.id.IdentifierGeneratorHelper.getIntegralDataTypeHolder(IdentifierGeneratorHelper.java:178)at org.hibernate.id.SequenceGenerator.buildHolder(SequenceGenerator.java:142)at org.hibernate.id.SequenceGenerator.generateHolder(SequenceGenerator.java:115)at org.hibernate.id.SequenceGenerator.generate(SequenceGenerator.java:105)at com.lgh.hibernate.mode.IdGenerator.generate(IdGenerator.java:19)at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:122)at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
可是这个错误在该网站中并没有出现,因为我的配置并没有任何不同,所以我认为是hibernate版本的问题,我的hibernate版本是3.5.5,而该网站中的hibernate版本是3.0.所以才会出现如上错误。于是我经过错误堆栈信息,找到了getIntegralDataTypeHolder方法,该方法定义如下:
public static IntegralDataTypeHolder getIntegralDataTypeHolder(Class integralType) { if ( integralType == Long.class || integralType == Integer.class || integralType == Short.class ) { return new BasicHolder( integralType ); } else if ( integralType == BigInteger.class ) { return new BigIntegerHolder(); } else if ( integralType == BigDecimal.class ) { return new BigDecimalHolder(); } else { throw new IdentifierGenerationException( "Unknown integral data type for ids : " + integralType.getName() ); }
原来,该只能识别Integer,Long,Short,BigInteger,BigDecimal类型,而对于其他类型(String)类型,他就会抛出:
"Unknown integral data type for ids "
继续查看堆栈信息,但是并没有找到任何直接相关的信息,但是在SequenceGenerator的初始化的时候会对hbm.xml中的配置进行config:也就是会调用SeequenceGenerator中的config()方法:
public void configure(Type type, Properties params, Dialect dialect) throws MappingException { type表示hbm.xml配置文件中的id的数据类型ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER );sequenceName = normalizer.normalizeIdentifierQuoting(PropertiesHelper.getString( SEQUENCE, params, "hibernate_sequence" ));parameters = params.getProperty( PARAMETERS );if ( sequenceName.indexOf( '.' ) < 0 ) {final String schemaName = normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) );final String catalogName = normalizer.normalizeIdentifierQuoting( params.getProperty( CATALOG ) );sequenceName = Table.qualify(dialect.quote( catalogName ),dialect.quote( schemaName ),dialect.quote( sequenceName ));}else {// if already qualified there is not much we can do in a portable manner so we pass it// through and assume the user has set up the name correctly.}this.identifierType = type; type表示hbm.xml配置文件中的id的数据类型sql = dialect.getSequenceNextValString( sequenceName );}
其中,他会读取hbm.xml文件中的id的type属性,而之间调用的 getIntegralDataTypeHolder()方法中就会去判断该type属性是否符合序列的要求:
因此,为了让String类型能够识别,我们在自定定义的IdGenerator中重写了父类SequenceGenerator中的configure()方法:
@Overridepublic void configure(Type type, Properties params, Dialect dialect)throws MappingException {super.configure(new IntegerType(), params, dialect);}
其中,我将Type类型默认指定为IntegerType类型,所以hibernate对hbm.xml文件中的id的type类型不会再接受审查,这样,就不在报错了。此时我的IdGenerator类完整代码如下:
package com.lgh.hibernate.mode;import java.io.Serializable;import java.util.Properties;import org.hibernate.HibernateException;import org.hibernate.MappingException;import org.hibernate.dialect.Dialect;import org.hibernate.engine.SessionImplementor;import org.hibernate.id.SequenceGenerator;import org.hibernate.type.IntegerType;import org.hibernate.type.Type;public class IdGenerator extends SequenceGenerator {@Overridepublic Serializable generate(SessionImplementor session, Object object)throws HibernateException {Serializable s = super.generate(session, object);System.out.println(s);return s+"a";}@Overridepublic void configure(Type type, Properties params, Dialect dialect)throws MappingException {super.configure(new IntegerType(), params, dialect);}}
此时,再次运行程序一切ok,查看数据库信息如下:
- hibernate如何自定义自增长的主键值?
- 如何查询自增长的主键id的值
- hibernate 中save之后怎么获取自增长的主键值? 类似servlet中的getGeneratedKeys();
- Hibernate支持oracle主键自增长
- Hibernate + Oracle实现主键自增长
- Hibernate主键的增长策略
- hibernate的主键增长策略
- 关于如何获得数据库插入操作中数据的自增长主键的值
- PowerDesigner16如何实现主键自增长?
- Hibernate 映射配置,主键自增长,复合主键
- sybase数据库主键自增长时如何插入带主键的数据
- 解决Hibernate生成的表的代理主键(id)不是自增长
- mysql数据库的主键自增长
- 获得ORACLE表的自增长主键
- oracle主键自增长的实现
- Mysql设置自增长主键的初始值
- Mysql设置自增长主键的初始值
- Mysql设置自增长主键的初始值
- 欧拉回路(Euler Circuits)
- QFontDatabase: Cannot find font directory问题解决方案(转)
- Android 密码输入框强力实现
- 单片机程序死机跑飞查错指南
- ubuntu 12.04 mariadb 服务操作
- hibernate如何自定义自增长的主键值?
- Mahout-DistanceMeasure (数据点间的距离计算方法)
- struts2实现上传下载(单文件上传与多文件上传的比较)
- 关于android创建对话框报错The method setPositiveButton(int, DialogInterface.OnClickListener) in the type Alert
- Git GUI windows客户端保存用户名与密码的问题
- 分享超级表格用户在知乎上与我们的对话
- 【动态规划】locker
- 小波变换和motion信号处理(一)
- [CPP]cpp小笔记2 --- float 的值的精度最大为Decimal point 往左6-7位