多说 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.getSqlT