In Hibernate4, if you want to use Sequencegenerator, it requires that the corresponding fields in the database are numeric types such as number, but in a specific project, because the sequence corresponds to the field is often the primary key, although it is numeric but does not participate in the calculation, there are some other reasons, It is often desirable to have a field defined as a character type, such as VARCHAR2, which is a reasonable requirement, and this article will provide a way to solve the problem.
After research source code discovery, this problem through hibernate extension way, will be more troublesome, modify the source code is a relatively simple way, the following describes the specific need to modify the source files, and the specific modification method.
The source files that need to be modified are org.hibernate.id.SequenceGenerator and org.hibernate.id.IdentifierGeneratorHelper.
Identifiergeneratorhelper need to modify more places:
public static integraldatatypeholder getintegraldatatypeholder (Class integraltype) { if ( integraltype == Long.class | | integralType == Integer.class | | integralType == Short.class | | integraltype == string.class) {//Increase the judgment of 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 () ); } }
How to construct the basicholder:
Public basicholder (Class exacttype) { this.exactType = exactType; if ( exacttype != long.class && exacttype != integer.class && exacttype != short.class && exacttype != string.class) {//Increase the judgment of String throw new identifiergenerationexception ( "Invalid type for basic integral holder : " + exactType ); } }
Makevalue method for basicholder:
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 modification is relatively simple, modify the Generate method can:
@Override public Serializable Generate (sessionimplementor session, Object obj) {number n =generateholder (sessi ON). Makevalue (); if (identifiertype.getreturnedclass () = = String.class) {//Increase the judgment on String return n.tostring (); }else{return n; } }
This modification was tested in 4.2.12 or later versions (iteration), and other versions were not validated.
Ways to let Sequencegenerator support character types in Hibernate4