【飞天奔月出品】聊聊JPA之GenerationType.AUTO

多说 GenerationType.AUTO 适用于多个数据库,

 

写道
在我们的应用中,一般选用@GeneratedValue(strategy=GenerationType.AUTO)这种方式,自动选择主键生成策略,以适应不同的数据库移植。

 

为什么我今天玩 sqlserver 可以创建主键, 但是主键却没有 IDENTITY标识呢?

 

难道是老人说的是错的? 难道教科书上写得不对? 事出反常必有妖,我偏偏不信这个邪

 

1.现象

 

现在这么一个简单的JPA类

 

 

@Entity
@Table(name = "T_SYS_CHOOSE_OPTION")
public class ChooseOption extends BaseModel implements Command{

    private Long id;

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getId(){
        return id;
    }

    public void setId(Long id){
        this.id = id;
    }
}

 

 

但是启动程序,  生成的表,id列却没有 IDENTITY 标识



 

2.调试

 

将 logback 相关类日志调整成 debug

 

 

<logger name="org.hibernate.tool.hbm2ddl.SchemaUpdate" level="DEBUG" />

 

 

对比下  GenerationType.AUTO 与 GenerationType.IDENTITY 生成的SQL语句

 

--GenerationType.IDENTITY

create table T_SYS_CHOOSE_OPTION (ID numeric(19,0) identity not null)

 

--GenerationType.AUTO

create table T_SYS_CHOOSE_OPTION (ID numeric(19,0) not null)

 

 很清晰的发现,生成的SQL不同点

 

 

3.分析问题

 

上面的想象,搜索了 google ,stackoverflow 等网站, 有用的文章不是很多

 

那我只有自己动手了,  拿出绝招, 那就是 源代码跟踪

 

最终定位到 org.hibernate.mapping.Table.sqlCreateString(Dialect, Mapping, String, String) 方法

 

核心代码片段:

 

 

public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) {
		StringBuffer buf = new StringBuffer( hasPrimaryKey() ? dialect.getCreateTableString() : dialect.getCreateMultisetTableString() )
				.append( ' ' )
				.append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
				.append( " (" );

		boolean identityColumn = idValue != null && idValue.isIdentityColumn( p.getIdentifierGeneratorFactory(), dialect );

		// Try to find out the name of the primary key to create it as identity if the IdentityGenerator is used
		String pkname = null;
		if ( hasPrimaryKey() && identityColumn ) {
			pkname = ( (Column) getPrimaryKey().getColumnIterator().next() ).getQuotedName( dialect );
		}

		Iterator iter = getColumnIterator();
		while ( iter.hasNext() ) {
			Column col = (Column) iter.next();

			buf.append( col.getQuotedName( dialect ) )
					.append( ' ' );

			if ( identityColumn && col.getQuotedName( dialect ).equals( pkname ) ) {
				// to support dialects that have their own identity data type
				if ( dialect.hasDataTypeInIdentityColumn() ) {
					buf.append( col.getSqlType( dialect, p ) );
				}
				buf.append( ' ' )
						.append( dialect.getIdentityColumnString( col.getSqlTypeCode( p ) ) );
			}
			else {

.....

 

 

生成 Identity 的关键语句是 

 

 

buf.append( ' ' )
						.append( dialect.getIdentityColumnString( col.ge
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
05-28

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值