Grails hack之改变domain class id类型

上回书说到,Sam成功地利用AST在编译期往grails doamin class中注入了客制化的属性。由于grails自己注入的id默认为Long,而我需要String(这样才能把UUID String赋给id)。怎样把Long改成String呢?

 

可以在domain class中加入一行声明

String id

同时还可以这样指定id生成规则:

static mapping = {
    id generator:'uuid.hex', params:[separator:'-']
}

 

个人不喜欢这样做:每个domain class都出现这种boilerplate code,无疑是件很令人不爽的事情。虽然id可以是Long也可以是String,但我不喜欢1,2,3这种东西来做id。

而且因为我抛弃了RDBMS,使用OODBMS,已经把GORM, Hibernate plugin从Grails中移除了(另外仿照它的样子,山寨了它的validation和dynamic finders)。

 

开始Hacking:

1. 尝试注入String类型的属性ID,直接就成功了。但每个domain class中同时含有Long id和String ID,ID利用上了,而id一直闲置着 - 怎么看都不爽。

2. 尝试删除Long id,注入String ID。Grails无法启动,报错: 它要求domain class必须有一个名为id的属性。

3. 方向已经很清楚了:不要注入String ID,把id的类型由Long改成String。怎么改?大胆尝试后发现竟如此的简单:

@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
public class GrsDomainTransformation implements ASTTransformation {
    
    //...

    private void transform(ClassNode classNode, boolean auditable) {
        // 'id' defaults to Long, so a little hacking is needed: change it to String so that I can assign UUID String to it
        changeIdPropertyType2String(classNode);
        injectDeletedProperty(classNode);
        if(auditable) {
            injectDateCreatedProperty(classNode);
            injectHistoryProperty(classNode);
        }
    }

    //...
    private void changeIdPropertyType2String(ClassNode classNode) {
        List<PropertyNode> properties = classNode.getProperties();
        for(PropertyNode p : properties) {
            if(GrailsDomainClassProperty.IDENTITY.equals(p.getName())) {
                p.setType(new ClassNode(String.class));
                break;
            }
        }
    }

}

 就这么一句

p.setType(new ClassNode(String.class));

轻松搞掂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值