`

自定义主键@TableGenerator重启后新值的问题

 
阅读更多
问题描述:
使用自定义表来构建主键,在每次重启之后的新id总是比定义表里面的gen_val大allocationSize倍。

Model的定义
@Entity
@TableGenerator(name = "rh_sys_portlet",
        table = "rh_sys_tb_generator",
        pkColumnName = "gen_name",
        valueColumnName = "gen_value",
        pkColumnValue = "rh_sys_portlet",
        allocationSize = 5
)
@Table(name = "rh_sys_portlet")
public class RhSysPortlet extends BaseObject implements java.io.Serializable{
   ......
}



问题原因:
org.hibernate.id.MultipleHiLoPerTableGenerator的configure()方法后面:
//hilo config
		maxLo = ConfigurationHelper.getInt(MAX_LO, params, Short.MAX_VALUE);
		returnClass = type.getReturnedClass();

		if ( maxLo >= 1 ) {
			hiloOptimizer = new OptimizerFactory.LegacyHiLoAlgorithmOptimizer( returnClass, maxLo );
		}

当maxLo大于1的时候,就调用new OptimizerFactory.LegacyHiLoAlgorithmOptimizer( returnClass, maxLo ),
这个方法会调用到org.hibernate.id.enhanced.OptimizerFactory
public LegacyHiLoAlgorithmOptimizer(Class returnClass, int incrementSize) {
			super( returnClass, incrementSize );
			if ( incrementSize < 1 )
				throw new HibernateException( "increment size cannot be less than 1" );
			if ( LOG.isTraceEnabled() ) {
				LOG.tracev( "Creating hilo optimizer (legacy) with [incrementSize={0}; returnClass={1}]", incrementSize, returnClass.getName() );
			}
			maxLo = incrementSize;
			lo = maxLo+1;
		}

在这个代码运行之后就到:
@Override
		public synchronized Serializable generate(AccessCallback callback) {
			if ( lo > maxLo ) {
				lastSourceValue = callback.getNextValue();
				lo = lastSourceValue.eq( 0 ) ? 1 : 0;
				hi = lastSourceValue.copy().multiplyBy( maxLo+1 );
			}
			value = hi.copy().add( lo++ );
			return value.makeValue();
		}

方法multiplyBy调用到org.hibernate.id.IdentifierGeneratorHelper
public IntegralDataTypeHolder multiplyBy(long factor) {
			checkInitialized();
			value *= factor;
			return this;
		}

=======================
在org.hibernate.id.MultipleHiLoPerTableGenerator
maxLo = ConfigurationHelper.getInt(MAX_LO, params, Short.MAX_VALUE);可以看到,param里面的MAX_LO值,才出现这个问题。


问题追溯:
那么继续找什么时候初始化这个param?
org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory
public IdentifierGenerator createIdentifierGenerator(String strategy, Type type, Properties config);


上面是被org.hibernate.mapping.SimpleValue
public IdentifierGenerator createIdentifierGenerator()
方法调用

在这个方法里面,identifierGeneratorProperties保存有max_lo信息,什么时候设定?
这个类里面有个
public void setIdentifierGeneratorProperties(Properties identifierGeneratorProperties) {
		this.identifierGeneratorProperties = identifierGeneratorProperties;
	}

被org.hibernate.cfg.BinderHelper类的
public static void makeIdGenerator()
调用

IdGenerator gen = mappings.getGenerator( generatorName, localGenerators );
gen里面设定params,然后传给这个方法的params。


最后参考文档:Hibernate Annotations参考文档 http://www.okrs.cn/blog/news/?1027.html, 知道注解加上
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "rh_sys_portlet")
    @GenericGenerator(name="rh_sys_portlet", strategy = "seqhilo",
            parameters = {
                    @Parameter(name="max_lo", value = "1")
            }
    )
    @Column(name = "portlet_id", unique = true, nullable = false)
    public Long getPortletId() {
        return this.portletId;
    }

    来设定这个max_lo值,就解决了问题。
分享到:
评论

相关推荐

    表生成器 @TableGenerator

    NULL 博文链接:https://mqyl1.iteye.com/blog/1098358

    JPA-2 基本注解

    JPA的基本注解主要包括@Entity、@Table、@Id、@GeneratedValue、@Basic、@Column、@Transient、@Temporal和@TableGenerator等。

    JPA 标注 JPA标签手册

    这是JPA标签配置手册,从ORACLE官方得到的资料,里面对JPA所有的标签都进行详细的说明。 Index of Annotations ...o @TableGenerator o @Temporal o @Transient • U o @UniqueConstraint • V o @Version

    JPA学习笔记(二)——JPA 注解

    JPA注解1.1 @Entity1.2 @Table1.3 @Id1.4 @GeneratedValue1.5 @Basic1.6 @Column1.7 @Transient1.8 @Temporal1.9 @TableGenerator 1. JPA注解 1.1 @Entity 标注在实体类上,表示此类对应一个数据表。 1.2 @Table 与...

    Hibernate注释大全收藏

    AUTO 生成器,适用与可移值的应用,多个@Id可以共享同一个 identifier生成器,只要把generator属性设成相同的值就可以。通过@SequenceGenerator 和 @TableGenerator 可以配置不同的 identifier 生成器。 table=...

    编程狂人第十二期

    探索 Hibernate 新 TableGenerator 机制 服务好“最后一公里”,高效CDN架构经验 探索推荐引擎内部的秘密 一起 select 引起的崩溃 课堂上传纸条如何防范中间人攻击? 程序人生 《9Tech访谈录》揭秘游戏王子白泽的...

    javax.persistence.jar

    javax.persistence.TableGenerator.class javax.persistence.Temporal.class javax.persistence.TemporalType.class javax.persistence.TransactionRequiredException.class javax.persistence.Transient.class ...

    table-generator:Sublime Text 3插件,用于将类似CSV的文本转换为其他可读表格式

    表格生成器-ST3插件甲崇高文本3插件用于将CSV状文本到其它可读表格格式在适当位置。 转换器内部的功劳 。...然后执行install.sh脚本以下载依赖包: $ sh install.sh用法用CSV之类的文字选择目标区域。...

Global site tag (gtag.js) - Google Analytics