Monday, August 21, 2006

Using sequence in Grails GORM



Create a "hibernate.cfg.xml" file in the "%PROJECT_HOME%\hibernate" directory of your project,
or if you always want to use sequence in Grails
Checkout Grails from the SVN repository and
you will need to customize the part of the source:

Easier Way:
(fix just one source)
Do the following change.
source code of org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinder.java
at method bindSimpleId()
change

id.setIdentifierGeneratorStrategy( "native" );

to

id.setIdentifierGeneratorStrategy( "sequence" );


and add


params.setProperty(PersistentIdentifierGenerator.PK, "id");
params.setProperty("sequence", entity.getTable().getName() + "_id_seq");


just below of the


if ( mappings.getCatalogName() != null ) {
params.setProperty( PersistentIdentifierGenerator.CATALOG, mappings.getCatalogName() );
}


method bindSimpleId() will look like:

private static void bindSimpleId(GrailsDomainClassProperty identifier, RootClass entity, Mappings mappings) {

// create the id value
SimpleValue id = new SimpleValue(entity.getTable());
// set identifier on entity
entity.setIdentifier( id );
// configure generator strategy
id.setIdentifierGeneratorStrategy( "sequence" );// change here native to sequence

Properties params = new Properties();

if ( mappings.getSchemaName() != null ) {
params.setProperty( PersistentIdentifierGenerator.SCHEMA, mappings.getSchemaName() );
}
if ( mappings.getCatalogName() != null ) {
params.setProperty( PersistentIdentifierGenerator.CATALOG, mappings.getCatalogName() );
}
params.setProperty(PersistentIdentifierGenerator.PK, "id");//add here
params.setProperty("sequence", entity.getTable().getName() + "_id_seq");//add here
id.setIdentifierGeneratorProperties(params);

// bind value
bindSimpleValue(identifier, id, mappings );

// create property
Property prop = new Property();
prop.setValue(id);

// bind property
bindProperty( identifier, prop, mappings );
// set identifier property
entity.setIdentifierProperty( prop );

id.getTable().setIdentifierValue( id );

}

this always uses sequence at every tables (Domain class).
(sequence is supported on DB2,Oracle,PostgreSQL,Interbase,McKoi,SAP DB)
Check hibernate reference for more information:

hibernate mapping-declaration-id-generator




Harder way:
I fixed more code and add option like this on domain class:

def identifierGeneratorStrategy = "sequence"
//without this option domain class will use original
' IdentifierGeneratorStrategy( "native" ) '

Here is my diff:

Index: D:/home/aioecl/workspace/grails/src/commons/org/codehaus/groovy/grails/commons/GrailsDomainClassProperty.java
===================================================================
--- D:/home/aioecl/workspace/grails/src/commons/org/codehaus/groovy/grails/commons/GrailsDomainClassProperty.java (revision 1030)
+++ D:/home/aioecl/workspace/grails/src/commons/org/codehaus/groovy/grails/commons/GrailsDomainClassProperty.java (working copy)
@@ -33,6 +33,7 @@
String CLASS = "class";
String MAPPED_BY = "mappedBy";
String BELONGS_TO = "belongsTo";
+ String IDENTIFIER_GENERATOR_STRATEGY ="identifierGeneratorStrategy";

/**
* Returns the name of the property

Index: D:/home/aioecl/workspace/grails/src/commons/org/codehaus/groovy/grails/commons/GrailsDomainClass.java
===================================================================
--- D:/home/aioecl/workspace/grails/src/commons/org/codehaus/groovy/grails/commons/GrailsDomainClass.java (revision 1030)
+++ D:/home/aioecl/workspace/grails/src/commons/org/codehaus/groovy/grails/commons/GrailsDomainClass.java (working copy)
@@ -159,4 +159,10 @@
* @return A set of sub classes or an empty set if none exist
*/
public Set getSubClasses();
+
+ /**
+ * Returns the identifierGeneratorStrategy String
+ * @return identifierGeneratorStrategy
+ */
+ public String getIdentifierGeneratorStrategy();
}

Index: D:/home/aioecl/workspace/grails/src/commons/org/codehaus/groovy/grails/commons/DefaultGrailsDomainClass.java
===================================================================
--- D:/home/aioecl/workspace/grails/src/commons/org/codehaus/groovy/grails/commons/DefaultGrailsDomainClass.java (revision 1046)
+++ D:/home/aioecl/workspace/grails/src/commons/org/codehaus/groovy/grails/commons/DefaultGrailsDomainClass.java (working copy)
@@ -62,6 +62,7 @@
private List owners = new ArrayList();
private boolean root = true;
private Set subClasses = new HashSet();
+ private String dentifierGeneratorStrategy;

public DefaultGrailsDomainClass(Class clazz) {
super(clazz, "");
@@ -84,6 +85,12 @@
if(getPropertyValue(GrailsDomainClassProperty.MAPPED_BY, String.class) != null)
this.mappedBy = (String)getPropertyValue(GrailsDomainClassProperty.MAPPED_BY, String.class);

+ if(getPropertyValue(GrailsDomainClassProperty.IDENTIFIER_GENERATOR_STRATEGY, String.class) != null)
+ this.dentifierGeneratorStrategy =
+ (String)getPropertyValue(
+ GrailsDomainClassProperty.IDENTIFIER_GENERATOR_STRATEGY, String.class);
+
+
Class belongsTo = (Class)getPropertyValue(GrailsDomainClassProperty.BELONGS_TO, Class.class);
if(belongsTo == null) {
List ownersProp = (List)getPropertyValue(GrailsDomainClassProperty.BELONGS_TO, List.class);
@@ -110,7 +117,8 @@
!descriptor.getName().equals( GrailsDomainClassProperty.OPTIONAL) &&
!descriptor.getName().equals( GrailsDomainClassProperty.CONSTRAINTS )&&
!descriptor.getName().equals( GrailsDomainClassProperty.MAPPED_BY ) &&
- !descriptor.getName().equals( GrailsDomainClassProperty.BELONGS_TO ) ) {
+ !descriptor.getName().equals( GrailsDomainClassProperty.BELONGS_TO ) &&
+ !descriptor.getName().equals( GrailsDomainClassProperty.IDENTIFIER_GENERATOR_STRATEGY )) {


GrailsDomainClassProperty property = new DefaultGrailsDomainClassProperty(this, descriptor);
@@ -498,5 +506,9 @@

public Set getSubClasses() {
return this.subClasses;
+ }
+
+ public String getIdentifierGeneratorStrategy() {
+ return this.dentifierGeneratorStrategy;
}
}

Index: D:/home/aioecl/workspace/grails/src/persistence/org/codehaus/groovy/grails/orm/hibernate/GrailsHibernateDomainClass.java
===================================================================
--- D:/home/aioecl/workspace/grails/src/persistence/org/codehaus/groovy/grails/orm/hibernate/GrailsHibernateDomainClass.java (revision 1101)
+++ D:/home/aioecl/workspace/grails/src/persistence/org/codehaus/groovy/grails/orm/hibernate/GrailsHibernateDomainClass.java (working copy)
@@ -250,4 +250,10 @@
public boolean isRoot() {
return getClazz().getSuperclass().equals(Object.class);
}
+
+
+ public String getIdentifierGeneratorStrategy() {
+ // TODO Should i return some?
+ return "";
+ }
}

Index: D:/home/aioecl/workspace/grails/src/persistence/org/codehaus/groovy/grails/orm/hibernate/cfg/GrailsDomainBinder.java
===================================================================
--- D:/home/aioecl/workspace/grails/src/persistence/org/codehaus/groovy/grails/orm/hibernate/cfg/GrailsDomainBinder.java (revision 1101)
+++ D:/home/aioecl/workspace/grails/src/persistence/org/codehaus/groovy/grails/orm/hibernate/cfg/GrailsDomainBinder.java (working copy)
@@ -453,7 +453,7 @@

LOG.info( "[GrailsDomainBinder] Mapping Grails domain class: " + domainClass.getFullName() + " -> " + root.getTable().getName() );

- bindSimpleId( domainClass.getIdentifier(), root, mappings );
+ bindSimpleId( domainClass.getIdentifier(), root, mappings ,domainClass.getIdentifierGeneratorStrategy());
bindVersion( domainClass.getVersion(), root, mappings );

root.createPrimaryKey();
@@ -649,16 +649,23 @@
* @param entity
* @param mappings
*/
- private static void bindSimpleId(GrailsDomainClassProperty identifier, RootClass entity, Mappings mappings) {
+ private static void bindSimpleId(GrailsDomainClassProperty identifier, RootClass entity,
+ Mappings mappings,String identifierGeneratorStrategy) {

// create the id value
SimpleValue id = new SimpleValue(entity.getTable());
// set identifier on entity
entity.setIdentifier( id );
// configure generator strategy
- id.setIdentifierGeneratorStrategy( "native" );
+ if(identifierGeneratorStrategy!=null &&
+ identifierGeneratorStrategy.equalsIgnoreCase("sequence") ){
+ id.setIdentifierGeneratorStrategy( "sequence" );
+ }else{
+ id.setIdentifierGeneratorStrategy( "native" );
+ }

Properties params = new Properties();
+

if ( mappings.getSchemaName() != null ) {
params.setProperty( PersistentIdentifierGenerator.SCHEMA, mappings.getSchemaName() );
@@ -666,6 +673,11 @@
if ( mappings.getCatalogName() != null ) {
params.setProperty( PersistentIdentifierGenerator.CATALOG, mappings.getCatalogName() );
}
+ if(identifierGeneratorStrategy!=null &&
+ identifierGeneratorStrategy.equalsIgnoreCase("sequence")){
+ params.setProperty(PersistentIdentifierGenerator.PK, "id");
+ params.setProperty("sequence", entity.getTable().getName() + "_id_seq");
+ }
id.setIdentifierGeneratorProperties(params);

// bind value





ugly code..... :(
Maybe there is more better way to do this ..

at your own risk........ :)

Labels:

0 Comments:

Post a Comment

<< Home