Hibernate4中让SequenceGenerator支持字符类型的方法
在Hibernate4中,如果要用SequenceGenerator,其要求数据库中的对应字段为NUMBER等数值类型,但是在具体项目中,因为序列对应的字段往往是主键,虽然是数值但并不参与计算,还有一些其他的原因,往往希望字段定义为字符类型,比如VARCHAR2等,这是合理的需求,本文将提供解决该问题的方法。
经过研究源代码发现,该问题通过Hibernate扩展的方式,会比较麻烦,修改源代码是比较简单方式,下面介绍具体需要修改的源文件,及具体修改方法。
需要修改的源文件为org.hibernate.id.SequenceGenerator和org.hibernate.id.IdentifierGeneratorHelper。
IdentifierGeneratorHelper需要修改的地方较多:
public static IntegralDataTypeHolder getIntegralDataTypeHolder(Class integralType) { if ( integralType == Long.class || integralType == Integer.class || integralType == Short.class || integralType == String.class) {//增加对String的判断 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() ); } }
BasicHolder的构造方法:
public BasicHolder(Class exactType) { this.exactType = exactType; if ( exactType != Long.class && exactType != Integer.class && exactType != Short.class && exactType != String.class) {//增加对String的判断 throw new IdentifierGenerationException( "Invalid type for basic integral holder : " + exactType ); } }
BasicHolder的makeValue方法:
public Number makeValue() { // TODO : should we check for truncation? checkInitialized(); if ( exactType == Long.class || exactType == String.class) { return value; } else if ( exactType == Integer.class ) { return ( int ) value; } else { return ( short ) value; } }
SequenceGenerator的修改比较简单,修改generate方法即可:
@Override public Serializable generate(SessionImplementor session, Object obj) { Number n =generateHolder( session ).makeValue(); if (identifierType.getReturnedClass() == String.class){//增加对String的判断 return n.toString(); }else{ return n; } }
这个修改在4.2.12以上版本(小版本)中测试通过,其他版本未验证。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。